From 05b51be5e16210dc0dcc0e3bc28aed24c716236e Mon Sep 17 00:00:00 2001 From: Matthew Grill Date: Thu, 15 Mar 2018 08:35:52 -0700 Subject: [PATCH 01/10] Permissions --- package.json | 1 + .../05_pages/Permissions/Permissions.js | 130 ++++++++++++++++-- src/components/Helpers/Loading.js | 58 ++++++++ src/components/UI/index.js | 9 ++ src/components/UI/table.js | 81 +++++++++++ yarn.lock | 4 + 6 files changed, 270 insertions(+), 13 deletions(-) create mode 100644 src/components/Helpers/Loading.js create mode 100644 src/components/UI/index.js create mode 100644 src/components/UI/table.js diff --git a/package.json b/package.json index 1f73bc104..26b7fedb4 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "private": true, "dependencies": { "emotion": "^9.0.2", + "makecancelable": "^1.0.0", "prop-types": "^15.6.1", "react": "^16.2.0", "react-dom": "^16.2.0", diff --git a/src/components/05_pages/Permissions/Permissions.js b/src/components/05_pages/Permissions/Permissions.js index db8ca5e9a..22530d713 100644 --- a/src/components/05_pages/Permissions/Permissions.js +++ b/src/components/05_pages/Permissions/Permissions.js @@ -1,17 +1,121 @@ -import React from 'react'; -import { css } from 'emotion'; +import React, { Component, Fragment } from 'react'; +import makeCancelable from 'makecancelable'; -const styles = { - title: css` - text-decoration: underline; - `, -}; +import Loading from '../../Helpers/Loading'; + +import { Table, TableBody, TableHeaderSimple } from '../../UI'; -const Permissions = () => ( -
-

Permissions

-

This will be the permissions page.

-
-); +const Permissions = class Permissions extends Component { + state = { + loaded: false, + }; + componentDidMount() { + this.cancelFetch = makeCancelable( + Promise.all([ + fetch( + `${ + process.env.REACT_APP_DRUPAL_BASE_URL + }/admin-api/permissions?_format=json`, + ).then(res => res.json()), + fetch( + `${ + process.env.REACT_APP_DRUPAL_BASE_URL + }/jsonapi/user_role/user_role`, + ).then(res => res.json()), + ]) + .then(([permissions, { data: roles }]) => + this.setState({ + rawPermissions: Object.keys(permissions).map( + key => permissions[key], + ), + renderablePermissions: Object.keys(permissions).map( + key => permissions[key], + ), + roles, + loaded: true, + }), + ) + .catch(err => this.setState({ loaded: false, err })), + ); + } + componentWillUnmount() { + this.cancelFetch(); + } + groupPermissions = permissions => + Object.entries( + permissions.reduce((acc, cur) => { + acc[cur.provider] = acc[cur.provider] || []; + acc[cur.provider].push(cur); + return acc; + }, {}), + ); + createTableRows = (groupedPermissions, roles) => + [].concat( + ...groupedPermissions.map(([permissionGroupName, permissions]) => [ + { + key: `permissionGroup-${permissionGroupName}`, + colspan: roles.length + 1, + tds: [{permissionGroupName}], + }, + ...permissions.map(permission => ({ + key: `permissionGroup-${permissionGroupName}-${permission.title}`, + tds: [ + permission.title, + ...roles.map( + ({ attributes }) => + attributes.is_admin && attributes.id === 'administrator' ? ( + + ) : ( + + ), + ), + ], + })), + ]), + ); + handleKeyPress = event => { + const input = event.target.value.toLowerCase(); + this.setState(prevState => ({ + ...prevState, + renderablePermissions: prevState.rawPermissions.filter( + ({ title, description, provider, provider_label }) => + `${title}${description}${provider}${provider_label}`.includes(input), + ), + })); + }; + render() { + return !this.state.loaded ? ( + + ) : ( + + + + + label.toUpperCase(), + ), + ]} + /> + +
+
+ ); + } +}; export default Permissions; diff --git a/src/components/Helpers/Loading.js b/src/components/Helpers/Loading.js new file mode 100644 index 000000000..26da2a54a --- /dev/null +++ b/src/components/Helpers/Loading.js @@ -0,0 +1,58 @@ +import React from 'react'; +import { css } from 'emotion'; + +const spinner = css` + margin: 100px auto 0; + width: 70px; + text-align: center; + > div { + width: 10px; + height: 10px; + background-color: #333; + + border-radius: 100%; + display: inline-block; + -webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both; + animation: sk-bouncedelay 1.4s infinite ease-in-out both; + } + .bounce1 { + -webkit-animation-delay: -0.32s; + animation-delay: -0.32s; + } + .bounce2 { + -webkit-animation-delay: -0.16s; + animation-delay: -0.16s; + } + @-webkit-keyframes sk-bouncedelay { + 0%, + 80%, + 100% { + -webkit-transform: scale(0); + } + 40% { + -webkit-transform: scale(1); + } + } + @keyframes sk-bouncedelay { + 0%, + 80%, + 100% { + -webkit-transform: scale(0); + transform: scale(0); + } + 40% { + -webkit-transform: scale(1); + transform: scale(1); + } + } +`; + +const Loading = () => ( +
+
+
+
+
+); + +export default Loading; diff --git a/src/components/UI/index.js b/src/components/UI/index.js new file mode 100644 index 000000000..bb4089b2a --- /dev/null +++ b/src/components/UI/index.js @@ -0,0 +1,9 @@ +import { TR, TD, TABLE, TBODY, THEAD } from './table'; + +export { + TR as TableRow, + TD as TableData, + TABLE as Table, + TBODY as TableBody, + THEAD as TableHeaderSimple, +}; diff --git a/src/components/UI/table.js b/src/components/UI/table.js new file mode 100644 index 000000000..9ca4490bc --- /dev/null +++ b/src/components/UI/table.js @@ -0,0 +1,81 @@ +import React from 'react'; +import { css } from 'emotion'; +import { + node, + bool, + oneOfType, + arrayOf, + string, + shape, + number, +} from 'prop-types'; + +const generateIDs = arr => + arr.map(value => ({ + value, + id: Math.random() + .toString(36) + .substring(2), + })); + +const TABLE = ({ children, zebra, ...props }) => { + const styles = css` + ${zebra ? 'tbody tr:nth-child(odd) {background-color: #e8e8e8;}' : ''}; + `; + return ( + + {children} +
+ ); +}; +TABLE.propTypes = { + children: oneOfType([arrayOf(node), node]).isRequired, + zebra: bool, +}; +TABLE.defaultProps = { + zebra: false, +}; + +const TR = ({ children, ...props }) => {children}; +TR.propTypes = { + children: oneOfType([arrayOf(node), node]).isRequired, +}; + +const TD = ({ children, ...props }) => {children}; +TD.propTypes = { + children: oneOfType([arrayOf(node), node]).isRequired, +}; + +const THEAD = ({ data }) => ( + + {data.map(label => {label})} + +); +THEAD.propTypes = { + data: arrayOf(string).isRequired, +}; + +const TBODY = ({ rows }) => ( + + {rows.map(({ colspan, tds, key }) => ( + + {generateIDs(tds).map(({ id, value }) => ( + + {value} + + ))} + + ))} + +); +TBODY.propTypes = { + rows: arrayOf( + shape({ + colspan: number, + key: string, + tds: arrayOf(node).isRequired, + }), + ).isRequired, +}; + +export { TR, TD, TABLE, TBODY, THEAD }; diff --git a/yarn.lock b/yarn.lock index 681b12ffa..91701bc30 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4647,6 +4647,10 @@ make-dir@^1.0.0: dependencies: pify "^3.0.0" +makecancelable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/makecancelable/-/makecancelable-1.0.0.tgz#c7e2606e59db7a4bf8098ff5b52d7f13173499e5" + makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" From 70b19e44c2659299100a4a090e1f9fad9e0f5ad5 Mon Sep 17 00:00:00 2001 From: Matthew Grill Date: Thu, 15 Mar 2018 08:45:15 -0700 Subject: [PATCH 02/10] Parse incoming HTML strings for permission titles with Interweave. --- package.json | 1 + src/components/05_pages/Permissions/Permissions.js | 4 ++-- yarn.lock | 7 +++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 26b7fedb4..2fa9157fb 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "private": true, "dependencies": { "emotion": "^9.0.2", + "interweave": "^8.0.2", "makecancelable": "^1.0.0", "prop-types": "^15.6.1", "react": "^16.2.0", diff --git a/src/components/05_pages/Permissions/Permissions.js b/src/components/05_pages/Permissions/Permissions.js index 22530d713..d788c17d4 100644 --- a/src/components/05_pages/Permissions/Permissions.js +++ b/src/components/05_pages/Permissions/Permissions.js @@ -1,8 +1,8 @@ import React, { Component, Fragment } from 'react'; import makeCancelable from 'makecancelable'; +import { Markup } from 'interweave'; import Loading from '../../Helpers/Loading'; - import { Table, TableBody, TableHeaderSimple } from '../../UI'; const Permissions = class Permissions extends Component { @@ -60,7 +60,7 @@ const Permissions = class Permissions extends Component { ...permissions.map(permission => ({ key: `permissionGroup-${permissionGroupName}-${permission.title}`, tds: [ - permission.title, + , ...roles.map( ({ attributes }) => attributes.is_admin && attributes.id === 'administrator' ? ( diff --git a/yarn.lock b/yarn.lock index 91701bc30..ed726b912 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3700,6 +3700,13 @@ interpret@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" +interweave@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/interweave/-/interweave-8.0.2.tgz#51001199c58d311f8b1d0100c4f6b9d494e97480" + dependencies: + babel-runtime "^6.26.0" + prop-types "^15.6.0" + invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2: version "2.2.3" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.3.tgz#1a827dfde7dcbd7c323f0ca826be8fa7c5e9d688" From 7351d07fa43eba6f7a0460358ed2a85787a3c723 Mon Sep 17 00:00:00 2001 From: Daniel Wehner Date: Thu, 15 Mar 2018 16:27:46 +0000 Subject: [PATCH 03/10] Store the permissions of each role --- .../05_pages/Permissions/Permissions.js | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/components/05_pages/Permissions/Permissions.js b/src/components/05_pages/Permissions/Permissions.js index d788c17d4..0698aa47d 100644 --- a/src/components/05_pages/Permissions/Permissions.js +++ b/src/components/05_pages/Permissions/Permissions.js @@ -31,6 +31,7 @@ const Permissions = class Permissions extends Component { renderablePermissions: Object.keys(permissions).map( key => permissions[key], ), + changedRoles: [], roles, loaded: true, }), @@ -49,6 +50,31 @@ const Permissions = class Permissions extends Component { return acc; }, {}), ); + + togglePermission = (permission, roleName, roles) => { + let roleIndex = roles.map(role => role.attributes.id).indexOf(roleName); + let role = roles[roleIndex]; + const index = role.attributes.permissions.indexOf(permission); + if (index !== -1) { + role.attributes.permissions.splice(index, 1); + } else { + role.attributes.permissions.push(permission); + } + roles[roleIndex] = role; + return roles; + }; + + onPermissionCheck = (roleName, permission) => { + this.setState((prevState, props) => { + return { + changedRoles: [ + ...new Set(prevState.changedRoles).add(roleName).values(), + ], + roles: this.togglePermission(permission, roleName, prevState.roles), + }; + }); + }; + createTableRows = (groupedPermissions, roles) => [].concat( ...groupedPermissions.map(([permissionGroupName, permissions]) => [ @@ -68,6 +94,9 @@ const Permissions = class Permissions extends Component { ) : ( + this.onPermissionCheck(attributes.id, permission.id) + } checked={attributes.permissions.includes(permission.id)} /> ), From 7663ba13392121fb313a869ce3a35f352d43444d Mon Sep 17 00:00:00 2001 From: Daniel Wehner Date: Thu, 15 Mar 2018 16:33:30 +0000 Subject: [PATCH 04/10] Move the admin role to the right --- .../05_pages/Permissions/Permissions.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/components/05_pages/Permissions/Permissions.js b/src/components/05_pages/Permissions/Permissions.js index 0698aa47d..d5206d1eb 100644 --- a/src/components/05_pages/Permissions/Permissions.js +++ b/src/components/05_pages/Permissions/Permissions.js @@ -32,7 +32,21 @@ const Permissions = class Permissions extends Component { key => permissions[key], ), changedRoles: [], - roles, + // Move admin roles to the right. + roles: roles.sort((a, b) => { + if (a.attributes.is_admin && b.attributes.is_admin) { + return a.attributes.id - b.attributes.id; + } + else if (a.attributes.is_admin) { + return 1; + } + else if (b.attributes.is_admin) { + return -1; + } + else { + return a.attributes.id - b.attributes.id; + } + }), loaded: true, }), ) From ef5701e1cd1261a59bbc6b6198a3d27e705e1ac3 Mon Sep 17 00:00:00 2001 From: Matthew Grill Date: Thu, 15 Mar 2018 09:39:23 -0700 Subject: [PATCH 05/10] Cleanup Permissions. Peace-Wave loading initial work. --- .../05_pages/Permissions/Permissions.js | 52 ++++++-------- src/components/Helpers/Loading.js | 67 ++++++------------- 2 files changed, 43 insertions(+), 76 deletions(-) diff --git a/src/components/05_pages/Permissions/Permissions.js b/src/components/05_pages/Permissions/Permissions.js index d5206d1eb..5439b87c8 100644 --- a/src/components/05_pages/Permissions/Permissions.js +++ b/src/components/05_pages/Permissions/Permissions.js @@ -36,16 +36,12 @@ const Permissions = class Permissions extends Component { roles: roles.sort((a, b) => { if (a.attributes.is_admin && b.attributes.is_admin) { return a.attributes.id - b.attributes.id; - } - else if (a.attributes.is_admin) { + } else if (a.attributes.is_admin) { return 1; - } - else if (b.attributes.is_admin) { + } else if (b.attributes.is_admin) { return -1; } - else { - return a.attributes.id - b.attributes.id; - } + return a.attributes.id - b.attributes.id; }), loaded: true, }), @@ -56,18 +52,16 @@ const Permissions = class Permissions extends Component { componentWillUnmount() { this.cancelFetch(); } - groupPermissions = permissions => - Object.entries( - permissions.reduce((acc, cur) => { - acc[cur.provider] = acc[cur.provider] || []; - acc[cur.provider].push(cur); - return acc; - }, {}), - ); + onPermissionCheck = (roleName, permission) => { + this.setState(prevState => ({ + changedRoles: [...new Set(prevState.changedRoles).add(roleName).values()], + roles: this.togglePermission(permission, roleName, prevState.roles), + })); + }; togglePermission = (permission, roleName, roles) => { - let roleIndex = roles.map(role => role.attributes.id).indexOf(roleName); - let role = roles[roleIndex]; + const roleIndex = roles.map(role => role.attributes.id).indexOf(roleName); + const role = roles[roleIndex]; const index = role.attributes.permissions.indexOf(permission); if (index !== -1) { role.attributes.permissions.splice(index, 1); @@ -78,16 +72,14 @@ const Permissions = class Permissions extends Component { return roles; }; - onPermissionCheck = (roleName, permission) => { - this.setState((prevState, props) => { - return { - changedRoles: [ - ...new Set(prevState.changedRoles).add(roleName).values(), - ], - roles: this.togglePermission(permission, roleName, prevState.roles), - }; - }); - }; + groupPermissions = permissions => + Object.entries( + permissions.reduce((acc, cur) => { + acc[cur.provider] = acc[cur.provider] || []; + acc[cur.provider].push(cur); + return acc; + }, {}), + ); createTableRows = (groupedPermissions, roles) => [].concat( @@ -108,7 +100,7 @@ const Permissions = class Permissions extends Component { ) : ( + onChange={() => this.onPermissionCheck(attributes.id, permission.id) } checked={attributes.permissions.includes(permission.id)} @@ -124,8 +116,8 @@ const Permissions = class Permissions extends Component { this.setState(prevState => ({ ...prevState, renderablePermissions: prevState.rawPermissions.filter( - ({ title, description, provider, provider_label }) => - `${title}${description}${provider}${provider_label}`.includes(input), + ({ title, description, provider, provider_label: providerLabel }) => + `${title}${description}${provider}${providerLabel}`.includes(input), ), })); }; diff --git a/src/components/Helpers/Loading.js b/src/components/Helpers/Loading.js index 26da2a54a..7beae5fac 100644 --- a/src/components/Helpers/Loading.js +++ b/src/components/Helpers/Loading.js @@ -1,57 +1,32 @@ import React from 'react'; import { css } from 'emotion'; -const spinner = css` - margin: 100px auto 0; - width: 70px; - text-align: center; - > div { - width: 10px; - height: 10px; - background-color: #333; - - border-radius: 100%; - display: inline-block; - -webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both; - animation: sk-bouncedelay 1.4s infinite ease-in-out both; - } - .bounce1 { - -webkit-animation-delay: -0.32s; - animation-delay: -0.32s; - } - .bounce2 { - -webkit-animation-delay: -0.16s; - animation-delay: -0.16s; - } - @-webkit-keyframes sk-bouncedelay { - 0%, - 80%, - 100% { - -webkit-transform: scale(0); - } - 40% { - -webkit-transform: scale(1); +const styles = { + wrap: css` + margin: 100px auto 0; + `, + left: css` + ::before { + content: '⬅️'; } - } - @keyframes sk-bouncedelay { - 0%, - 80%, - 100% { - -webkit-transform: scale(0); - transform: scale(0); + `, + right: css` + ::before { + content: '➡️'; } - 40% { - -webkit-transform: scale(1); - transform: scale(1); + `, + peace: css` + ::before { + content: '✌️'; } - } -`; + `, +}; const Loading = () => ( -
-
-
-
+
+ + +
); From 9cbe92230b2b6bbe128b252860b3197c10756772 Mon Sep 17 00:00:00 2001 From: Matthew Grill Date: Thu, 15 Mar 2018 11:26:25 -0700 Subject: [PATCH 06/10] Updated Peace-Wave loading component. Co-authored-by: Michael Herchel --- src/components/Helpers/Loading.js | 34 +++++++++++++++++-------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/components/Helpers/Loading.js b/src/components/Helpers/Loading.js index 7beae5fac..696026b5f 100644 --- a/src/components/Helpers/Loading.js +++ b/src/components/Helpers/Loading.js @@ -5,28 +5,32 @@ const styles = { wrap: css` margin: 100px auto 0; `, - left: css` - ::before { - content: '⬅️'; - } - `, - right: css` - ::before { - content: '➡️'; - } - `, peace: css` - ::before { - content: '✌️'; + display: inline-block; + vertical-align: middle; + animation-direction: alternate; + animation-iteration-count: infinite; + animation-duration: 0.5s; + animation-timing-function: cubic-bezier(0, 0, 1, 1); + transform-origin: bottom; + font-size: 50px; + animation-name: rotate; + @keyframes rotate { + from { + transform: rotate(-10deg); + } + to { + transform: rotate(10deg); + } } `, }; const Loading = () => (
- - - + + ✌️ +
); From 406d2ab913c046b3bc0672709e1ad4204d6aeff0 Mon Sep 17 00:00:00 2001 From: Matthew Grill Date: Fri, 16 Mar 2018 09:09:40 -0700 Subject: [PATCH 07/10] Fixes - Keyframes adjustments. Accept header for JSON API requests. Performance improvements for Table Body components. --- .../05_pages/Permissions/Permissions.js | 43 ++++++++++--------- src/components/Helpers/Loading.js | 21 ++++----- src/components/UI/index.js | 9 ---- src/components/UI/table.js | 22 +++++----- 4 files changed, 44 insertions(+), 51 deletions(-) delete mode 100644 src/components/UI/index.js diff --git a/src/components/05_pages/Permissions/Permissions.js b/src/components/05_pages/Permissions/Permissions.js index 5439b87c8..c208edf33 100644 --- a/src/components/05_pages/Permissions/Permissions.js +++ b/src/components/05_pages/Permissions/Permissions.js @@ -3,11 +3,13 @@ import makeCancelable from 'makecancelable'; import { Markup } from 'interweave'; import Loading from '../../Helpers/Loading'; -import { Table, TableBody, TableHeaderSimple } from '../../UI'; +import { Table, TableBody, TableHeaderSimple } from '../../UI/Table'; const Permissions = class Permissions extends Component { state = { loaded: false, + rawPermissions: [], + renderablePermissions: [], }; componentDidMount() { this.cancelFetch = makeCancelable( @@ -21,6 +23,7 @@ const Permissions = class Permissions extends Component { `${ process.env.REACT_APP_DRUPAL_BASE_URL }/jsonapi/user_role/user_role`, + { headers: { Accept: 'application/vnd.api+json' } }, ).then(res => res.json()), ]) .then(([permissions, { data: roles }]) => @@ -58,7 +61,6 @@ const Permissions = class Permissions extends Component { roles: this.togglePermission(permission, roleName, prevState.roles), })); }; - togglePermission = (permission, roleName, roles) => { const roleIndex = roles.map(role => role.attributes.id).indexOf(roleName); const role = roles[roleIndex]; @@ -71,7 +73,6 @@ const Permissions = class Permissions extends Component { roles[roleIndex] = role; return roles; }; - groupPermissions = permissions => Object.entries( permissions.reduce((acc, cur) => { @@ -80,33 +81,35 @@ const Permissions = class Permissions extends Component { return acc; }, {}), ); - createTableRows = (groupedPermissions, roles) => [].concat( ...groupedPermissions.map(([permissionGroupName, permissions]) => [ { key: `permissionGroup-${permissionGroupName}`, colspan: roles.length + 1, - tds: [{permissionGroupName}], + tds: [[`td-${permissionGroupName}`, {permissionGroupName}]], }, ...permissions.map(permission => ({ key: `permissionGroup-${permissionGroupName}-${permission.title}`, tds: [ - , - ...roles.map( - ({ attributes }) => - attributes.is_admin && attributes.id === 'administrator' ? ( - - ) : ( - - this.onPermissionCheck(attributes.id, permission.id) - } - checked={attributes.permissions.includes(permission.id)} - /> - ), - ), + [ + `td-${permissionGroupName}-${permission.title}`, + , + ], + ...roles.map(({ attributes }, index) => [ + `td-${permissionGroupName}-${permission.title}-${index}-cb`, + attributes.is_admin && attributes.id === 'administrator' ? ( + + ) : ( + + this.onPermissionCheck(attributes.id, permission.id) + } + checked={attributes.permissions.includes(permission.id)} + /> + ), + ]), ], })), ]), diff --git a/src/components/Helpers/Loading.js b/src/components/Helpers/Loading.js index 696026b5f..72562817a 100644 --- a/src/components/Helpers/Loading.js +++ b/src/components/Helpers/Loading.js @@ -1,5 +1,14 @@ import React from 'react'; -import { css } from 'emotion'; +import { css, keyframes } from 'emotion'; + +const rotate = keyframes` + from { + transform: rotate(-10deg); + } + to { + transform: rotate(10deg); + } +`; const styles = { wrap: css` @@ -14,15 +23,7 @@ const styles = { animation-timing-function: cubic-bezier(0, 0, 1, 1); transform-origin: bottom; font-size: 50px; - animation-name: rotate; - @keyframes rotate { - from { - transform: rotate(-10deg); - } - to { - transform: rotate(10deg); - } - } + animation-name: ${rotate}; `, }; diff --git a/src/components/UI/index.js b/src/components/UI/index.js deleted file mode 100644 index bb4089b2a..000000000 --- a/src/components/UI/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import { TR, TD, TABLE, TBODY, THEAD } from './table'; - -export { - TR as TableRow, - TD as TableData, - TABLE as Table, - TBODY as TableBody, - THEAD as TableHeaderSimple, -}; diff --git a/src/components/UI/table.js b/src/components/UI/table.js index 9ca4490bc..0f97998d3 100644 --- a/src/components/UI/table.js +++ b/src/components/UI/table.js @@ -10,14 +10,6 @@ import { number, } from 'prop-types'; -const generateIDs = arr => - arr.map(value => ({ - value, - id: Math.random() - .toString(36) - .substring(2), - })); - const TABLE = ({ children, zebra, ...props }) => { const styles = css` ${zebra ? 'tbody tr:nth-child(odd) {background-color: #e8e8e8;}' : ''}; @@ -59,9 +51,9 @@ const TBODY = ({ rows }) => ( {rows.map(({ colspan, tds, key }) => ( - {generateIDs(tds).map(({ id, value }) => ( - - {value} + {tds.map(([tdKey, tdValue]) => ( + + {tdValue} ))} @@ -78,4 +70,10 @@ TBODY.propTypes = { ).isRequired, }; -export { TR, TD, TABLE, TBODY, THEAD }; +export { + TR as TableRow, + TD as TableData, + TABLE as Table, + TBODY as TableBody, + THEAD as TableHeaderSimple, +}; From e6126cb9f5fba4477d78e9fa2e526e3679a4b050 Mon Sep 17 00:00:00 2001 From: Matthew Grill Date: Fri, 16 Mar 2018 13:10:32 -0700 Subject: [PATCH 08/10] Fixes initial state setup. Adjusts naming of Table exports. --- src/components/05_pages/Permissions/Permissions.js | 14 +++++--------- src/components/UI/table.js | 8 +------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/components/05_pages/Permissions/Permissions.js b/src/components/05_pages/Permissions/Permissions.js index c208edf33..9c96dd602 100644 --- a/src/components/05_pages/Permissions/Permissions.js +++ b/src/components/05_pages/Permissions/Permissions.js @@ -3,7 +3,7 @@ import makeCancelable from 'makecancelable'; import { Markup } from 'interweave'; import Loading from '../../Helpers/Loading'; -import { Table, TableBody, TableHeaderSimple } from '../../UI/Table'; +import { Table, TBody, THead } from '../../UI/Table'; const Permissions = class Permissions extends Component { state = { @@ -28,12 +28,8 @@ const Permissions = class Permissions extends Component { ]) .then(([permissions, { data: roles }]) => this.setState({ - rawPermissions: Object.keys(permissions).map( - key => permissions[key], - ), - renderablePermissions: Object.keys(permissions).map( - key => permissions[key], - ), + rawPermissions: permissions, + renderablePermissions: permissions, changedRoles: [], // Move admin roles to the right. roles: roles.sort((a, b) => { @@ -136,7 +132,7 @@ const Permissions = class Permissions extends Component { onKeyDown={this.handleKeyPress} /> - @@ -144,7 +140,7 @@ const Permissions = class Permissions extends Component { ), ]} /> - Date: Fri, 16 Mar 2018 17:21:48 -0400 Subject: [PATCH 09/10] Use human readable provider_label for permissions grouping label --- .../05_pages/Permissions/Permissions.js | 67 ++++++++++--------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/src/components/05_pages/Permissions/Permissions.js b/src/components/05_pages/Permissions/Permissions.js index 9c96dd602..495ac353d 100644 --- a/src/components/05_pages/Permissions/Permissions.js +++ b/src/components/05_pages/Permissions/Permissions.js @@ -72,43 +72,48 @@ const Permissions = class Permissions extends Component { groupPermissions = permissions => Object.entries( permissions.reduce((acc, cur) => { - acc[cur.provider] = acc[cur.provider] || []; - acc[cur.provider].push(cur); + acc[cur.provider] = acc[cur.provider] || { + providerLabel: cur.provider_label, + permissions: [], + }; + acc[cur.provider].permissions.push(cur); return acc; }, {}), ); createTableRows = (groupedPermissions, roles) => [].concat( - ...groupedPermissions.map(([permissionGroupName, permissions]) => [ - { - key: `permissionGroup-${permissionGroupName}`, - colspan: roles.length + 1, - tds: [[`td-${permissionGroupName}`, {permissionGroupName}]], - }, - ...permissions.map(permission => ({ - key: `permissionGroup-${permissionGroupName}-${permission.title}`, - tds: [ - [ - `td-${permissionGroupName}-${permission.title}`, - , + ...groupedPermissions.map( + ([providerMachineName, { providerLabel, permissions }]) => [ + { + key: `permissionGroup-${providerMachineName}`, + colspan: roles.length + 1, + tds: [[`td-${providerMachineName}`, {providerLabel}]], + }, + ...permissions.map(permission => ({ + key: `permissionGroup-${providerMachineName}-${permission.title}`, + tds: [ + [ + `td-${providerMachineName}-${permission.title}`, + , + ], + ...roles.map(({ attributes }, index) => [ + `td-${providerMachineName}-${permission.title}-${index}-cb`, + attributes.is_admin && attributes.id === 'administrator' ? ( + + ) : ( + + this.onPermissionCheck(attributes.id, permission.id) + } + checked={attributes.permissions.includes(permission.id)} + /> + ), + ]), ], - ...roles.map(({ attributes }, index) => [ - `td-${permissionGroupName}-${permission.title}-${index}-cb`, - attributes.is_admin && attributes.id === 'administrator' ? ( - - ) : ( - - this.onPermissionCheck(attributes.id, permission.id) - } - checked={attributes.permissions.includes(permission.id)} - /> - ), - ]), - ], - })), - ]), + })), + ], + ), ); handleKeyPress = event => { const input = event.target.value.toLowerCase(); From 107e1fa83c3f5ee49557b8cb2b01819367f1d385 Mon Sep 17 00:00:00 2001 From: Matthew Grill Date: Mon, 19 Mar 2018 09:05:36 -0700 Subject: [PATCH 10/10] Fix filesystem case issue. --- src/components/05_pages/Permissions/Permissions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/05_pages/Permissions/Permissions.js b/src/components/05_pages/Permissions/Permissions.js index 495ac353d..fd8679850 100644 --- a/src/components/05_pages/Permissions/Permissions.js +++ b/src/components/05_pages/Permissions/Permissions.js @@ -3,7 +3,7 @@ import makeCancelable from 'makecancelable'; import { Markup } from 'interweave'; import Loading from '../../Helpers/Loading'; -import { Table, TBody, THead } from '../../UI/Table'; +import { Table, TBody, THead } from '../../UI/table'; const Permissions = class Permissions extends Component { state = {