Skip to content

Commit

Permalink
[Drilldowns] Preserve state when selecting different action factory (#…
Browse files Browse the repository at this point in the history
…65074)

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
Dosant and elasticmachine authored May 7, 2020
1 parent 6ef45e1 commit 3604f5d
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ export interface ActionWizardProps {

/**
* Action factory selected changed
* null - means user click "change" and removed action factory selection
* empty - means user click "change" and removed action factory selection
*/
onActionFactoryChange: (actionFactory: ActionFactory | null) => void;
onActionFactoryChange: (actionFactory?: ActionFactory) => void;

/**
* current config for currently selected action factory
Expand Down Expand Up @@ -71,7 +71,7 @@ export const ActionWizard: React.FC<ActionWizardProps> = ({
actionFactory={currentActionFactory}
showDeselect={actionFactories.length > 1}
onDeselect={() => {
onActionFactoryChange(null);
onActionFactoryChange(undefined);
}}
context={context}
config={config}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export function Demo({ actionFactories }: { actionFactories: Array<ActionFactory
config?: ActionBaseConfig;
}>({});

function changeActionFactory(newActionFactory: ActionFactory | null) {
function changeActionFactory(newActionFactory?: ActionFactory) {
if (!newActionFactory) {
// removing action factory
return setState({});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,42 @@ test('Create only mode', async () => {
expect(await mockDynamicActionManager.state.get().events.length).toBe(1);
});

test('After switching between action factories state is restored', async () => {
const screen = render(
<FlyoutManageDrilldowns
placeContext={{}}
dynamicActionManager={mockDynamicActionManager}
viewMode={'create'}
/>
);
// wait for initial render. It is async because resolving compatible action factories is async
await wait(() => expect(screen.getAllByText(/Create/i).length).toBeGreaterThan(0));
fireEvent.change(screen.getByLabelText(/name/i), {
target: { value: 'test' },
});
fireEvent.click(screen.getByText(/Go to URL/i));
fireEvent.change(screen.getByLabelText(/url/i), {
target: { value: 'https://elastic.co' },
});

// change to dashboard
fireEvent.click(screen.getByText(/change/i));
fireEvent.click(screen.getByText(/Go to Dashboard/i));

// change back to url
fireEvent.click(screen.getByText(/change/i));
fireEvent.click(screen.getByText(/Go to URL/i));

expect(screen.getByLabelText(/url/i)).toHaveValue('https://elastic.co');
expect(screen.getByLabelText(/name/i)).toHaveValue('test');

fireEvent.click(screen.getAllByText(/Create Drilldown/i)[1]);
await wait(() => expect(notifications.toasts.addSuccess).toBeCalled());
expect(await (mockDynamicActionManager.state.get().events[0].action.config as any).url).toBe(
'https://elastic.co'
);
});

test.todo("Error when can't fetch drilldown list");

test("Error when can't save drilldown changes", async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,72 @@ export interface FlyoutDrilldownWizardProps<CurrentActionConfig extends object =
actionFactoryContext?: object;
}

function useWizardConfigState(
initialDrilldownWizardConfig?: DrilldownWizardConfig
): [
DrilldownWizardConfig,
{
setName: (name: string) => void;
setActionConfig: (actionConfig: object) => void;
setActionFactory: (actionFactory?: ActionFactory) => void;
}
] {
const [wizardConfig, setWizardConfig] = useState<DrilldownWizardConfig>(
() =>
initialDrilldownWizardConfig ?? {
name: '',
}
);
const [actionConfigCache, setActionConfigCache] = useState<Record<string, object>>(
initialDrilldownWizardConfig?.actionFactory
? {
[initialDrilldownWizardConfig.actionFactory
.id]: initialDrilldownWizardConfig.actionConfig!,
}
: {}
);

return [
wizardConfig,
{
setName: (name: string) => {
setWizardConfig({
...wizardConfig,
name,
});
},
setActionConfig: (actionConfig: object) => {
setWizardConfig({
...wizardConfig,
actionConfig,
});
},
setActionFactory: (actionFactory?: ActionFactory) => {
if (actionFactory) {
setWizardConfig({
...wizardConfig,
actionFactory,
actionConfig: actionConfigCache[actionFactory.id] ?? actionFactory.createConfig(),
});
} else {
if (wizardConfig.actionFactory?.id) {
setActionConfigCache({
...actionConfigCache,
[wizardConfig.actionFactory.id]: wizardConfig.actionConfig!,
});
}

setWizardConfig({
...wizardConfig,
actionFactory: undefined,
actionConfig: undefined,
});
}
},
},
];
}

export function FlyoutDrilldownWizard<CurrentActionConfig extends object = object>({
onClose,
onBack,
Expand All @@ -53,11 +119,8 @@ export function FlyoutDrilldownWizard<CurrentActionConfig extends object = objec
drilldownActionFactories,
actionFactoryContext,
}: FlyoutDrilldownWizardProps<CurrentActionConfig>) {
const [wizardConfig, setWizardConfig] = useState<DrilldownWizardConfig>(
() =>
initialDrilldownWizardConfig ?? {
name: '',
}
const [wizardConfig, { setActionFactory, setActionConfig, setName }] = useWizardConfigState(
initialDrilldownWizardConfig
);

const isActionValid = (
Expand Down Expand Up @@ -95,35 +158,11 @@ export function FlyoutDrilldownWizard<CurrentActionConfig extends object = objec
>
<FormDrilldownWizard
name={wizardConfig.name}
onNameChange={newName => {
setWizardConfig({
...wizardConfig,
name: newName,
});
}}
onNameChange={setName}
actionConfig={wizardConfig.actionConfig}
onActionConfigChange={newActionConfig => {
setWizardConfig({
...wizardConfig,
actionConfig: newActionConfig,
});
}}
onActionConfigChange={setActionConfig}
currentActionFactory={wizardConfig.actionFactory}
onActionFactoryChange={actionFactory => {
if (!actionFactory) {
setWizardConfig({
...wizardConfig,
actionFactory: undefined,
actionConfig: undefined,
});
} else {
setWizardConfig({
...wizardConfig,
actionFactory,
actionConfig: actionFactory.createConfig(),
});
}
}}
onActionFactoryChange={setActionFactory}
actionFactories={drilldownActionFactories}
actionFactoryContext={actionFactoryContext!}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export interface FormDrilldownWizardProps {
onNameChange?: (name: string) => void;

currentActionFactory?: ActionFactory;
onActionFactoryChange?: (actionFactory: ActionFactory | null) => void;
onActionFactoryChange?: (actionFactory?: ActionFactory) => void;
actionFactoryContext: object;

actionConfig?: object;
Expand Down

0 comments on commit 3604f5d

Please sign in to comment.