Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CP] Custom properties phase 1 #1620

Open
wants to merge 61 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
96eb24d
feat: add handleDeleteProperty
Bad-Company Apr 10, 2017
8c2757e
feat: add edit/delete property
Bad-Company Apr 11, 2017
713b693
feat: add edit/delete buttons
Bad-Company Apr 11, 2017
f83c0e4
feat: handle value on type change
Bad-Company Apr 11, 2017
f92b260
fix: flow errors
Bad-Company Apr 11, 2017
f8c4d31
fix: disable edit/delete on default fields
Bad-Company Apr 11, 2017
3c9ba9c
refactor: move render controlButtons to renderedAttributes
Bad-Company Apr 12, 2017
0c2c441
refactor: put name, type, value to 'currentEdit'
Bad-Company Apr 12, 2017
8af3242
fix: handle fieldLabel if it's not unique
Bad-Company Apr 12, 2017
9245261
refactor: move custom properties out from object-form-inner
Bad-Company Apr 13, 2017
0d7e93f
refactor: pass props through custom properties
Bad-Company Apr 13, 2017
70fb53b
fix: handle to date/boolean type change
Bad-Company Apr 14, 2017
23d4daa
fix: flow errors
Bad-Company Apr 14, 2017
661a955
spike on extracted render methods
tonypizzicato Apr 17, 2017
a271e8f
refactor: move renderers out of object-form-inner to /renderers
Bad-Company Apr 17, 2017
1fd1d0e
fix: flow errors
Bad-Company Apr 17, 2017
23b1eab
feat: add pointer to control buttons
Bad-Company Apr 17, 2017
89e4e1f
general improvements
tonypizzicato Apr 18, 2017
6f36638
feat: add propertyType check.
Bad-Company Apr 18, 2017
ebe66e5
feat: add deleteProperty modal
Bad-Company Apr 18, 2017
7e4728a
style: add semicolon
Bad-Company Apr 18, 2017
5f3be64
fix: handle edit/new property title
Bad-Company Apr 18, 2017
6e99d50
refactor: use ConfirmationDialog instead of DeletePropertyModal
Bad-Company Apr 18, 2017
3ad52ee
fix: lint errror
Bad-Company Apr 18, 2017
e7e81e3
style: remove extra spaces
Bad-Company Apr 19, 2017
0e39eab
Merge branch 'feature/custom-properties'
Bad-Company Apr 26, 2017
4ab846f
fix: change import path
Bad-Company Apr 26, 2017
2c8daed
Merge pull request #1329 from FoxComm/feature/cp-add-delete-edit-buttons
tonypizzicato Apr 26, 2017
d1bf698
Merge branch 'master' into feature/custom-properties
tonypizzicato May 2, 2017
155bb0f
saved: image load
Bad-Company Apr 20, 2017
5a75061
chore: clean up code
Bad-Company Apr 24, 2017
0d09012
feat: add select image button
Bad-Company Apr 24, 2017
6feb440
feat: add mocked image load
Bad-Company Apr 24, 2017
222860e
refactor: pass ProductImage to Image as prop
Bad-Company Apr 25, 2017
9cf097a
feat: add deleteFile action
Bad-Company Apr 25, 2017
07f2f33
feat: style image upload container
Bad-Company Apr 25, 2017
b2db50d
style: imageCard
Bad-Company Apr 26, 2017
35ddc20
feat: add external-link action and edit mock
Bad-Company Apr 26, 2017
86dce1e
refactor: reimplement mocked api response
Bad-Company Apr 26, 2017
ed6c475
fix: actions height
Bad-Company Apr 26, 2017
14d8c7a
fix: imageCard width
Bad-Company Apr 26, 2017
40cb83e
chore: change mock image
Bad-Company Apr 26, 2017
a976de1
fix: lint errors
Bad-Company Apr 26, 2017
f00a852
fix: flow errors
Bad-Company Apr 26, 2017
854176c
fix: lint errors
Bad-Company Apr 26, 2017
f142671
refactor: put add/delete image to renderer.
Bad-Company Apr 27, 2017
0704a41
refactor: extract render image func to class.
Bad-Company Apr 27, 2017
57e73f6
feat: add EditImage to image renderer
Bad-Company Apr 28, 2017
d8f7133
feat: set default title & alt
Bad-Company Apr 28, 2017
f7e27c8
chore: remove alt and title from mocked response
Bad-Company Apr 28, 2017
02d336a
fix: lint & flow errors
Bad-Company Apr 28, 2017
87a6366
refactor: use Image component instead of ImageCard
Bad-Company Apr 28, 2017
139ab83
fixes
tonypizzicato May 2, 2017
fbeb0a5
Merge pull request #1621 from FoxComm/feature/cp-single-image-upload
tonypizzicato May 3, 2017
d2b8b20
feat: add real api call
Bad-Company May 17, 2017
2371812
fix: bug with image `error.png` during loading
Bad-Company May 17, 2017
55eae87
refactor: get rid of less in custom properties
Bad-Company May 18, 2017
0237b79
minor fixes
tonypizzicato May 19, 2017
2cc5c2c
Merge pull request #1822 from FoxComm/feature/cp-add-api-call
tonypizzicato May 19, 2017
be72799
hover transitions
tonypizzicato May 19, 2017
e9a9a4a
Merge pull request #1833 from FoxComm/refactor/cp-styles
tonypizzicato May 19, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions ashes/src/components/custom-properties/custom-properties.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

.controls {
position: absolute;
right: 21px;

& > i {
margin: 0 5px;
cursor: pointer;
}
}

:global .fc-save-cancel {
display: flex;
justify-content: flex-end;
}

:global .fc-save-cancel__cancel {
background-color: transparent;
text-decoration: underline;

&:hover {
background-color: transparent;
}
}

.addProperty {
display: flex;
align-items: center;
margin: 30px -20px -20px -20px;
padding: 20px;
border-top: 1px solid #d9d9d9;
cursor: pointer;
transition: all .2s;

&:hover {
background-color: #f7f7f7;
}
}

.buttonTitle {
margin-right: 10px;
font-size: 14px;
font-weight: 600;
}

.icon {
font-size: 10px;
}


247 changes: 247 additions & 0 deletions ashes/src/components/custom-properties/custom-properties.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
// @flow

// libs
import React, { Component, Element } from 'react';
import { autobind } from 'core-decorators';
import { get, keys, omit } from 'lodash';

// components
import CustomPropertyModal from './custom-property-modal';
import ConfirmationDialog from '../modal/confirmation-dialog';

// style
import s from './custom-properties.css';

type Props = {
canAddProperty?: boolean,
attributes: Attributes,
onChange: (attributes: Attributes) => void,
schema?: Object,
children: Element<*>
};

type State = {
isAddingProperty: boolean,
isEditingProperty: boolean,
isDeletingProperty: boolean,
errors: { [id: string]: any },
currentEdit: {
name: string,
type: string,
value: any,
},
propertyToDelete: string,
}

export default class CustomProperties extends Component {
props: Props;

state: State = {
isAddingProperty: false,
isEditingProperty: false,
isDeletingProperty: false,
errors: {},
currentEdit: {
name: '',
type: '',
value: '',
},
propertyToDelete: '',
};

get customPropertyForm() {
if (this.state.isAddingProperty) {
return (
<CustomPropertyModal
isVisible={true}
onSave={this.handleCreateProperty}
onCancel={() => this.setState({ isAddingProperty: false })}
/>
);
}

if (this.state.isEditingProperty) {
return (
<CustomPropertyModal
isVisible={true}
currentEdit={this.state.currentEdit}
onSave={this.handleEditProperty}
onCancel={() => this.setState({ isEditingProperty: false })}
/>
);
}
}

get deletePropertyForm() {
if (this.state.isDeletingProperty) {
return (
<ConfirmationDialog
header="Delete Custom Property?"
body="Are you sure you want to delete the custom property?"
cancel="Cancel"
confirm="Yes, Delete"
isVisible={true}
confirmAction={this.handleDeleteProperty}
onCancel={() => this.setState({ isDeletingProperty: false }) }
/>
);
}
}

@autobind
controlButtons(name: string, type: string, value: any) {
const defaultProperties = keys(get(this.props.schema, 'properties', {}));

if (defaultProperties.includes(name)) {
return null;
}

return (
<div className={s.controls}>
<i className="icon-edit" onClick={() => this.onEdit(name, type, value)} />
<i className="icon-trash" onClick={() => this.onDelete(name)} />
</div>
);
}

@autobind
handleCreateProperty(property: { fieldLabel: string, propertyType: string }) {
const { fieldLabel, propertyType } = property;
const label = fieldLabel.toLowerCase();
// TODO show error message, if fieldLabel is not unique
if (!this.isUnique(label)) {
return null;
}

const value = (() => {
switch (propertyType) {
case('date'):
return new Date().toString();
case('bool'):
return false;
default:
return '';
}
})();
this.setState({
isAddingProperty: false
}, () => this.handleChange(label, propertyType, value));
}

@autobind
handleEditProperty(property: { fieldLabel: string, propertyType: string, fieldValue: any }) {
const { attributes } = this.props;
const { currentEdit: { name } } = this.state;
const { fieldLabel, propertyType, fieldValue } = property;

const preparedObject = omit(attributes, name);
const newAttributes = {
...preparedObject,
[fieldLabel]: {
t: propertyType,
v: fieldValue,
}
};

this.setState({
isEditingProperty: false,
currentEdit: {
name: '',
type: '',
value: ''
}
}, this.props.onChange(newAttributes));
}

@autobind
handleDeleteProperty() {
const newAttributes = omit(this.props.attributes, this.state.propertyToDelete);
this.setState({ isDeletingProperty: false }, this.props.onChange(newAttributes));
}

@autobind
handleChange(name: string, type: string, value: any) {
const { attributes } = this.props;
const newAttributes = {
...attributes,
[name]: {
t: type,
v: value,
}
};

this.props.onChange(newAttributes);
}

@autobind
isUnique(fieldLabel: string) {
const reservedNames = keys(get(this.props, 'attributes', {}));
const unique = !reservedNames.includes(fieldLabel);
return unique;
}

@autobind
processAttr(content: Element<*>, name: string, type: string, value: any) {
return (
<div key={name}>
{this.controlButtons(name, type, value)}
{content}
</div>
);
}

@autobind
handleAddProperty() {
this.setState({ isAddingProperty: true });
}

@autobind
onEdit(name: string, type: string, value: any) {
this.setState({
isEditingProperty: true,
currentEdit: {
name,
type,
value
},
});
}

@autobind
onDelete(name: string) {
this.setState({
isDeletingProperty: true,
propertyToDelete: name
});
}

get addCustomProperty() {
if (this.props.canAddProperty) {
return (
<div className={s.addProperty} onClick={this.handleAddProperty}>
<span className={s.buttonTitle}>Custom Property</span>
<a className={s.icon}>
<i className="icon-add" />
</a>
</div>
);
}
}

get children(): Element<*> {
return React.cloneElement((this.props.children), {
processAttr: this.processAttr,
});
}

render() {
return (
<div>
{this.children}
{this.addCustomProperty}
{this.customPropertyForm}
{this.deletePropertyForm}
</div>
);
}
}
12 changes: 12 additions & 0 deletions ashes/src/components/custom-properties/custom-property-modal.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.modal {
min-width: 575px;
}

:global .fc-dropdown {
max-width: 100%;
margin-bottom: 10px;
}

:global .fc-content-box {
margin-bottom: 0;
}
Loading