import * as React from 'react'; import Component from 'react-component-component'; import { connect } from 'react-redux'; import { IGlobalState } from 'src/store'; import Grid, { GridItem } from 'mineral-ui/Grid'; import Table, { TableCell } from 'mineral-ui/Table'; import { prop, sortBy } from 'ramda'; import { Dispatch } from 'redux'; import ExtendedFieldEditor from 'src/pages/ConfigEditorDashboard/ExtendedMappingEditor/ExtendedFieldEditor'; import FieldsFilter, { ISelectOption } from './FieldsFilterDisplay'; import SelectableTableRow from 'src/components/SelectableTableRow'; import { IExtendedMapping } from '../../VersionDashboard/AddProjectForm/types'; /*************** * redux container **************/ export interface IExternalProps { graphqlField: string; } interface IReduxStateProps { extendedMapping?: IExtendedMapping; } export const mapStateToProps = ( state: IGlobalState, { graphqlField }: IExternalProps, ): IReduxStateProps => { if (!state.configEditor.currentProjectData) { return {}; } else { const currentProjectIndexData = state.configEditor.currentProjectData.project.indices.find( (index) => index.graphqlField === graphqlField, ); if (currentProjectIndexData) { return { extendedMapping: currentProjectIndexData.extended, }; } else { return {}; } } }; interface IReduxDispatchProps {} const mapDispatchtoProps = ( dispatch: Dispatch, ownProps: IExternalProps, ): IReduxDispatchProps => ({}); /************************ * local state model ************************/ export interface ILocalState { filter: { active: string | null; isArray: string | null; primaryKey: string | null; quickSearchEnabled: string | null; type: string | null; field: string; }; selectedField: string | null; } interface IStateContainer { state: ILocalState; setState: (s: ILocalState) => void; } export const EXTENDED_FIELD_TYPES: { boolean: 'boolean'; date: 'date'; double: 'double'; float: 'float'; half_float: 'float'; id: 'id'; integer: 'integer'; keyword: 'keyword'; long: 'long'; nested: 'nested'; object: 'object'; scaled_float: 'float'; string: 'string'; text: 'text'; unsigned_long: 'long'; } = { boolean: 'boolean', date: 'date', double: 'double', float: 'float', half_float: 'float', id: 'id', integer: 'integer', keyword: 'keyword', long: 'long', nested: 'nested', object: 'object', scaled_float: 'float', string: 'string', text: 'text', unsigned_long: 'long', }; /********************** * rendered component *********************/ const FieldsTable = React.memo(Table, ({ data }, { data: nextData }) => { const toSelectedState = ({ selected }) => selected; const lastSelectedIndex = data.map(toSelectedState).indexOf(true); const nextSelectedIndex = nextData.map(toSelectedState).indexOf(true); return nextData.length === data.length && lastSelectedIndex === nextSelectedIndex; }); interface IInjectedProps extends IReduxStateProps, IReduxDispatchProps {} const Dashboard: React.ComponentType = connect( mapStateToProps, mapDispatchtoProps, )(({ extendedMapping, graphqlField }: IInjectedProps & IExternalProps) => { if (!extendedMapping) { return null; } const emptyFilter = { active: null, isArray: null, primaryKey: null, quickSearchEnabled: null, field: '', type: null, }; const initialState: ILocalState = { filter: emptyFilter, selectedField: extendedMapping[0].field, }; const onFieldFilterChange = ({ state, setState }: IStateContainer) => (e: React.SyntheticEvent) => setState({ ...state, filter: { ...state.filter, field: e.currentTarget.value }, }); const onFilterOptionSelect = (s: IStateContainer) => (field: keyof typeof extendedMapping[0]) => (e: ISelectOption) => s.setState({ ...s.state, filter: { ...s.state.filter, [field]: e.value, }, }); const setSelectedField = (s: IStateContainer) => (field: string) => () => { s.setState({ ...s.state, selectedField: field }); }; const getSelectedField = (s: IStateContainer) => extendedMapping.find((entry) => entry.field === s.state.selectedField); const getFilteredFields = (state: ILocalState): typeof extendedMapping => sortBy(prop('field'))( extendedMapping.filter((field) => { const { filter } = state; return ( field.field.includes(filter.field) && (filter.type ? field.type === filter.type : true) && (filter.active !== null ? String(field.active) === filter.active : true) && (filter.isArray !== null ? String(field.isArray) === filter.isArray : true) && (filter.primaryKey !== null ? String(field.primaryKey) === filter.primaryKey : true) && (filter.quickSearchEnabled !== null ? String(field.quickSearchEnabled) === filter.quickSearchEnabled : true) ); }), ); return ( {(s: IStateContainer) => { const filteredExtendedMapping = getFilteredFields(s.state); const selectedField = getSelectedField(s); const fieldTableColumns = [ { content: `Fields (${filteredExtendedMapping.length})`, key: 'field', }, ]; const fieldTableRows = filteredExtendedMapping.map((entry) => ({ selected: s.state.selectedField === entry.field, row: (props) => { return ( {entry.field} ); }, })); return (
{selectedField && ( )}
); }}
); }); export default Dashboard;