initializes columns properly in ColumnSelector
This commit is contained in:
@@ -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;
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
|
||||
.btn {
|
||||
margin: 0 0 0 $baseline;
|
||||
min-width: 150px;
|
||||
|
||||
&.btn--secondary {
|
||||
&.btn--primary {
|
||||
svg {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user