initializes columns properly in ColumnSelector

This commit is contained in:
James
2020-05-21 09:41:11 -04:00
parent a1a8d0b982
commit a361b9a53d
6 changed files with 114 additions and 34 deletions

View File

@@ -0,0 +1,55 @@
const getInitialColumnState = ({
fields, timestamps, useAsTitle, defaultColumns,
} = {}) => {
let availableFields = [...fields].filter((field) => {
return field?.hidden !== true && field?.hidden?.admin !== true;
});
availableFields.push({
name: 'id',
label: 'ID',
});
if (timestamps) {
availableFields = availableFields.concat([
{
name: 'createdAt',
label: 'Created At',
},
{
name: 'modifiedAt',
label: 'Modified At',
},
]);
}
let initialColumns = [];
if (Array.isArray(defaultColumns)) {
initialColumns = defaultColumns;
} else if (useAsTitle) {
initialColumns.push(useAsTitle);
const remainingColumns = availableFields.filter((field) => {
return field.name !== useAsTitle;
}).slice(0, 2).map((field) => {
return field.name;
});
initialColumns = initialColumns.concat(remainingColumns);
} else {
initialColumns = availableFields.slice(0, 3).reduce((columns, field) => {
return [
...columns,
field.name,
];
}, []);
}
return {
columns: initialColumns,
fields: availableFields,
};
};
module.exports = getInitialColumnState;

View File

@@ -1,5 +1,6 @@
import React, { useEffect, useReducer } from 'react';
import React, { useState, useEffect, useReducer } from 'react';
import PropTypes from 'prop-types';
import getInitialState from './getInitialState';
import Pill from '../Pill';
import Plus from '../../icons/Plus';
import X from '../../icons/X';
@@ -8,58 +9,75 @@ import './index.scss';
const baseClass = 'column-selector';
const reducer = (state, { type, column }) => {
const reducer = (state, { type, payload }) => {
if (type === 'enable') {
return [
...state,
column,
payload,
];
}
return state.filter(remainingColumn => remainingColumn !== column);
if (type === 'replace') {
return [
...payload,
];
}
return state.filter(remainingColumn => remainingColumn !== payload);
};
const ColumnSelector = (props) => {
const {
handleChange,
fields,
collection,
} = props;
const [columns, dispatchColumns] = useReducer(reducer, []);
const [initialColumns, setInitialColumns] = useState([]);
const [availableFields, setAvailableFields] = useState([]);
const [columns, dispatchColumns] = useReducer(reducer, initialColumns);
useEffect(() => {
if (typeof handleChange === 'function') handleChange(columns);
}, [columns, handleChange]);
useEffect(() => {
const { columns: initializedColumns, fields: initializedFields } = getInitialState(collection);
setInitialColumns(initializedColumns);
setAvailableFields(initializedFields);
}, [collection]);
useEffect(() => {
dispatchColumns({ payload: initialColumns, type: 'replace' });
}, [initialColumns]);
return (
<div className={baseClass}>
{fields && fields.map((field) => {
if (field?.hidden !== true || field?.hidden?.admin !== true) {
const isEnabled = columns.find(column => column === field.name);
return (
<Pill
onClick={() => dispatchColumns({ column: field.name, type: isEnabled ? 'disable' : 'enable' })}
alignIcon="left"
key={field.name}
icon={isEnabled ? <X /> : <Plus />}
pillStyle={isEnabled ? 'dark' : undefined}
className={`${baseClass}__active-column`}
>
{field.label}
</Pill>
);
}
return null;
{availableFields && availableFields.map((field) => {
const isEnabled = columns.find(column => column === field.name);
return (
<Pill
onClick={() => dispatchColumns({ payload: field.name, type: isEnabled ? 'disable' : 'enable' })}
alignIcon="left"
key={field.name}
icon={isEnabled ? <X /> : <Plus />}
pillStyle={isEnabled ? 'dark' : undefined}
className={`${baseClass}__active-column`}
>
{field.label}
</Pill>
);
})}
</div>
);
};
ColumnSelector.propTypes = {
fields: PropTypes.arrayOf(
PropTypes.shape({}),
).isRequired,
collection: PropTypes.shape({
fields: PropTypes.arrayOf(
PropTypes.shape({}),
),
timestamps: PropTypes.bool,
}).isRequired,
handleChange: PropTypes.func.isRequired,
};

View File

@@ -2,10 +2,10 @@
.column-selector {
background: $color-background-gray;
padding: base(1) base(1) 0;
padding: base(1) base(1) base(.5);
.pill {
margin-right: base(1);
margin-bottom: base(1);
margin-right: base(.5);
margin-bottom: base(.5);
}
}

View File

@@ -15,6 +15,7 @@ const baseClass = 'list-controls';
const ListControls = (props) => {
const {
handleChange,
collection,
collection: {
useAsTitle,
fields,
@@ -63,7 +64,7 @@ const ListControls = (props) => {
/>
<Button
className={`${baseClass}__toggle-columns`}
buttonStyle={visibleDrawer === 'columns' ? 'secondary' : undefined}
buttonStyle={visibleDrawer === 'columns' ? undefined : 'secondary'}
onClick={() => setVisibleDrawer(visibleDrawer !== 'columns' ? 'columns' : false)}
icon={<Chevron />}
>
@@ -71,7 +72,7 @@ const ListControls = (props) => {
</Button>
<Button
className={`${baseClass}__toggle-where`}
buttonStyle={visibleDrawer === 'where' ? 'secondary' : undefined}
buttonStyle={visibleDrawer === 'where' ? undefined : 'secondary'}
onClick={() => setVisibleDrawer(visibleDrawer !== 'where' ? 'where' : false)}
icon={<Chevron />}
>
@@ -83,7 +84,7 @@ const ListControls = (props) => {
height={visibleDrawer === 'columns' ? 'auto' : 0}
>
<ColumnSelector
fields={fields}
collection={collection}
handleChange={setColumns}
/>
</AnimateHeight>

View File

@@ -17,8 +17,9 @@
.btn {
margin: 0 0 0 $baseline;
min-width: 150px;
&.btn--secondary {
&.btn--primary {
svg {
transform: rotate(180deg);
}