Skip to content

Commit

Permalink
[App Search] Refactor out a shared MultiInputRows component (elastic#…
Browse files Browse the repository at this point in the history
…96881)

* Add new reusable MultiInputRows component

- basically the CurationQuery component, but with a generic values var & allows passing in custom text for every string

* Update CurationQueries with MultiInputRows

* Update MultiInputRows to support on change behavior

- for upcoming Relevance Tuning usage

* Update Relevance Tuning value boost form to use new component

- relevance_tuning_form.test.tsx fix: was getting test errors with mount(), so I switched to shallow()

* Change submitOnChange to onChange fn

- more flexible - allows for either an onSubmit or onChange, or even potentially both

* Convert MultiInputRowsLogic to keyed Kea logic

- so that we can have multiple instances on the same page - primarily the value boosts use case

* Update LogicMounter helper & tests to handle keyed logic w/ props

* [Misc] LogicMounter helper - fix typing, perf

- Use Kea's types instead of trying to rewrite my own LogicFile
- Add an early return for tests that pass `{}` to values as well for performance

* PR feedback: Change values prop to initialValues

+ bonus - add a fallback for initially empty components
+ add a test to check that the logic was mounted correctly

* PR feedback: Remove useRef/on mount onChange catch for now

- We don't currently need the extra catch for any live components, and it's confusing
  • Loading branch information
Constance authored and kibanamachine committed Apr 14, 2021
1 parent 5ba7fc1 commit 57989a6
Show file tree
Hide file tree
Showing 28 changed files with 559 additions and 683 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,10 @@ export const setMockActions = (actions: object) => {
* unmount();
* });
*/
import { resetContext, Logic, LogicInput } from 'kea';
import { resetContext, LogicWrapper } from 'kea';

type LogicFile = LogicWrapper<any>;

interface LogicFile {
inputs: Array<LogicInput<Logic>>;
build(props?: object): void;
mount(): Function;
}
export class LogicMounter {
private logicFile: LogicFile;
private unmountFn!: Function;
Expand All @@ -100,24 +97,39 @@ export class LogicMounter {
}

// Reset context with optional default value overrides
public resetContext = (values?: object) => {
if (!values) {
public resetContext = (values?: object, props?: object) => {
if (!values || !Object.keys(values).length) {
resetContext({});
} else {
const path = this.logicFile.inputs[0].path as string[]; // example: ['x', 'y', 'z']
const defaults = path.reduceRight((value: object, key: string) => ({ [key]: value }), values); // example: { x: { y: { z: values } } }
let { path, key } = this.logicFile.inputs[0];

// For keyed logic files, both key and path should be functions
if (this.logicFile._isKeaWithKey) {
key = key(props);
path = path(key);
}

// Generate the correct nested defaults obj based on the file path
// example path: ['x', 'y', 'z']
// example defaults: { x: { y: { z: values } } }
const defaults = path.reduceRight(
(value: object, name: string) => ({ [name]: value }),
values
);
resetContext({ defaults });
}
};

// Automatically reset context & mount the logic file
public mount = (values?: object, props?: object) => {
this.resetContext(values);
if (props) this.logicFile.build(props);
this.resetContext(values, props);

const logicWithProps = this.logicFile.build(props);
this.unmountFn = logicWithProps.mount();

const unmount = this.logicFile.mount();
this.unmountFn = unmount;
return unmount; // Keep Kea behavior of returning an unmount fn from mount
return logicWithProps;
// NOTE: Unlike kea's mount(), this returns the current
// built logic instance with props, NOT the unmount fn
};

// Also add unmount as a class method that can be destructured on init without becoming stale later
Expand Down Expand Up @@ -146,7 +158,7 @@ export class LogicMounter {
const { listeners } = this.logicFile.inputs[0];

return typeof listeners === 'function'
? (listeners as Function)(listenersArgs) // e.g., listeners({ values, actions, props }) => ({ ... })
? listeners(listenersArgs) // e.g., listeners({ values, actions, props }) => ({ ... })
: listeners; // handles simpler logic files that just define listeners: { ... }
};
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 57989a6

Please sign in to comment.