Skip to content

Commit 3604f5d

Browse files
[Drilldowns] Preserve state when selecting different action factory (#65074)
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
1 parent 6ef45e1 commit 3604f5d

File tree

5 files changed

+112
-37
lines changed

5 files changed

+112
-37
lines changed

x-pack/plugins/advanced_ui_actions/public/components/action_wizard/action_wizard.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ export interface ActionWizardProps {
3232

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

3939
/**
4040
* current config for currently selected action factory
@@ -71,7 +71,7 @@ export const ActionWizard: React.FC<ActionWizardProps> = ({
7171
actionFactory={currentActionFactory}
7272
showDeselect={actionFactories.length > 1}
7373
onDeselect={() => {
74-
onActionFactoryChange(null);
74+
onActionFactoryChange(undefined);
7575
}}
7676
context={context}
7777
config={config}

x-pack/plugins/advanced_ui_actions/public/components/action_wizard/test_data.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ export function Demo({ actionFactories }: { actionFactories: Array<ActionFactory
167167
config?: ActionBaseConfig;
168168
}>({});
169169

170-
function changeActionFactory(newActionFactory: ActionFactory | null) {
170+
function changeActionFactory(newActionFactory?: ActionFactory) {
171171
if (!newActionFactory) {
172172
// removing action factory
173173
return setState({});

x-pack/plugins/drilldowns/public/components/connected_flyout_manage_drilldowns/connected_flyout_manage_drilldowns.test.tsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,42 @@ test('Create only mode', async () => {
173173
expect(await mockDynamicActionManager.state.get().events.length).toBe(1);
174174
});
175175

176+
test('After switching between action factories state is restored', async () => {
177+
const screen = render(
178+
<FlyoutManageDrilldowns
179+
placeContext={{}}
180+
dynamicActionManager={mockDynamicActionManager}
181+
viewMode={'create'}
182+
/>
183+
);
184+
// wait for initial render. It is async because resolving compatible action factories is async
185+
await wait(() => expect(screen.getAllByText(/Create/i).length).toBeGreaterThan(0));
186+
fireEvent.change(screen.getByLabelText(/name/i), {
187+
target: { value: 'test' },
188+
});
189+
fireEvent.click(screen.getByText(/Go to URL/i));
190+
fireEvent.change(screen.getByLabelText(/url/i), {
191+
target: { value: 'https://elastic.co' },
192+
});
193+
194+
// change to dashboard
195+
fireEvent.click(screen.getByText(/change/i));
196+
fireEvent.click(screen.getByText(/Go to Dashboard/i));
197+
198+
// change back to url
199+
fireEvent.click(screen.getByText(/change/i));
200+
fireEvent.click(screen.getByText(/Go to URL/i));
201+
202+
expect(screen.getByLabelText(/url/i)).toHaveValue('https://elastic.co');
203+
expect(screen.getByLabelText(/name/i)).toHaveValue('test');
204+
205+
fireEvent.click(screen.getAllByText(/Create Drilldown/i)[1]);
206+
await wait(() => expect(notifications.toasts.addSuccess).toBeCalled());
207+
expect(await (mockDynamicActionManager.state.get().events[0].action.config as any).url).toBe(
208+
'https://elastic.co'
209+
);
210+
});
211+
176212
test.todo("Error when can't fetch drilldown list");
177213

178214
test("Error when can't save drilldown changes", async () => {

x-pack/plugins/drilldowns/public/components/flyout_drilldown_wizard/flyout_drilldown_wizard.tsx

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,72 @@ export interface FlyoutDrilldownWizardProps<CurrentActionConfig extends object =
4141
actionFactoryContext?: object;
4242
}
4343

44+
function useWizardConfigState(
45+
initialDrilldownWizardConfig?: DrilldownWizardConfig
46+
): [
47+
DrilldownWizardConfig,
48+
{
49+
setName: (name: string) => void;
50+
setActionConfig: (actionConfig: object) => void;
51+
setActionFactory: (actionFactory?: ActionFactory) => void;
52+
}
53+
] {
54+
const [wizardConfig, setWizardConfig] = useState<DrilldownWizardConfig>(
55+
() =>
56+
initialDrilldownWizardConfig ?? {
57+
name: '',
58+
}
59+
);
60+
const [actionConfigCache, setActionConfigCache] = useState<Record<string, object>>(
61+
initialDrilldownWizardConfig?.actionFactory
62+
? {
63+
[initialDrilldownWizardConfig.actionFactory
64+
.id]: initialDrilldownWizardConfig.actionConfig!,
65+
}
66+
: {}
67+
);
68+
69+
return [
70+
wizardConfig,
71+
{
72+
setName: (name: string) => {
73+
setWizardConfig({
74+
...wizardConfig,
75+
name,
76+
});
77+
},
78+
setActionConfig: (actionConfig: object) => {
79+
setWizardConfig({
80+
...wizardConfig,
81+
actionConfig,
82+
});
83+
},
84+
setActionFactory: (actionFactory?: ActionFactory) => {
85+
if (actionFactory) {
86+
setWizardConfig({
87+
...wizardConfig,
88+
actionFactory,
89+
actionConfig: actionConfigCache[actionFactory.id] ?? actionFactory.createConfig(),
90+
});
91+
} else {
92+
if (wizardConfig.actionFactory?.id) {
93+
setActionConfigCache({
94+
...actionConfigCache,
95+
[wizardConfig.actionFactory.id]: wizardConfig.actionConfig!,
96+
});
97+
}
98+
99+
setWizardConfig({
100+
...wizardConfig,
101+
actionFactory: undefined,
102+
actionConfig: undefined,
103+
});
104+
}
105+
},
106+
},
107+
];
108+
}
109+
44110
export function FlyoutDrilldownWizard<CurrentActionConfig extends object = object>({
45111
onClose,
46112
onBack,
@@ -53,11 +119,8 @@ export function FlyoutDrilldownWizard<CurrentActionConfig extends object = objec
53119
drilldownActionFactories,
54120
actionFactoryContext,
55121
}: FlyoutDrilldownWizardProps<CurrentActionConfig>) {
56-
const [wizardConfig, setWizardConfig] = useState<DrilldownWizardConfig>(
57-
() =>
58-
initialDrilldownWizardConfig ?? {
59-
name: '',
60-
}
122+
const [wizardConfig, { setActionFactory, setActionConfig, setName }] = useWizardConfigState(
123+
initialDrilldownWizardConfig
61124
);
62125

63126
const isActionValid = (
@@ -95,35 +158,11 @@ export function FlyoutDrilldownWizard<CurrentActionConfig extends object = objec
95158
>
96159
<FormDrilldownWizard
97160
name={wizardConfig.name}
98-
onNameChange={newName => {
99-
setWizardConfig({
100-
...wizardConfig,
101-
name: newName,
102-
});
103-
}}
161+
onNameChange={setName}
104162
actionConfig={wizardConfig.actionConfig}
105-
onActionConfigChange={newActionConfig => {
106-
setWizardConfig({
107-
...wizardConfig,
108-
actionConfig: newActionConfig,
109-
});
110-
}}
163+
onActionConfigChange={setActionConfig}
111164
currentActionFactory={wizardConfig.actionFactory}
112-
onActionFactoryChange={actionFactory => {
113-
if (!actionFactory) {
114-
setWizardConfig({
115-
...wizardConfig,
116-
actionFactory: undefined,
117-
actionConfig: undefined,
118-
});
119-
} else {
120-
setWizardConfig({
121-
...wizardConfig,
122-
actionFactory,
123-
actionConfig: actionFactory.createConfig(),
124-
});
125-
}
126-
}}
165+
onActionFactoryChange={setActionFactory}
127166
actionFactories={drilldownActionFactories}
128167
actionFactoryContext={actionFactoryContext!}
129168
/>

x-pack/plugins/drilldowns/public/components/form_drilldown_wizard/form_drilldown_wizard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export interface FormDrilldownWizardProps {
1919
onNameChange?: (name: string) => void;
2020

2121
currentActionFactory?: ActionFactory;
22-
onActionFactoryChange?: (actionFactory: ActionFactory | null) => void;
22+
onActionFactoryChange?: (actionFactory?: ActionFactory) => void;
2323
actionFactoryContext: object;
2424

2525
actionConfig?: object;

0 commit comments

Comments
 (0)