Skip to content

Commit 5e1b797

Browse files
import submissions
1 parent 5067d6e commit 5e1b797

11 files changed

Lines changed: 111 additions & 87 deletions

File tree

packages/edit-form/features/form/Form.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { JsonForms } from '@jsonforms/react';
44
import schema from '../table/example-jsonschema.json';
55

66
import { useAppSelector, selectData, selectEditorState, useAppDispatch, setRowData } from 'state';
7+
import { selectJsonSchema } from 'project-state';
78

89
import {
910
materialRenderers,
@@ -12,6 +13,7 @@ import {
1213

1314

1415
export function Form() {
16+
const schema = useAppSelector(selectJsonSchema);
1517
const tableData = useAppSelector(selectData);
1618
// @ts-ignore
1719
const { selectedRows } = useAppSelector(selectEditorState);
@@ -21,12 +23,12 @@ export function Form() {
2123
const rowData = rowIndex !== null && tableData[rowIndex];
2224

2325
const onChange = useCallback( ({errors, data}: {errors: any[], data: any}) => {
24-
if(errors.length === 0) {
25-
dispatch(setRowData([rowIndex, data]));
26+
if(errors.length === 0 && rowIndex != null) {
27+
dispatch(setRowData({row: data, rowIndex}));
2628
}
2729
}, [dispatch, rowIndex]);
2830

29-
return (
31+
return !rowData ? <p>For editing, select exactly 1 row.</p> : (
3032
<JsonForms
3133
renderers={materialRenderers}
3234
cells={materialCells}

packages/edit-form/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"@mui/icons-material": "^5.14.0",
2424
"@mui/material": "^5.14.0",
2525
"@mui/x-date-pickers": "^6.10.0",
26+
"project-state": "workspace:*",
2627
"@types/react": "^18.2.20",
2728
"@types/react-dom": "^18.2.7",
2829
"react": "^18.2.0",

packages/edit-table/features/table/Table.tsx

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,63 +5,66 @@ import { MaterialReactTable, MRT_Cell } from 'material-react-table';
55
import * as _ from 'lodash'
66

77
import { useAppSelector, useAppDispatch } from 'state';
8-
import { selectData, setCellData, selectEditorState, setRowSelection, Person } from 'state';
8+
import { selectData, setCellData, selectEditorState, setRowSelection, Row } from 'state';
99

10-
import example_jsonSchema from './example-jsonschema.json';
10+
import { selectJsonSchema } from 'project-state';
1111
import { schema2columns } from './schema2columns';
1212

1313
export const Table = () => {
1414
const tableInstanceRef = useRef(null);
15-
//console.log(tableInstanceRef)
1615

1716
const tableData = useAppSelector(selectData);
1817
const tableState = useAppSelector(selectEditorState);
1918
const dispatch = useAppDispatch();
2019

20+
const jsonSchema = useAppSelector(selectJsonSchema);
2121
const columns = useMemo(
22-
() => schema2columns(example_jsonSchema),
23-
[],
22+
() => jsonSchema && schema2columns(jsonSchema),
23+
[jsonSchema],
2424
);
2525

26-
const handleSaveCell = (cell: MRT_Cell<Person>, value: any) => {
26+
const handleSaveCell = (cell: MRT_Cell<Row>, value: any) => {
2727
dispatch(setCellData([cell.row.index, cell.column.id, value]))
2828
};
2929

30-
return <MaterialReactTable
31-
tableInstanceRef={tableInstanceRef}
30+
console.log({tableData, tableState})
31+
return !columns ? <p>Loading Columns from Schema…</p> : (
32+
<MaterialReactTable
33+
tableInstanceRef={tableInstanceRef}
3234

33-
//@ts-ignore
34-
columns={columns}
35-
data={tableData}
36-
state={tableState}
35+
//@ts-ignore
36+
columns={columns}
37+
data={tableData}
38+
state={tableState}
3739

38-
enableColumnResizing
39-
enablePinning
40+
enableColumnResizing
41+
enablePinning
4042

41-
enableEditing
42-
editingMode="cell"
43-
muiTableBodyCellEditTextFieldProps={({ cell }) => ({
44-
onBlur: (event) => {
45-
//@ts-ignore
46-
handleSaveCell(cell, event.target.value);
47-
},
48-
})}
43+
enableEditing
44+
editingMode="cell"
45+
muiTableBodyCellEditTextFieldProps={({ cell }) => ({
46+
onBlur: (event) => {
47+
//@ts-ignore
48+
handleSaveCell(cell, event.target.value);
49+
},
50+
})}
4951

50-
muiTableBodyCellProps={({ table, column, cell }) => ({
51-
onMouseDown: (_event) => {
52-
dispatch(setRowSelection([cell.row.index]));
53-
},
54-
onClick: (_event) => {
55-
/** like handleDoubleClick of MRT_TableBodyCell **/
56-
table.setEditingCell(cell);
57-
queueMicrotask(() => {
58-
const textField = table.refs.editInputRefs.current[column.id];
59-
if (textField) {
60-
textField.focus();
61-
textField.select?.();
62-
}
63-
});
64-
}
65-
})}
66-
/>;
52+
muiTableBodyCellProps={({ table, column, cell }) => ({
53+
onMouseDown: (_event) => {
54+
dispatch(setRowSelection([cell.row.index]));
55+
},
56+
onClick: (_event) => {
57+
/** like handleDoubleClick of MRT_TableBodyCell **/
58+
table.setEditingCell(cell);
59+
queueMicrotask(() => {
60+
const textField = table.refs.editInputRefs.current[column.id];
61+
if (textField) {
62+
textField.focus();
63+
textField.select?.();
64+
}
65+
});
66+
}
67+
})}
68+
/>
69+
);
6770
};

packages/edit-table/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"@mui/x-date-pickers": "^6.10.0",
2828
"@types/react": "^18.2.20",
2929
"material-react-table": "^1.14.0",
30+
"project-state": "workspace:*",
3031
"state": "workspace:*"
3132
}
3233
}

packages/edit-timeline/features/timeline/TimelineExpl.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ import {
1111
Timeline as TimelineType,
1212
TimelineItem,
1313
TimelineOptions,
14+
TimelineOptionsItemCallbackFunction
1415
} from "vis-timeline/types";
1516
import { useAppSelector, useAppDispatch } from "state";
1617
import { AppDispatch } from "state";
17-
import { selectData, setCellData, setRowSelection } from "state";
18+
import { selectData, setCellData, setRowSelection, Row } from "state";
1819

1920
import mapping from "./example-mapping.json";
2021
import * as _ from "lodash";
@@ -31,7 +32,7 @@ interface Item extends TimelineItem {
3132
}
3233

3334
/** Calculate a timeline event from a row of table data **/
34-
function eventFromRow(row: any, index: number) {
35+
function eventFromRow(row: Row, index: number) {
3536
return {
3637
id: row.id,
3738
content: _.get(row, mapping.content),
@@ -99,8 +100,8 @@ export function TimelineExpl() {
99100
[tableData]
100101
);
101102

102-
const onMove = useCallback(
103-
(item: Item, callback: any) => handleMove(dispatch, item, callback),
103+
const onMove: TimelineOptionsItemCallbackFunction = useCallback(
104+
(item: TimelineItem, callback: any) => handleMove(dispatch, item as Item, callback),
104105
[dispatch]
105106
);
106107
const onSelect = useCallback(

packages/example/features/app/App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { Table } from 'edit-table';
1515
import { Form } from 'edit-form';
1616
import { tabs } from '../app/Tabs';
1717

18-
import { Wip } from 'import';
18+
import { Import } from 'import';
1919

2020
export interface AppProps {
2121
title?: string;
@@ -46,7 +46,7 @@ export const App = ({
4646
drawer={ <Form/> }
4747
tabs={ tabs }
4848
>
49-
<Wip/>
49+
<Import/>
5050
<Table/>
5151
</Layout>
5252
</SecuredYProvider>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { useEffect } from 'react';
2+
3+
import { useAppSelector, useAppDispatch, setRowData } from 'state';
4+
import { selectJsonSchema, selectCryptedData } from 'project-state';
5+
import { PGPProvider, decryptUsingContext } from 'pgp-provider';
6+
7+
export function DecryptAndImportLastNewSubmission() {
8+
const jsonSchema = useAppSelector(selectJsonSchema);
9+
const cryptedData = useAppSelector(selectCryptedData);
10+
11+
/** TODO: Delete decrypted dataset after import and loop over submissions **/
12+
13+
const { data, uuid, keyId, armoredPublicKey } = cryptedData[cryptedData.length-1] || {};
14+
const decrypted_str = decryptUsingContext(data);
15+
const decrypted = decrypted_str && JSON.parse(decrypted_str);
16+
17+
const dispatch = useAppDispatch();
18+
useEffect( () => {
19+
const row = { ...decrypted, id: uuid, uuid, keyId, armoredPublicKey }
20+
decrypted && dispatch(setRowData({row}));
21+
}, [decrypted]);
22+
23+
return <></>
24+
}
25+
26+
export function Import() {
27+
return <PGPProvider>
28+
<DecryptAndImportLastNewSubmission/>
29+
</PGPProvider>
30+
}

packages/import/features/Wip.tsx

Lines changed: 0 additions & 18 deletions
This file was deleted.

packages/import/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from "./features/Wip";
1+
export * from "./features/Import";

packages/state/features/slices/dataSlice.ts

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,37 @@
11
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
22
import { RootState } from "../state/store";
33
import * as _ from "lodash";
4-
import data from "../example/example-data.json";
54

6-
type Name = {
7-
firstName: string;
8-
lastName: string;
9-
};
10-
11-
export type Person = {
12-
name: Name;
13-
address: string;
14-
state: string;
15-
phoneNumber?: string;
16-
};
5+
export interface Row extends Object {
6+
id: string
7+
}
178

189
export interface DataState {
19-
data: Person[];
10+
data: Row[];
2011
}
2112

2213
const initialState: DataState = {
23-
data,
14+
data: [],
2415
};
2516

2617
export const dataSlice = createSlice({
2718
name: "data",
2819
initialState,
2920
reducers: {
30-
setTableData: (state, action: PayloadAction<Person[]>) => {
21+
setTableData: (state, action: PayloadAction<Row[]>) => {
3122
state.data = action.payload;
3223
},
33-
setRowData: (state, action: PayloadAction<any>) => {
34-
const [rowIndex, newValue] = action.payload;
35-
state.data[rowIndex] = newValue;
24+
setRowData: (state, action: PayloadAction<{row: Row, rowIndex?: number}>) => {
25+
/** `rowIndex` should be used as optional hint for better performance whenever possible **/
26+
const {row, rowIndex} = action.payload;
27+
28+
const checkedRowIndex = rowIndex && state.data[rowIndex].id == row.id ?
29+
rowIndex :
30+
rowIndex && console.error('setRowData failed because of non-matching id!');
31+
32+
const searchedRowIndex = state.data.findIndex(r => r.id == row.id);
33+
const nextRowIndex = state.data.length;
34+
state.data[checkedRowIndex || (searchedRowIndex != -1 ? searchedRowIndex : nextRowIndex)] = row;
3635
},
3736
setCellData: (state, action: PayloadAction<any>) => {
3837
const [rowIndex, columnId, newValue] = action.payload;
@@ -41,8 +40,7 @@ export const dataSlice = createSlice({
4140
},
4241
});
4342

44-
export const { setTableData, setRowData, setCellData } =
45-
dataSlice.actions;
43+
export const { setTableData, setRowData, setCellData } = dataSlice.actions;
4644

4745
export const selectData = (state: RootState) =>
4846
// @ts-ignore

0 commit comments

Comments
 (0)