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

ENH Render some buttons for blocks that can not be edited inline #963

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

9 changes: 8 additions & 1 deletion client/src/components/ElementActions/SaveAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,18 @@ import { initialize } from 'redux-form';
* the inline edit form's data for the current block.
*/
const SaveAction = (MenuComponent) => (props) => {
if (!props.expandable) {
// Some elemental blocks can not be edited inline (e.g. User form blocks)
// We don't want to add a "Save action for those blocks.
return (
<MenuComponent {...props} />
);
}

const handleClick = (event) => {
event.stopPropagation();

const { element, type, securityId, formData, reinitialiseForm } = props;

const { jQuery: $ } = window;
const noTitle = i18n.inject(
i18n._t(
Expand Down
50 changes: 50 additions & 0 deletions client/src/components/ElementActions/tests/SaveAction-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* eslint-disable import/no-extraneous-dependencies */
/* global jest, describe, it, expect */

import React from 'react';
import { Component as SaveAction } from '../SaveAction';
import Enzyme, { mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });

describe('SaveAction', () => {
let wrapper = null;
const mockMutation = jest.fn(() => new Promise((resolve) => { resolve(); }));
const WrappedComponent = (props) => <div>{props.children}</div>;
const ActionComponent = SaveAction(WrappedComponent);

it('renders a button when block is expandable', () => {
wrapper = mount(
<ActionComponent
title="My save action"
element={{
ID: 123,
BlockSchema: { type: 'Test' },
canCreate: true
}}
expandable
actions={{ handlePublishBlock: mockMutation }}
toggle={false}
/>
);
expect(wrapper.find('button').length).toBe(1);
});

it('does not renders a button when block is not expandable', () => {
wrapper = mount(
<ActionComponent
title="My save action"
element={{
ID: 123,
BlockSchema: { type: 'Test' },
canCreate: true
}}
expandable={false}
actions={{ handlePublishBlock: mockMutation }}
toggle={false}
/>
);
expect(wrapper.find('button').length).toBe(0);
});
});
19 changes: 13 additions & 6 deletions client/src/components/ElementEditor/ElementActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ class ElementActions extends Component {
* @returns {HTMLElement[]|null}
*/
renderEditTabs() {
const { editTabs, activeTab, type } = this.props;
const { editTabs, activeTab, type, expandable } = this.props;

if (!editTabs || !editTabs.length) {
// Don't render tabs if the block is not expandable or if no tabs are defined
if (!expandable || !editTabs || !editTabs.length) {
return null;
}

Expand All @@ -59,12 +60,15 @@ class ElementActions extends Component {
* @returns {DropdownItem|null}
*/
renderDivider() {
const { children, editTabs } = this.props;
const { children, editTabs, expandable } = this.props;

if (editTabs && editTabs.length && React.Children.count(children)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I swap the return null and return DropdownItem around just so the approach between renderDivider and renderTabs are consistien

return <DropdownItem divider role="separator" />;
// Don't render divider if the block is not expandable or if no tabs are defined
// or if there's no actions displayed after the tab list
if (!expandable || !editTabs || !editTabs.length || React.Children.count(children) === 0) {
return null;
}
return null;

return <DropdownItem divider role="separator" />;
}

/**
Expand All @@ -76,6 +80,7 @@ class ElementActions extends Component {
render() {
const { children, id, ActionMenuComponent } = this.props;


const dropdownToggleClassNames = [
'element-editor-header__actions-toggle',
'btn',
Expand Down Expand Up @@ -112,10 +117,12 @@ ElementActions.propTypes = {
name: PropTypes.string,
})),
handleEditTabsClick: PropTypes.func.isRequired,
expandable: PropTypes.bool
};

ElementActions.defaultProps = {
editTabs: [],
expandable: true
};

export { ElementActions as Component };
Expand Down
26 changes: 11 additions & 15 deletions client/src/components/ElementEditor/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,21 +160,17 @@ class Header extends Component {
<h3 className={titleClasses}>{element.title || noTitle}</h3>
</div>
{!simple && <div className="element-editor-header__actions">
{expandable &&
<div
role="none"
onClick={(event) => event.stopPropagation()}
>
<ElementActionsComponent
element={element}
type={type}
areaId={areaId}
activeTab={activeTab}
editTabs={type.editTabs}
handleEditTabsClick={handleEditTabsClick}
/>
</div>
}
<div role="none" onClick={(event) => event.stopPropagation()}>
<ElementActionsComponent
element={element}
type={type}
areaId={areaId}
activeTab={activeTab}
editTabs={type.editTabs}
handleEditTabsClick={handleEditTabsClick}
expandable={expandable}
/>
</div>
<i className={expandCaretClasses} title={expandTitle} />
</div>}
</div>
Expand Down
23 changes: 22 additions & 1 deletion client/src/components/ElementEditor/tests/ElementActions-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ describe('ElementActions', () => {
expect(actions.at(0).props().title).toEqual('Content');
expect(actions.at(1).props().title).toEqual('Settings');
expect(actions.at(2).props().title).toEqual('History');
});
});
});

describe('render()', () => {
Expand Down Expand Up @@ -74,5 +74,26 @@ describe('ElementActions', () => {

expect(wrapper.find('DropdownItem').length).toBe(1);
});

it('should not render inline-edit items for non-expandable block', () => {
const wrapper = shallow(
<ElementActions
areaId={1}
expandable={false}
editTabs={testTabs}
type={{ title: 'Some block' }}
ActionMenuComponent={ActionMenuComponent}
handleEditTabsClick={editTabsClick}
/>
);

// No dropdown separator should exist when there are no non-CMS actions
expect(wrapper.find('DropdownItem').length).toBe(0);

// See all the relevant action menu options
expect(wrapper.html()).not.toContain('Content');
expect(wrapper.html()).not.toContain('Settings');
expect(wrapper.html()).not.toContain('History');
});
});
});
4 changes: 2 additions & 2 deletions client/src/components/ElementEditor/tests/Header-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ describe('Header', () => {
expect(wrapper.text()).toContain('ElementActionsComponent');
});

it('should not render an ElementActions when the element is not expandable', () => {
it('should render an ElementActions even when the element is not expandable', () => {
const wrapper = shallow(
<Header
element={element}
Expand All @@ -170,7 +170,7 @@ describe('Header', () => {
/>
);

expect(wrapper.text()).not.toContain('ElementActionsComponent');
expect(wrapper.text()).toContain('ElementActionsComponent');
maxime-rainville marked this conversation as resolved.
Show resolved Hide resolved
});
});

Expand Down
34 changes: 6 additions & 28 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2145,12 +2145,7 @@ colormin@^1.0.5:
css-color-names "0.0.4"
has "^1.0.1"

colors@^1.1.2:
version "1.4.0"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==

colors@~1.1.2:
colors@1.1.2, colors@^1.1.2, colors@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM=
Expand Down Expand Up @@ -2601,7 +2596,7 @@ debug@^3.1.0, debug@^3.2.7:
dependencies:
ms "^2.1.1"

debuglog@*, debuglog@^1.0.1:
debuglog@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
Expand Down Expand Up @@ -4713,7 +4708,7 @@ imports-loader@^0.6.5:
loader-utils "0.2.x"
source-map "0.1.x"

imurmurhash@*, imurmurhash@^0.1.4:
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
Expand Down Expand Up @@ -6225,11 +6220,6 @@ lodash._basecopy@^3.0.0:
resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36"
integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=

lodash._baseindexof@*:
version "3.1.0"
resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c"
integrity sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw=

lodash._baseuniq@~4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
Expand All @@ -6238,16 +6228,11 @@ lodash._baseuniq@~4.6.0:
lodash._createset "~4.0.0"
lodash._root "~3.0.0"

lodash._bindcallback@*, lodash._bindcallback@^3.0.0:
lodash._bindcallback@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e"
integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4=

lodash._cacheindexof@*:
version "3.0.2"
resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92"
integrity sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI=

lodash._createassigner@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11"
Expand All @@ -6257,19 +6242,12 @@ lodash._createassigner@^3.0.0:
lodash._isiterateecall "^3.0.0"
lodash.restparam "^3.0.0"

lodash._createcache@*:
version "3.1.2"
resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093"
integrity sha1-VtagZAF2JeeevKa4AY4XRAvc8JM=
dependencies:
lodash._getnative "^3.0.0"

lodash._createset@~4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26"
integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=

lodash._getnative@*, lodash._getnative@^3.0.0:
lodash._getnative@^3.0.0:
version "3.9.1"
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=
Expand Down Expand Up @@ -6380,7 +6358,7 @@ lodash.memoize@^4.1.2:
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=

lodash.restparam@*, lodash.restparam@^3.0.0:
lodash.restparam@^3.0.0:
version "3.6.1"
resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=
Expand Down