Fix edit view drag-n-drop design

This commit is contained in:
soupette 2018-08-09 18:21:31 +02:00
parent 3d42a91a0c
commit 3feae01952
13 changed files with 100 additions and 21 deletions

View File

@ -142,7 +142,7 @@ class InputNumberWithErrors extends React.Component { // eslint-disable-line rea
InputNumberWithErrors.defaultProps = { InputNumberWithErrors.defaultProps = {
autoFocus: false, autoFocus: false,
className: '', className: '',
customBootstrapClass: 'col-md-6', customBootstrapClass: 'col-md-4',
deactivateErrorHighlight: false, deactivateErrorHighlight: false,
didCheckErrors: false, didCheckErrors: false,
disabled: false, disabled: false,

View File

@ -37,6 +37,9 @@ class Manager {
let ret; let ret;
switch(number) { switch(number) {
case 12:
ret = [];
break;
case 9: case 9:
ret = ['__col-md-3__', '__col-md-6__']; ret = ['__col-md-3__', '__col-md-6__'];
break; break;
@ -77,6 +80,11 @@ class Manager {
case 'checkbox': case 'checkbox':
case 'boolean': case 'boolean':
case 'date': case 'date':
case 'bigint':
case 'decimal':
case 'float':
case 'integer':
case 'number':
return 4; return 4;
case 'json': case 'json':
case 'wysiwyg': case 'wysiwyg':

View File

@ -7,10 +7,11 @@
justify-content: space-between; justify-content: space-between;
background: #E6F0FB !important; background: #E6F0FB !important;
line-height: 30px; line-height: 30px;
color: #333740; // box-sizing: border-box;
border: 1px solid darken(#AED4FB, 20%)!important; border: 1px solid #AED4FB!important;
border-radius: 2px; border-radius: 2px;
cursor: move !important; color: #007EFF;
font-weight: 500;
> i { > i {
margin-right: 10px; margin-right: 10px;

View File

@ -155,9 +155,9 @@ class DraggableAttr extends React.Component {
> >
<i className="fa fa-th" aria-hidden="true" /> <i className="fa fa-th" aria-hidden="true" />
<span>{name}</span> <span>{name}</span>
<ClickOverHint show={isOver && !isDragging} /> <ClickOverHint show={isOver && !isDragging && !isEditing} />
{ !isOver && name.toLowerCase() !== label.toLowerCase() && ( { (!isOver || isEditing) && name.toLowerCase() !== label.toLowerCase() && (
<div className={styles.info}> <div className={styles.infoLabel}>
{label} {label}
</div> </div>
)} )}
@ -165,7 +165,7 @@ class DraggableAttr extends React.Component {
<VariableEditIcon onClick={this.handleClickEdit} /> <VariableEditIcon onClick={this.handleClickEdit} />
) : ( ) : (
<DraggedRemovedIcon isDragging={dragStart} onRemove={this.handleRemove} /> <DraggedRemovedIcon isDragging={dragStart || isEditing} onRemove={this.handleRemove} />
)} )}
</div> </div>
), ),

View File

@ -25,6 +25,8 @@
.editingAttr { .editingAttr {
background: #E6F0FB!important; background: #E6F0FB!important;
border: 1px solid #AED4FB!important; border: 1px solid #AED4FB!important;
color: #007EFF;
font-weight: 500;
} }
.info { .info {
@ -35,6 +37,14 @@
font-style: italic; font-style: italic;
} }
.infoLabel {
position: absolute;
top: 0;
right: 40px;
color: #858B9A;
font-weight: 400;
}
.dragged { .dragged {
position: relative; position: relative;
height: 30px !important; height: 30px !important;

View File

@ -6,13 +6,26 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import cn from 'classnames';
import styles from './styles.scss'; import styles from './styles.scss';
function DraggedRemovedIcon({ isDragging, onRemove, withLongerHeight, ...rest }) { function DraggedRemovedIcon({ isDragging, onRemove, withLongerHeight, ...rest }) {
let className = styles.removeIcon;
if (isDragging) {
className = styles.removeIconDragged;
}
if (withLongerHeight) {
className = styles.removeIconLonger;
}
if (isDragging && withLongerHeight) {
className = styles.removeIconLongerDragged;
}
return ( return (
<span <span
className={cn( isDragging && styles.removeIconDragged, withLongerHeight ? styles.removeIconLonger : styles.removeIcon)} className={className}
onClick={onRemove} onClick={onRemove}
{...rest} {...rest}
/> />

View File

@ -5,6 +5,7 @@
cursor: pointer; cursor: pointer;
text-align: center; text-align: center;
float: right; float: right;
line-height: 28px !important;
&:after { &:after {
display: inline-block; display: inline-block;
@ -12,14 +13,13 @@
width: 8px; width: 8px;
height: 8px; height: 8px;
margin: auto; margin: auto;
margin-top: -3px;
background-image: url('../../assets/images/icon-cross.svg'); background-image: url('../../assets/images/icon-cross.svg');
} }
} }
.removeIconDragged { .removeIconDragged {
width: 30px; width: 30px;
background: #F3F4F4; background: #AED4FB;
height: 28px; height: 28px;
cursor: pointer; cursor: pointer;
text-align: center; text-align: center;
@ -54,3 +54,22 @@
background-image: url('../../assets/images/icon-cross.svg'); background-image: url('../../assets/images/icon-cross.svg');
} }
} }
.removeIconLongerDragged {
width: 30px;
background: #AED4FB;
height: 82px;
line-height: 82px;
cursor: pointer;
text-align: center;
float: right;
&:after {
display: inline-block;
content: '';
width: 8px;
height: 8px;
margin: auto;
background-image: url('../../assets/images/icon-cross-blue.svg');
}
}

View File

@ -27,6 +27,11 @@ const getBootstrapClass = attrType => {
case 'boolean': case 'boolean':
case 'toggle': case 'toggle':
case 'date': case 'date':
case 'bigint':
case 'decimal':
case 'float':
case 'integer':
case 'number':
return { return {
bootstrap: 'col-md-4', bootstrap: 'col-md-4',
wrapper: cn(styles.attrWrapper), wrapper: cn(styles.attrWrapper),
@ -41,6 +46,7 @@ const getBootstrapClass = attrType => {
withLongerHeight: true, withLongerHeight: true,
}; };
case 'file': case 'file':
case 'text':
return { return {
bootstrap: 'col-md-6', bootstrap: 'col-md-6',
wrapper: cn(styles.attrWrapper, styles.customHeight), wrapper: cn(styles.attrWrapper, styles.customHeight),
@ -232,19 +238,19 @@ class VariableDraggableAttr extends React.Component {
{ showLeftCarret && <Carret style={carretStyle} />} { showLeftCarret && <Carret style={carretStyle} />}
<div className={cn(classNames.wrapper, isEditing && styles.editingVariableAttr)} style={style}> <div className={cn(classNames.wrapper, isEditing && styles.editingVariableAttr)} style={style}>
<i className="fa fa-th" /> <i className="fa fa-th" />
<span className={styles.truncated}> <span className={cn(isEditing && styles.editing, styles.truncated)}>
{name} {name}
</span> </span>
<ClickOverHint show={isOver} /> <ClickOverHint show={isOver && !isEditing} />
{!isOver && get(data, 'name', '').toLowerCase() !== get(data, 'label', '').toLowerCase() && ( {(!isOver || isEditing) && get(data, 'name', '').toLowerCase() !== get(data, 'label', '').toLowerCase() && (
<div className={styles.info}> <div className={styles.infoLabel}>
{data.label} {data.label}
</div> </div>
)} )}
{isEditing && !isOver ? ( {isEditing && !isOver ? (
<VariableEditIcon withLongerHeight={classNames.withLongerHeight} onClick={this.handleClickEdit} /> <VariableEditIcon withLongerHeight={classNames.withLongerHeight} onClick={this.handleClickEdit} />
) : ( ) : (
<DraggedRemovedIcon withLongerHeight={classNames.withLongerHeight} onRemove={this.handleRemove} /> <DraggedRemovedIcon isDragging={isEditing} withLongerHeight={classNames.withLongerHeight} onRemove={this.handleRemove} />
)} )}
</div> </div>
{ showRightCarret && <Carret style={carretStyle} />} { showRightCarret && <Carret style={carretStyle} />}

View File

@ -55,6 +55,14 @@
font-style: italic; font-style: italic;
} }
.infoLabel {
position: absolute;
top: 0;
right: 40px;
color: #858B9A;
font-weight: 400;
}
.truncated { .truncated {
overflow: hidden; overflow: hidden;
white-space:nowrap; white-space:nowrap;
@ -71,3 +79,8 @@
width: 10px; width: 10px;
background: blue; background: blue;
} }
.editing {
color: #007EFF;
font-weight: 500;
}

View File

@ -5,7 +5,7 @@ import Manager from 'utils/Manager';
const stateUpdater = (obj, array, keys) => obj.updateIn(['modifiedSchema', 'models', ...keys.split('.'), 'fields'], () => array); const stateUpdater = (obj, array, keys) => obj.updateIn(['modifiedSchema', 'models', ...keys.split('.'), 'fields'], () => array);
const createManager = (obj, array, keys, dropIndex, layout) => new Manager(stateUpdater(obj, array, keys), array, keys, dropIndex, layout); const createManager = (obj, array, keys, dropIndex, layout) => new Manager(stateUpdater(obj, array, keys), array, keys, dropIndex, layout);
const getElementsOnALine = (manager, line, list) => { const getElementsOnALine = (manager, line, list) => {
const firstElIndex = line === 0 ? 0 : manager.arrayOfEndLineElements[line - 1].index + 1; const firstElIndex = line === 0 ? 0 : get(manager.arrayOfEndLineElements[line - 1], 'index', list.size -1) + 1;
const lastElIndex = get(manager.arrayOfEndLineElements[line], 'index', list.size -1) + 1; const lastElIndex = get(manager.arrayOfEndLineElements[line], 'index', list.size -1) + 1;
const elements = manager.getElementsOnALine(range(firstElIndex, lastElIndex)); const elements = manager.getElementsOnALine(range(firstElIndex, lastElIndex));

View File

@ -373,8 +373,8 @@ function appReducer(state = initialState, action) {
return state return state
.updateIn(['modifiedSchema', 'models', ...action.keys.split('.'), 'fields'], list => { .updateIn(['modifiedSchema', 'models', ...action.keys.split('.'), 'fields'], list => {
const manager = new Manager(state, list, action.keys, 0, layout); const manager = new Manager(state, list, action.keys, 0, layout);
const newList = reorderList(manager, manager.getLayout()); const newList = manager.getLayout();
updatedList = newList; updatedList = reorderList(manager, newList);
return newList; return newList;
}) })

View File

@ -48,6 +48,7 @@
> p { > p {
margin-bottom: 28px; margin-bottom: 28px;
color: #787E8F; color: #787E8F;
font-weight: 400;
} }
} }

View File

@ -37,6 +37,9 @@ class Manager {
let ret; let ret;
switch(number) { switch(number) {
case 12:
ret = [];
break;
case 9: case 9:
ret = ['__col-md-3__', '__col-md-6__']; ret = ['__col-md-3__', '__col-md-6__'];
break; break;
@ -76,6 +79,11 @@ class Manager {
case 'checkbox': case 'checkbox':
case 'boolean': case 'boolean':
case 'date': case 'date':
case 'bigint':
case 'decimal':
case 'float':
case 'integer':
case 'number':
return 4; return 4;
case 'json': case 'json':
case 'wysiwyg': case 'wysiwyg':