UNPKG

@adaptabletools/adaptable

Version:

Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements

169 lines (168 loc) 8.04 kB
import * as React from 'react'; import { WizardLegend } from './WizardLegend'; import { ArrayExtensions } from '../../Utilities/Extensions/ArrayExtensions'; import { Flex } from 'rebass'; import Dialog from '../../components/Dialog'; import SimpleButton from '../../components/SimpleButton'; import Panel from '../../components/Panel'; import kebabCase from 'lodash/kebabCase'; export const AdaptableWizardContext = React.createContext({ data: null, updateGoBackState: () => { }, onRender: (ActiveStep) => { }, api: null, }); export const useWizardContext = () => { return React.useContext(AdaptableWizardContext); }; class DummyActiveStep { canNext() { return false; } canBack() { return false; } next() { // no implementation for this } back() { // no implementation for this } getIndexStepIncrement() { return 1; } getIndexStepDecrement() { return 1; } } //Remark : the component doesnt handle the change of props once displayed... It's easy to do but not sure it's needed //as in the top component we do the render with a ternary expression so we add/remove the element from the render instead of having a property //Show/hide. export class AdaptableWizard extends React.Component { constructor(props) { super(props); //we need to init with a dummy one as Ref is a callback once the component is rendered. So once set we force Re render.... //I have no idea so far how to do it differently this.ActiveStep = new DummyActiveStep(); let indexStart = 0; if (this.props.stepStartIndex) { indexStart = this.props.stepStartIndex; } let BodyElement = this.props.steps[indexStart].Element; this.stepName = this.props.steps[indexStart].StepName; let newElement = this.cloneWizardStep(BodyElement); this.state = { ActiveState: newElement, IndexState: indexStart }; } render() { let wizardStepNames = ArrayExtensions.RetrieveDistinct(this.props.steps.map((x) => { return x.StepName; })); const hasNext = this.props.steps.length > 1; const hasBack = hasNext; return (React.createElement(AdaptableWizardContext.Provider, { value: { data: this.props.data, updateGoBackState: () => this.ForceUpdateGoBackState(), api: this.props.api, onRender: (ActiveStep) => { this.ActiveStep = ActiveStep; this.forceUpdate(); }, } }, React.createElement(Dialog, { modal: true, isOpen: true, showCloseButton: false, onDismiss: () => (this.props.onHide ? this.props.onHide() : null) }, React.createElement(Flex, { flexDirection: "column", "data-name": this.props.moduleInfo.FriendlyName ? `${kebabCase(this.props.moduleInfo.FriendlyName)}-wizard` : '', style: { height: '100%', width: '70vw', maxWidth: 1000, maxHeight: '80vh', ...this.props.style, } }, React.createElement(Panel, { header: this.props.moduleInfo.FriendlyName, border: "none", className: "ab-WizardDialog__steps", borderRadius: "none", variant: "primary", style: { flex: 'none' } }, this.props.showStepsLegend === false ? null : (React.createElement(WizardLegend, { StepNames: wizardStepNames, ActiveStepName: this.stepName, FriendlyName: '', CanShowAllSteps: this.canFinishWizard(), onStepButtonClicked: (s) => this.onStepButtonClicked(s) }))), React.createElement(Flex, { style: { flex: 1, overflow: 'auto' }, flexDirection: "column" }, this.state.ActiveState), React.createElement(Flex, { flexDirection: "row", padding: 2, backgroundColor: "primary", alignItems: "center", className: "ab-WizardDialog__footer" }, React.createElement(SimpleButton, { tone: "neutral", variant: "text", "data-name": "close", onClick: () => this.props.onHide(), tooltip: this.props.closeTooltip ?? 'Close wizard', accessLevel: 'Full' }, this.props.closeText ?? 'CLOSE'), React.createElement("div", { style: { flex: 1 } }), hasBack ? (React.createElement(SimpleButton, { "data-name": "back", variant: "outlined", disabled: !this.ActiveStep.canBack() || this.isFirstStep(), onClick: () => this.handleClickBack(), icon: "arrow-left", accessLevel: 'Full' }, "Back")) : null, hasNext ? (React.createElement(SimpleButton, { variant: "outlined", "data-name": "next", disabled: !this.ActiveStep.canNext() || this.isLastStep(), onClick: () => this.handleClickNext(), icon: "arrow-right", iconPosition: "end", accessLevel: 'Full', marginLeft: 2, marginRight: 2 }, "Next")) : null, React.createElement(SimpleButton, { tone: "accent", "data-name": "finish", variant: "raised", disabled: !this.canFinishWizard(), onClick: () => this.handleClickFinish(), icon: 'check', accessLevel: 'Full' }, "Finish")))))); } onStepButtonClicked(stepName) { let wizardStepInfo = this.props.steps.find((s) => s.StepName == stepName); let bodyElement = wizardStepInfo.Element; let newElement = this.cloneWizardStep(bodyElement); this.stepName = wizardStepInfo.StepName; this.setState({ ActiveState: newElement, IndexState: wizardStepInfo.Index, }); } ForceUpdateGoBackState() { this.forceUpdate(); } isLastStep() { return this.state.IndexState == this.props.steps.length - 1; } isFirstStep() { return this.state.IndexState == 0; } canFinishWizard() { return this.ActiveStep.canNext() && this.props.canFinishWizard(); } handleClickBack() { if (!this.isFirstStep()) { if (this.ActiveStep.canBack()) { let decrement = this.ActiveStep.getIndexStepDecrement(); this.ActiveStep.back(); let activeWizardInfo = this.props.steps[this.state.IndexState - decrement]; let bodyElement = activeWizardInfo.Element; let newElement = this.cloneWizardStep(bodyElement); this.stepName = activeWizardInfo.StepName; this.setState({ ActiveState: newElement, IndexState: this.state.IndexState - decrement, }); } } } handleClickNext() { if (this.ActiveStep.canNext()) { let increment = this.ActiveStep.getIndexStepIncrement(); this.ActiveStep.next(); let activeWizardInfo = this.props.steps[this.state.IndexState + increment]; let bodyElement = activeWizardInfo.Element; let newElement = this.cloneWizardStep(bodyElement); this.stepName = activeWizardInfo.StepName; this.setState({ ActiveState: newElement, IndexState: this.state.IndexState + increment, }); } } handleClickFinish() { if (this.ActiveStep.canNext()) { this.ActiveStep.next(); if (this.props.onFinish) { this.props.onFinish(); } this.props.onHide(); } } //So we inject everything needed for the Wizard cloneWizardStep(step) { return React.cloneElement(step, { ref: (Element) => { if (Element) { this.ActiveStep = Element; this.forceUpdate(); } else { this.ActiveStep = null; } }, data: this.props.data, updateGoBackState: () => this.ForceUpdateGoBackState(), api: this.props.api, }); } }