implemented feature

TODOs:
- extract logic to feature file to simplify component
- add unit test
- add end-to-end tests
This commit is contained in:
Chris Kruining 2024-12-02 16:26:00 +01:00
parent 316e3158db
commit 4e98849e07
No known key found for this signature in database
GPG key ID: EB894A3560CCCAD2
3 changed files with 101 additions and 20 deletions

View file

@ -19,6 +19,7 @@ export interface GridContextType {
mutate(prop: string, lang: string, value: string): void;
remove(props: string[]): void;
insert(prop: string): void;
addColumn(name: string): void;
}
export interface GridApi {
@ -29,6 +30,7 @@ export interface GridApi {
clear(): void;
remove(keys: string[]): void;
insert(prop: string): void;
addColumn(name: string): void;
}
const GridContext = createContext<GridContextType>();
@ -38,8 +40,9 @@ const useGrid = () => useContext(GridContext)!;
export const Grid: Component<{ class?: string, columns: string[], rows: Rows, api?: (api: GridApi) => any }> = (props) => {
const [selection, setSelection] = createSignal<SelectionItem[]>([]);
const [state, setState] = createStore<{ rows: Record<string, Record<string, string>>, snapshot: Rows, numberOfRows: number }>({
const [state, setState] = createStore<{ rows: Record<string, Record<string, string>>, columns: string[], snapshot: Rows, numberOfRows: number }>({
rows: {},
columns: [],
snapshot: new Map,
numberOfRows: 0,
});
@ -51,12 +54,17 @@ export const Grid: Component<{ class?: string, columns: string[], rows: Rows, ap
return deepDiff(state.snapshot, state.rows).toArray();
});
const rows = createMemo(() => Object.fromEntries(Object.entries(state.rows).map(([key, row]) => [key, unwrap(row)] as const)));
const columns = createMemo(() => state.columns);
createEffect(() => {
setState('rows', Object.fromEntries(deepCopy(props.rows).entries()));
setState('snapshot', props.rows);
});
createEffect(() => {
setState('columns', [...props.columns]);
});
createEffect(() => {
setState('numberOfRows', Object.keys(state.rows).length);
});
@ -82,18 +90,27 @@ export const Grid: Component<{ class?: string, columns: string[], rows: Rows, ap
insert(prop: string) {
setState('rows', produce(rows => {
rows[prop] = Object.fromEntries(props.columns.slice(1).map(lang => [lang, '']));
rows[prop] = Object.fromEntries(state.columns.slice(1).map(lang => [lang, '']));
return rows
}))
},
addColumn(name: string): void {
setState(produce(state => {
state.columns.push(name);
state.rows = Object.fromEntries(Object.entries(state.rows).map(([key, row]) => [key, { ...row, [name]: '' }]));
return state;
}))
},
};
return <GridContext.Provider value={ctx}>
<SelectionProvider selection={setSelection} multiSelect>
<Api api={props.api} />
<_Grid class={props.class} columns={props.columns} rows={rows()} />
<_Grid class={props.class} columns={columns()} rows={rows()} />
</SelectionProvider>
</GridContext.Provider>;
};
@ -154,6 +171,10 @@ const Api: Component<{ api: undefined | ((api: GridApi) => any) }> = (props) =>
insert(prop: string) {
gridContext.insert(prop);
},
addColumn(name: string): void {
gridContext.addColumn(name);
},
};
createEffect(() => {