@adaptabletools/adaptable
Version:
Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements
114 lines (113 loc) • 4.4 kB
JavaScript
import * as React from 'react';
import { useReducer, useState, useEffect } from 'react';
import { prepareDataSource, prepareGridOptions } from './helper';
import { Flex } from 'rebass';
import ConfigurationDialog from './AdaptableConfigurationDialog';
import FileDroppable from '../../components/FileDroppable';
import { validDataSource } from './Utils';
export const initialState = {
dropped: false,
};
export const reducer = (state, action) => {
if (action.type === 'DROPPED') {
return {
...state,
adaptableOptions: action.payload.adaptableOptions,
gridOptions: action.payload.gridOptions,
dropped: true,
error: null,
};
}
if (action.type === 'ERROR') {
return {
...state,
dropped: false,
error: action.payload,
};
}
if (action.type === 'CANCEL') {
return {
...state,
error: null,
dropped: false,
};
}
return state;
};
/**
* The wizard in a few modes:
*
* 1. Based on data:
* 1.1 Drag and drop a file
* 1.2 Fetch data from a url
*
* 2. Based on configuration:
* Provide a schema, on how the data looks like.
*/
export const Wizard = (props) => {
const [state, dispatch] = useReducer(reducer, {
...initialState,
adaptableOptions: props.adaptableOptions,
gridOptions: props.gridOptions,
});
const [droppableKey, setDroppableKey] = useState(Date.now());
const [isDataLoading, setIsDataLoading] = useState(false);
const handleDataSource = (array, file) => {
const dataSourceInfo = (props.prepareData || prepareDataSource)(array, file);
try {
validDataSource(dataSourceInfo);
}
catch (err) {
return dispatch({
type: 'ERROR',
payload: `Invalid adaptable configuration - ${err}`,
});
}
const gridOptions = prepareGridOptions(dataSourceInfo, props.gridOptions);
const adaptableOptions = { ...props.adaptableOptions };
adaptableOptions.adaptableId = adaptableOptions.adaptableId || (file ? file.name : '');
if (dataSourceInfo.primaryKey) {
adaptableOptions.primaryKey = dataSourceInfo.primaryKey;
}
const shouldShowWizard = props.fetchData ? Boolean(props.showFetchDataWizard) : true;
if (shouldShowWizard) {
dispatch({
type: 'DROPPED',
payload: { adaptableOptions, gridOptions },
});
}
else {
props.onInit(adaptableOptions, gridOptions);
}
};
let wizard;
if (props.skipToWizard || state.dropped) {
wizard = (React.createElement(ConfigurationDialog, { startSections: props.startSections, adaptableConfig: {
adaptableOptions: state.adaptableOptions,
gridOptions: state.gridOptions,
}, onCancel: () => {
// change the file droppable component key
// so it's remounted and it's in the initial state
setDroppableKey(Date.now());
dispatch({
type: 'CANCEL',
});
}, onFinish: (adaptableConfig) => {
props.onInit(adaptableConfig.adaptableOptions, adaptableConfig.gridOptions);
} }));
}
useEffect(() => {
if (props.fetchData) {
setIsDataLoading(true);
props.fetchData().then((data) => {
handleDataSource(data);
setIsDataLoading(false);
});
}
}, []);
const ddEnabled = props.ddEnabled ?? !props.fetchData;
return (React.createElement(React.Fragment, null,
ddEnabled && (React.createElement(FileDroppable, { key: droppableKey, className: 'ab-NocodeWizard', toJSON: props.fileContentsToJSON, readFile: props.readFile, fileAccept: props.fileAccept, helpText: props.helpText, message: state.error, defaultText: props.defaultActionMessage, dragOverText: props.dragOverActionMessage, loadingText: props.loadingMessage, onDropSuccess: handleDataSource })),
isDataLoading && (React.createElement(Flex, { className: 'ab-NocodeWizard', alignItems: "center", justifyContent: "center", flexDirection: "column" }, props.loadingMessage || 'Loading ...')),
wizard));
};