Skip to content

Commit

Permalink
Sorting blocks now uses the SortBlocks mutation
Browse files Browse the repository at this point in the history
  • Loading branch information
ScopeyNZ committed Oct 23, 2018
1 parent 019a0e5 commit 03421c8
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 73 deletions.
10 changes: 3 additions & 7 deletions client/src/components/ElementEditor/Element.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,19 +239,15 @@ class Element extends Component {
key={element.ID}
>
<HeaderComponent
id={element.ID}
title={element.Title}
version={element.Version}
isLiveVersion={element.IsLiveVersion}
isPublished={element.IsPublished}
elementType={element.BlockSchema.type}
fontIcon={element.BlockSchema.iconClass}
element={element}
expandable={element.InlineEditable}
link={link}
editTabs={editTabs}
previewExpanded={previewExpanded}
expandable={element.InlineEditable}
handleEditTabsClick={this.handleTabClick}
activeTab={activeTab}
disableTooltip={isDragging}
/>
<ContentComponent
id={element.ID}
Expand Down
17 changes: 1 addition & 16 deletions client/src/components/ElementEditor/ElementDragPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,6 @@ class ElementDragPreview extends Component {
}

const { x, y } = currentOffset;

const thing = element || {
ID: 2,
Title: 'Something blah',
Version: 5,
IsLiveVersion: true,
IsPublished: true,
BlockSchema: { iconClass: 'font-icon-block-form' },
};

const transform = `translate(${x}px, ${y}px)`;
const style = {
transform,
Expand All @@ -32,12 +22,7 @@ class ElementDragPreview extends Component {
return (
<div className="element-editor-drag-preview" style={style}>
<Header
id={thing.ID}
title={thing.Title}
version={thing.Version}
isLiveVersion={thing.IsLiveVersion}
isPublished={thing.IsPublished}
fontIcon={thing.BlockSchema.iconClass}
element={element}
simple
/>
</div>
Expand Down
23 changes: 18 additions & 5 deletions client/src/components/ElementEditor/ElementEditor.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, { PureComponent, PropTypes } from 'react';
import { inject } from 'lib/Injector';
import { compose } from 'redux';
import { elementTypeType } from 'types/elementTypeType';
import { connect } from 'react-redux';
import { compose } from 'redux';
import { loadElementFormStateName } from 'state/editor/loadElementFormStateName';
import { DragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import classnames from 'classnames';

import sortBlockMutation from 'state/editor/sortBlockMutation';
import ElementDragPreview from 'components/ElementEditor/ElementDragPreview';

/**
Expand All @@ -19,7 +19,7 @@ class ElementEditor extends PureComponent {
super(props);

this.state = {
dragTargetElementId: false,
dragTargetElementId: undefined,
isDragging: false,
draggedElement: null,
};
Expand Down Expand Up @@ -47,10 +47,19 @@ class ElementEditor extends PureComponent {
}

handleDragDrop() {
const { dragTargetElementId: targetId, draggedElement: element } = this.state;
const { actions: { handleSortBlock }, pageId } = this.props;

this.setState({
dragTargetElementId: false,
dragTargetElementId: undefined,
isDragging: false,
});

if (!handleSortBlock || (targetId && targetId === element.ID)) {
return;
}

handleSortBlock(element.ID, targetId || 0, pageId);
}

render() {
Expand Down Expand Up @@ -99,6 +108,9 @@ ElementEditor.propTypes = {
elementTypes: PropTypes.arrayOf(elementTypeType).isRequired,
pageId: PropTypes.number.isRequired,
elementalAreaId: PropTypes.number.isRequired,
actions: PropTypes.shape({
handleSortBlock: PropTypes.func,
}),
};

ElementEditor.defaultProps = {};
Expand Down Expand Up @@ -132,5 +144,6 @@ export default compose(
ListComponent,
}),
() => 'ElementEditor'
)
),
sortBlockMutation
)(ElementEditor);
1 change: 1 addition & 0 deletions client/src/components/ElementEditor/ElementList.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class ElementList extends Component {
element={element}
editTabs={this.getEditTabs(element)}
link={element.BlockSchema.actions.edit}
isDragging={isDragging}
onDragOver={onDragOver}
onDragDrop={onDragDrop}
onDragStart={onDragStart}
Expand Down
46 changes: 27 additions & 19 deletions client/src/components/ElementEditor/Header.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { Component, PropTypes } from 'react';
import { Tooltip } from 'reactstrap';
import { elementType } from 'types/elementType';
import { compose } from 'redux';
import { inject } from 'lib/Injector';
import i18n from 'i18n';
Expand All @@ -16,6 +17,19 @@ class Header extends Component {
};
}

componentDidUpdate() {
if (this.state.tooltipOpen && this.props.disableTooltip) {
// This addresses an issue where the tooltip will stick around after dragging. The
// ability to have a tooltip is back (props.disableTooltip) but the old state remains.
// Using `setState` in `componentDidUpdate` is dangerous but is okay within a reasonable
// condition that avoids the (potential) infinite loop.
// eslint-disable-next-line react/no-did-update-set-state
this.setState({
tooltipOpen: false
});
}
}

toggle() {
this.setState({
tooltipOpen: !this.state.tooltipOpen
Expand All @@ -28,7 +42,7 @@ class Header extends Component {
* @returns {DOMElement|null}
*/
renderVersionedStateMessage() {
const { isLiveVersion, isPublished } = this.props;
const { element: { IsLiveVersion: isLiveVersion, IsPublished: isPublished } } = this.props;

// No indication required for published elements
if (isPublished && isLiveVersion) {
Expand Down Expand Up @@ -58,20 +72,18 @@ class Header extends Component {

render() {
const {
id,
title,
elementType,
fontIcon,
expandable,
element,
previewExpanded,
simple,
disableTooltip,
expandable,
ElementActionsComponent,
} = this.props;

const noTitle = i18n.inject(i18n._t('ElementHeader.NOTITLE', 'Untitled {type} block'), { type: elementType });
const titleClasses = classNames({
'element-editor-header__title': true,
'element-editor-header__title--none': !title,
'element-editor-header__title--none': !element.Title,
});
const expandTitle = i18n._t('ElementHeader.EXPAND', 'Show editable fields');
const containerClasses = classNames(
Expand All @@ -87,6 +99,7 @@ class Header extends Component {
'font-icon-down-open-big': expandable && !previewExpanded,
}
);
const blockIconId = `element-icon-${element.ID}`;

return (
<div className={containerClasses}>
Expand All @@ -95,18 +108,18 @@ class Header extends Component {
</div>
<div className="element-editor-header__info">
<div className="element-editor-header__icon-container">
<i className={fontIcon} id={`element-editor-header__icon${id}`} />
<i className={element.BlockSchema.iconClass} id={blockIconId} />
{this.renderVersionedStateMessage()}
{!simple && <Tooltip
placement="top"
isOpen={this.state.tooltipOpen}
target={`element-editor-header__icon${id}`}
isOpen={this.state.tooltipOpen && !disableTooltip}
target={blockIconId}
toggle={this.toggle}
>
{elementType}
{element.BlockSchema.type}
</Tooltip>}
</div>
<h3 className={titleClasses}>{title || noTitle}</h3>
<h3 className={titleClasses}>{element.Title || noTitle}</h3>
</div>
{!simple && <div className="element-editor-header__actions">
{expandable &&
Expand All @@ -125,17 +138,12 @@ class Header extends Component {
}

Header.propTypes = {
id: PropTypes.string,
title: PropTypes.string,
version: PropTypes.number,
isLiveVersion: PropTypes.bool,
isPublished: PropTypes.bool,
element: elementType.isRequired,
elementType: PropTypes.string,
fontIcon: PropTypes.string,
simple: PropTypes.bool,
ElementActionsComponent: React.PropTypes.oneOfType([React.PropTypes.node, React.PropTypes.func]),
expandable: PropTypes.bool,
previewExpanded: PropTypes.bool,
disableTooltip: PropTypes.bool,
};

Header.defaultProps = {
Expand Down
57 changes: 33 additions & 24 deletions client/src/components/ElementEditor/tests/Header-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,60 +11,62 @@ Enzyme.configure({ adapter: new Adapter() });
describe('Header', () => {
const ElementActionsComponent = () => <div />;
const testTabs = ['Content', 'Settings', 'History'];
const element = {
ID: '0',
InlineEditable: true,
Title: 'Sample File Block',
BlockSchema: {
type: 'File',
iconClass: 'font-icon-block-file',
},
};

describe('render()', () => {
it('should render the icon', () => {
element.ID = '11';
const wrapper = shallow(
<Header
id={'11'}
title="Sample File Block"
elementType="File"
fontIcon="font-icon-block-file"
element={element}
ElementActionsComponent={ElementActionsComponent}
/>
);

expect(wrapper.instance().props.id).toBe('11');
expect(wrapper.find('i.font-icon-block-file')).toHaveLength(1);
expect(wrapper.find('#element-editor-header__icon11')).toHaveLength(1);
expect(wrapper.find('#element-icon-11')).toHaveLength(1);
});

it('should render the title', () => {
element.ID = '12';
const wrapper = shallow(
<Header
id={'12'}
title="Sample File Block"
elementType="File"
fontIcon="font-icon-block-file"
element={element}
editTabs={testTabs}
ElementActionsComponent={ElementActionsComponent}
/>
);

expect(wrapper.instance().props.id).toBe('12');
expect(wrapper.text()).toContain('Sample File Block');
});

it('should contain a Tooltip', () => {
element.ID = '13';
const wrapper = shallow(
<Header
id={'13'}
title="Sample File Block"
elementType="File"
fontIcon="font-icon-block-file"
element={element}
editTabs={testTabs}
ElementActionsComponent={ElementActionsComponent}
/>
);

expect(wrapper.instance().props.id).toBe('13');
expect(wrapper.find('Tooltip').length).toBe(1);
expect(wrapper.instance().props.elementType).toBe('File');
const tooltip = wrapper.find('Tooltip');
expect(tooltip.length).toBe(1);
expect(tooltip.children().text()).toBe('File');
});

it('should render a "right caret" button when not expandable', () => {
const wrapper = shallow(
<Header
element={element}
expandable={false}
ElementActionsComponent={ElementActionsComponent}
/>
Expand All @@ -78,6 +80,7 @@ describe('Header', () => {
it('should render a "down caret" button when not expanded', () => {
const wrapper = shallow(
<Header
element={element}
expandable
previewExpanded={false}
ElementActionsComponent={ElementActionsComponent}
Expand All @@ -92,6 +95,7 @@ describe('Header', () => {
it('should render an "up caret" button when expanded', () => {
const wrapper = shallow(
<Header
element={element}
expandable
previewExpanded
ElementActionsComponent={ElementActionsComponent}
Expand All @@ -106,6 +110,7 @@ describe('Header', () => {
it('should render an ElementActions component when the element is expandable', () => {
const wrapper = shallow(
<Header
element={element}
expandable
ElementActionsComponent={ElementActionsComponent}
/>
Expand All @@ -117,6 +122,7 @@ describe('Header', () => {
it('should not render an ElementActions when the element is not expandable', () => {
const wrapper = shallow(
<Header
element={element}
expandable={false}
ElementActionsComponent={ElementActionsComponent}
/>
Expand All @@ -128,11 +134,12 @@ describe('Header', () => {

describe('renderVersionedStateMessage()', () => {
it('identifies draft versions', () => {
element.IsPublished = false;
element.IsLiveVersion = false;
const wrapper = shallow(
<Header
element={element}
ElementActionsComponent={ElementActionsComponent}
isPublished={false}
isLiveVersion={false}
/>
);

Expand All @@ -142,11 +149,12 @@ describe('Header', () => {
});

it('identifies modified versions', () => {
element.IsPublished = true;
element.IsLiveVersion = false;
const wrapper = shallow(
<Header
ElementActionsComponent={ElementActionsComponent}
isPublished
isLiveVersion={false}
element={element}
/>
);

Expand All @@ -156,11 +164,12 @@ describe('Header', () => {
});

it('ignores live versions', () => {
element.IsPublished = true;
element.IsLiveVersion = true;
const wrapper = shallow(
<Header
ElementActionsComponent={ElementActionsComponent}
isPublished
isLiveVersion
element={element}
/>
);

Expand Down
Loading

0 comments on commit 03421c8

Please sign in to comment.