antd-crud-table 0.4.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +293 -783
- package/dist/CrudTable-Btf58zof.js +610 -0
- package/dist/CrudTable-DRN70sET.cjs +1 -0
- package/dist/CrudTable.cjs +1 -1
- package/dist/CrudTable.d.ts +85 -18
- package/dist/CrudTable.js +3 -306
- package/dist/CrudTableLazy.cjs +1 -1
- package/dist/CrudTableLazy.d.ts +4 -3
- package/dist/CrudTableLazy.js +8 -7
- package/dist/core/CustomDataSource.d.ts +35 -0
- package/dist/core/InMemoryDataSource.d.ts +30 -0
- package/dist/core/LocalStorageDataSource.d.ts +30 -0
- package/dist/core/RestDataSource.d.ts +120 -0
- package/dist/core/StaticDataSource.d.ts +20 -0
- package/dist/core/identity.d.ts +28 -0
- package/dist/core/inMemoryQuery.d.ts +26 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/types.d.ts +86 -0
- package/dist/en_US-D3Kl6g3n.cjs +1 -0
- package/dist/en_US-DGCMDOdX.js +41 -0
- package/dist/exportData.cjs +13 -13
- package/dist/exportData.js +48 -39
- package/dist/fields/registry.d.ts +38 -0
- package/dist/fields/types.d.ts +29 -0
- package/dist/hooks/useCrudTable.d.ts +114 -57
- package/dist/hooks/useLocalStorageCrud.d.ts +14 -9
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +14 -6
- package/dist/index.js +7 -0
- package/dist/locale/en_US.d.ts +10 -0
- package/dist/locale/index.d.ts +4 -0
- package/dist/locale/types.d.ts +89 -0
- package/dist/locale/useResolvedLocale.d.ts +35 -0
- package/dist/useCrudTable-40jpmCkr.cjs +1 -0
- package/dist/useCrudTable-DxjnXVlQ.js +460 -0
- package/dist/useCrudTable.cjs +1 -1
- package/dist/useCrudTable.js +2 -235
- package/dist/useLocalStorageCrud.cjs +1 -1
- package/dist/useLocalStorageCrud.js +12 -198
- package/dist/utils/exportData.d.ts +37 -12
- package/package.json +52 -16
package/dist/CrudTable.d.ts
CHANGED
|
@@ -1,34 +1,101 @@
|
|
|
1
1
|
import { ProColumns } from '@ant-design/pro-components';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import { FormRule } from 'antd';
|
|
3
|
+
import { CrudTableActions, UseCrudTableOptions } from './hooks/useCrudTable';
|
|
4
|
+
import { FieldType } from './fields/registry';
|
|
5
|
+
import { EnumOption } from './fields/types';
|
|
6
|
+
import { PartialCrudTableLocale } from './locale/types';
|
|
7
|
+
/**
|
|
8
|
+
* A column bound to one property of `T`.
|
|
9
|
+
*
|
|
10
|
+
* `K` ties `dataIndex` to a real key, so `customRender` and `transform`
|
|
11
|
+
* receive that property's type rather than a widened one.
|
|
12
|
+
*/
|
|
13
|
+
export interface CrudColumnFor<T, K extends keyof T> extends Omit<ProColumns<T>, 'dataIndex' | 'title' | 'render'> {
|
|
14
|
+
/** The record property this column reads. */
|
|
15
|
+
dataIndex: K;
|
|
16
|
+
/** Also used as the form label, so a plain string rather than a ReactNode. */
|
|
17
|
+
title: string;
|
|
18
|
+
/** Which registry entry renders and edits this column. Defaults to `string`. */
|
|
6
19
|
fieldType?: FieldType;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
20
|
+
/** Selectable values, for `enum` columns. */
|
|
21
|
+
enumOptions?: Record<string, EnumOption>;
|
|
22
|
+
/** Cell renderer for `custom` columns, receiving this property's type. */
|
|
23
|
+
customRender?: (value: T[K], record: T) => React.ReactNode;
|
|
24
|
+
/** How this column behaves in the create/edit form. */
|
|
12
25
|
formConfig?: {
|
|
26
|
+
/** Adds a required rule, unless `rules` is given instead. */
|
|
13
27
|
required?: boolean;
|
|
28
|
+
/** Replaces the registry's control entirely. */
|
|
14
29
|
component?: React.ReactNode;
|
|
15
|
-
|
|
16
|
-
|
|
30
|
+
/** Applied to the submitted value before it reaches the data source. */
|
|
31
|
+
transform?: (value: T[K]) => T[K];
|
|
32
|
+
/** antd validation rules. Replaces `required` when both are present. */
|
|
33
|
+
rules?: FormRule[];
|
|
17
34
|
};
|
|
35
|
+
/** Editable in the create/edit form. Defaults to true. */
|
|
18
36
|
fieldEditable?: boolean;
|
|
37
|
+
/** Exposed in the search form. Defaults to true. */
|
|
19
38
|
searchable?: boolean;
|
|
20
39
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
40
|
+
/**
|
|
41
|
+
* A column for any one key of `T` - the type an array of columns holds.
|
|
42
|
+
*
|
|
43
|
+
* Distributing over `keyof T` is what keeps each column's callbacks bound to
|
|
44
|
+
* its own property type. A single `CrudColumnFor<T, keyof T>` would widen
|
|
45
|
+
* `customRender` and `transform` to accept a union of every property type,
|
|
46
|
+
* losing exactly the precision this exists for.
|
|
47
|
+
*/
|
|
48
|
+
export type CrudColumn<T> = {
|
|
49
|
+
[K in keyof T]-?: CrudColumnFor<T, K>;
|
|
50
|
+
}[keyof T];
|
|
51
|
+
/** Everything needed to render a {@link CrudTable}. */
|
|
52
|
+
export interface CrudTableConfig<T extends object, K extends keyof T> {
|
|
53
|
+
/** Column definitions, each bound to a property of `T`. */
|
|
54
|
+
columns: readonly CrudColumn<T>[];
|
|
55
|
+
/** The property holding each record's identity. */
|
|
56
|
+
rowKey: K;
|
|
57
|
+
/** Table header, also used to name exported files. */
|
|
24
58
|
title: string;
|
|
59
|
+
/** Rows per page. Defaults to 10. */
|
|
25
60
|
defaultPageSize?: number;
|
|
26
|
-
|
|
61
|
+
/** Selects and configures the data strategy. */
|
|
62
|
+
hookConfig: UseCrudTableOptions<T, K>;
|
|
63
|
+
/** Show row selection and the bulk delete control. Defaults to false. */
|
|
27
64
|
enableBulkOperations?: boolean;
|
|
65
|
+
/** Show ProTable's column visibility and density controls. Defaults to true. */
|
|
28
66
|
enableColumnSettings?: boolean;
|
|
67
|
+
/** Show the export entries in the toolbar menu. Defaults to true. */
|
|
29
68
|
enableExport?: boolean;
|
|
30
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Whether export covers the whole filtered result set or just the rows on
|
|
71
|
+
* screen. Defaults to `'all'`, falling back to `'page'` when the data source
|
|
72
|
+
* cannot list without pagination.
|
|
73
|
+
*/
|
|
74
|
+
exportScope?: 'all' | 'page';
|
|
75
|
+
/** Extra per-row controls, appended after Edit and Delete. */
|
|
76
|
+
customActions?: (record: T, actions: CrudTableActions<T, K>) => React.ReactNode[];
|
|
77
|
+
/**
|
|
78
|
+
* Overrides for the library's own wording.
|
|
79
|
+
*
|
|
80
|
+
* antd and ProTable chrome follow the surrounding `ConfigProvider`; this is
|
|
81
|
+
* for the strings the library itself produces. Anything omitted falls back
|
|
82
|
+
* to English.
|
|
83
|
+
*/
|
|
84
|
+
locale?: PartialCrudTableLocale;
|
|
31
85
|
}
|
|
32
|
-
|
|
86
|
+
/**
|
|
87
|
+
* A paginated, searchable table with a create/edit form and CRUD wired through
|
|
88
|
+
* a {@link CrudDataSource}.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```tsx
|
|
92
|
+
* <CrudTable<User, 'id'>
|
|
93
|
+
* title="Users"
|
|
94
|
+
* rowKey="id"
|
|
95
|
+
* columns={[{ dataIndex: 'name', title: 'Name', fieldType: 'string' }]}
|
|
96
|
+
* hookConfig={{ staticData: users }}
|
|
97
|
+
* />
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
declare const CrudTable: <T extends object, K extends keyof T>(config: CrudTableConfig<T, K>) => import("react").JSX.Element;
|
|
33
101
|
export default CrudTable;
|
|
34
|
-
export type { CrudTableConfig, CrudColumn, DataType };
|
package/dist/CrudTable.js
CHANGED
|
@@ -1,306 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
import { Button as o, DatePicker as s, Dropdown as c, Form as l, Input as u, InputNumber as d, Modal as f, Select as p, Switch as m, Tag as h, message as g } from "antd";
|
|
5
|
-
import { useEffect as _, useState as v } from "react";
|
|
6
|
-
import { format as y, formatISO as b, parseISO as x } from "date-fns";
|
|
7
|
-
import S from "dayjs";
|
|
8
|
-
import { jsx as C, jsxs as w } from "react/jsx-runtime";
|
|
9
|
-
//#region lib/CrudTable.tsx
|
|
10
|
-
var T = (T) => {
|
|
11
|
-
let { columns: E, rowKey: D, title: O, defaultPageSize: k = 10, hookConfig: A, enableBulkOperations: j = !1, customActions: M } = T, N = e(D, {
|
|
12
|
-
defaultPageSize: k,
|
|
13
|
-
...A
|
|
14
|
-
}), [P, F] = v(!1), [I, L] = v(null), [R, z] = v([]), [B] = l.useForm();
|
|
15
|
-
_(() => {
|
|
16
|
-
N.refresh();
|
|
17
|
-
}, []);
|
|
18
|
-
let V = E.map((e) => {
|
|
19
|
-
let t = {
|
|
20
|
-
...e,
|
|
21
|
-
dataIndex: e.dataIndex,
|
|
22
|
-
title: e.title,
|
|
23
|
-
search: e.searchable !== !1
|
|
24
|
-
};
|
|
25
|
-
switch (e.fieldType) {
|
|
26
|
-
case "date": return {
|
|
27
|
-
...t,
|
|
28
|
-
valueType: "dateTime",
|
|
29
|
-
render: (t, n) => {
|
|
30
|
-
let r = n[e.dataIndex];
|
|
31
|
-
if (!r) return "-";
|
|
32
|
-
try {
|
|
33
|
-
return /* @__PURE__ */ C("span", { children: y(x(r), "yyyy-MM-dd HH:mm") });
|
|
34
|
-
} catch {
|
|
35
|
-
return /* @__PURE__ */ C("span", { children: r });
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
case "enum": return {
|
|
40
|
-
...t,
|
|
41
|
-
valueType: "select",
|
|
42
|
-
valueEnum: e.enumOptions,
|
|
43
|
-
render: (t, n) => {
|
|
44
|
-
let r = n[e.dataIndex], i = e.enumOptions?.[r];
|
|
45
|
-
return i ? /* @__PURE__ */ C(h, {
|
|
46
|
-
color: i.color,
|
|
47
|
-
children: i.text
|
|
48
|
-
}) : r;
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
case "number": return {
|
|
52
|
-
...t,
|
|
53
|
-
valueType: "digit",
|
|
54
|
-
render: (t, n) => {
|
|
55
|
-
let r = n[e.dataIndex];
|
|
56
|
-
return typeof r == "number" ? r.toLocaleString() : r;
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
case "boolean": return {
|
|
60
|
-
...t,
|
|
61
|
-
valueType: "switch",
|
|
62
|
-
render: (t, n) => /* @__PURE__ */ C(h, {
|
|
63
|
-
color: n[e.dataIndex] ? "green" : "red",
|
|
64
|
-
children: n[e.dataIndex] ? "Yes" : "No"
|
|
65
|
-
})
|
|
66
|
-
};
|
|
67
|
-
case "custom": return {
|
|
68
|
-
...t,
|
|
69
|
-
render: (t, n) => e.customRender?.(n[e.dataIndex], n)
|
|
70
|
-
};
|
|
71
|
-
default: return t;
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
V.push({
|
|
75
|
-
title: "Actions",
|
|
76
|
-
valueType: "option",
|
|
77
|
-
width: 200,
|
|
78
|
-
render: (e, t) => {
|
|
79
|
-
let n = [/* @__PURE__ */ C(o, {
|
|
80
|
-
type: "link",
|
|
81
|
-
size: "small",
|
|
82
|
-
onClick: () => U(t),
|
|
83
|
-
children: "Edit"
|
|
84
|
-
}, "edit"), /* @__PURE__ */ C(o, {
|
|
85
|
-
type: "link",
|
|
86
|
-
size: "small",
|
|
87
|
-
danger: !0,
|
|
88
|
-
onClick: () => G(t[D]),
|
|
89
|
-
children: "Delete"
|
|
90
|
-
}, "delete")], r = M?.(t, N) || [];
|
|
91
|
-
return [...n, ...r];
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
let H = async (e, t, n) => {
|
|
95
|
-
try {
|
|
96
|
-
let r = {
|
|
97
|
-
current: e.current,
|
|
98
|
-
pageSize: e.pageSize,
|
|
99
|
-
sortBy: Object.keys(t)[0],
|
|
100
|
-
sortOrder: Object.values(t)[0],
|
|
101
|
-
...n,
|
|
102
|
-
...e
|
|
103
|
-
}, i = N.operations;
|
|
104
|
-
if (i?.getList) {
|
|
105
|
-
let e = await i.getList(r);
|
|
106
|
-
return {
|
|
107
|
-
data: e.data,
|
|
108
|
-
success: !0,
|
|
109
|
-
total: e.total
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
return {
|
|
113
|
-
data: N.state.data,
|
|
114
|
-
success: !0,
|
|
115
|
-
total: N.state.total
|
|
116
|
-
};
|
|
117
|
-
} catch {
|
|
118
|
-
return g.error("Failed to fetch data"), {
|
|
119
|
-
data: [],
|
|
120
|
-
success: !1,
|
|
121
|
-
total: 0
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
}, U = (e) => {
|
|
125
|
-
if (L(e || null), e) {
|
|
126
|
-
let t = { ...e };
|
|
127
|
-
E.forEach((e) => {
|
|
128
|
-
let n = e.dataIndex;
|
|
129
|
-
if (e.fieldType === "date" && t[n]) try {
|
|
130
|
-
t[n] = S(t[n]);
|
|
131
|
-
} catch {}
|
|
132
|
-
}), B.setFieldsValue(t);
|
|
133
|
-
} else B.resetFields();
|
|
134
|
-
F(!0);
|
|
135
|
-
}, W = async () => {
|
|
136
|
-
try {
|
|
137
|
-
let e = await B.validateFields(), t = { ...e };
|
|
138
|
-
E.forEach((n) => {
|
|
139
|
-
let r = n.dataIndex;
|
|
140
|
-
if (n.fieldType === "date" && e[r]) try {
|
|
141
|
-
t[r] = b(e[r]);
|
|
142
|
-
} catch {}
|
|
143
|
-
n.formConfig?.transform && (t[r] = n.formConfig.transform(e[r]));
|
|
144
|
-
}), I && I[D] ? await N.update(I[D], t) : await N.create(t), F(!1), N.actionRef.current?.reload();
|
|
145
|
-
} catch (e) {
|
|
146
|
-
console.error("Form validation failed:", e);
|
|
147
|
-
}
|
|
148
|
-
}, G = async (e) => {
|
|
149
|
-
f.confirm({
|
|
150
|
-
title: "Are you sure?",
|
|
151
|
-
content: "This action cannot be undone.",
|
|
152
|
-
okText: "Yes, Delete",
|
|
153
|
-
okType: "danger",
|
|
154
|
-
cancelText: "Cancel",
|
|
155
|
-
onOk: async () => {
|
|
156
|
-
await N.delete(e) && N.actionRef.current?.reload();
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
}, K = async () => {
|
|
160
|
-
if (R.length === 0) {
|
|
161
|
-
g.warning("Please select items to delete");
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
f.confirm({
|
|
165
|
-
title: `Delete ${R.length} items?`,
|
|
166
|
-
content: "This action cannot be undone.",
|
|
167
|
-
okText: "Yes, Delete All",
|
|
168
|
-
okType: "danger",
|
|
169
|
-
cancelText: "Cancel",
|
|
170
|
-
onOk: async () => {
|
|
171
|
-
let e = R.map((e) => N.delete(e));
|
|
172
|
-
await Promise.allSettled(e), z([]), N.actionRef.current?.reload();
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
}, q = j ? {
|
|
176
|
-
selectedRowKeys: R,
|
|
177
|
-
onChange: z
|
|
178
|
-
} : void 0;
|
|
179
|
-
return /* @__PURE__ */ w(r, {
|
|
180
|
-
needDeps: !0,
|
|
181
|
-
intl: a,
|
|
182
|
-
children: [/* @__PURE__ */ C(i, {
|
|
183
|
-
headerTitle: O,
|
|
184
|
-
rowKey: D,
|
|
185
|
-
rowClassName: (e, t) => t % 2 == 0 ? "row-differentiator" : "",
|
|
186
|
-
actionRef: N.actionRef,
|
|
187
|
-
columns: V,
|
|
188
|
-
request: H,
|
|
189
|
-
search: { labelWidth: "auto" },
|
|
190
|
-
pagination: {
|
|
191
|
-
pageSize: k,
|
|
192
|
-
showSizeChanger: !0,
|
|
193
|
-
showQuickJumper: !0
|
|
194
|
-
},
|
|
195
|
-
loading: N.state.loading,
|
|
196
|
-
rowSelection: q,
|
|
197
|
-
toolBarRender: () => [
|
|
198
|
-
/* @__PURE__ */ C(o, {
|
|
199
|
-
type: "primary",
|
|
200
|
-
icon: /* @__PURE__ */ C(n, {}),
|
|
201
|
-
onClick: () => U(),
|
|
202
|
-
children: "New"
|
|
203
|
-
}, "add"),
|
|
204
|
-
...j && R.length > 0 ? [/* @__PURE__ */ w(o, {
|
|
205
|
-
danger: !0,
|
|
206
|
-
onClick: K,
|
|
207
|
-
children: [
|
|
208
|
-
"Delete Selected (",
|
|
209
|
-
R.length,
|
|
210
|
-
")"
|
|
211
|
-
]
|
|
212
|
-
}, "bulk-delete")] : [],
|
|
213
|
-
/* @__PURE__ */ C(c, {
|
|
214
|
-
menu: { items: [{
|
|
215
|
-
key: "export",
|
|
216
|
-
label: "Export",
|
|
217
|
-
disabled: !0
|
|
218
|
-
}, {
|
|
219
|
-
key: "refresh",
|
|
220
|
-
label: "Refresh",
|
|
221
|
-
onClick: () => N.refresh()
|
|
222
|
-
}] },
|
|
223
|
-
children: /* @__PURE__ */ C(o, { children: /* @__PURE__ */ C(t, {}) })
|
|
224
|
-
}, "menu")
|
|
225
|
-
],
|
|
226
|
-
options: {
|
|
227
|
-
setting: { listsHeight: 400 },
|
|
228
|
-
reload: () => N.refresh()
|
|
229
|
-
},
|
|
230
|
-
dateFormatter: "string"
|
|
231
|
-
}), /* @__PURE__ */ C(f, {
|
|
232
|
-
title: I ? "Edit Item" : "Create Item",
|
|
233
|
-
open: P,
|
|
234
|
-
onOk: W,
|
|
235
|
-
onCancel: () => F(!1),
|
|
236
|
-
destroyOnClose: !0,
|
|
237
|
-
width: 600,
|
|
238
|
-
children: /* @__PURE__ */ C(l, {
|
|
239
|
-
form: B,
|
|
240
|
-
layout: "vertical",
|
|
241
|
-
children: E.map((e) => {
|
|
242
|
-
if (!e.dataIndex) return null;
|
|
243
|
-
let t = e.dataIndex, n = e.title, r = !(e.fieldEditable ?? !0), i = e.formConfig?.rules || (e.formConfig?.required ? [{
|
|
244
|
-
required: !0,
|
|
245
|
-
message: `${n} is required`
|
|
246
|
-
}] : []);
|
|
247
|
-
if (e.formConfig?.component) return /* @__PURE__ */ C(l.Item, {
|
|
248
|
-
name: t,
|
|
249
|
-
label: n,
|
|
250
|
-
rules: i,
|
|
251
|
-
children: e.formConfig.component
|
|
252
|
-
}, t);
|
|
253
|
-
switch (e.fieldType) {
|
|
254
|
-
case "string": return /* @__PURE__ */ C(l.Item, {
|
|
255
|
-
name: t,
|
|
256
|
-
label: n,
|
|
257
|
-
rules: i,
|
|
258
|
-
children: /* @__PURE__ */ C(u, { disabled: r })
|
|
259
|
-
}, t);
|
|
260
|
-
case "number": return /* @__PURE__ */ C(l.Item, {
|
|
261
|
-
name: t,
|
|
262
|
-
label: n,
|
|
263
|
-
rules: i,
|
|
264
|
-
children: /* @__PURE__ */ C(d, {
|
|
265
|
-
style: { width: "100%" },
|
|
266
|
-
disabled: r
|
|
267
|
-
})
|
|
268
|
-
}, t);
|
|
269
|
-
case "date": return /* @__PURE__ */ C(l.Item, {
|
|
270
|
-
name: t,
|
|
271
|
-
label: n,
|
|
272
|
-
rules: i,
|
|
273
|
-
children: /* @__PURE__ */ C(s, {
|
|
274
|
-
style: { width: "100%" },
|
|
275
|
-
showTime: !0,
|
|
276
|
-
disabled: r
|
|
277
|
-
})
|
|
278
|
-
}, t);
|
|
279
|
-
case "boolean": return /* @__PURE__ */ C(l.Item, {
|
|
280
|
-
name: t,
|
|
281
|
-
label: n,
|
|
282
|
-
valuePropName: "checked",
|
|
283
|
-
children: /* @__PURE__ */ C(m, { disabled: r })
|
|
284
|
-
}, t);
|
|
285
|
-
case "enum": return /* @__PURE__ */ C(l.Item, {
|
|
286
|
-
name: t,
|
|
287
|
-
label: n,
|
|
288
|
-
rules: i,
|
|
289
|
-
children: /* @__PURE__ */ C(p, {
|
|
290
|
-
disabled: r,
|
|
291
|
-
placeholder: `Select ${n.toLowerCase()}`,
|
|
292
|
-
options: Object.entries(e.enumOptions || {}).map(([e, t]) => ({
|
|
293
|
-
label: t.text,
|
|
294
|
-
value: e
|
|
295
|
-
}))
|
|
296
|
-
})
|
|
297
|
-
}, t);
|
|
298
|
-
default: return null;
|
|
299
|
-
}
|
|
300
|
-
})
|
|
301
|
-
})
|
|
302
|
-
})]
|
|
303
|
-
});
|
|
304
|
-
};
|
|
305
|
-
//#endregion
|
|
306
|
-
export { T as default };
|
|
1
|
+
import { t as e } from "./CrudTable-Btf58zof.js";
|
|
2
|
+
import "./exportData.js";
|
|
3
|
+
export { e as default };
|
package/dist/CrudTableLazy.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
require(
|
|
1
|
+
Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});const e=require("./en_US-D3Kl6g3n.cjs");let t=require("react"),n=require("react/jsx-runtime");var r=(0,t.lazy)(()=>Promise.resolve().then(()=>require("./CrudTable.cjs"))),i=i=>(0,n.jsx)(t.Suspense,{fallback:(0,n.jsx)(`div`,{style:{textAlign:`center`,padding:`2rem`},children:i.locale?.loading??e.t.loading}),children:(0,n.jsx)(r,{...i})});exports.default=i;
|
package/dist/CrudTableLazy.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { CrudTableConfig
|
|
2
|
-
|
|
1
|
+
import { CrudTableConfig } from './CrudTable';
|
|
2
|
+
/** Code-split `CrudTable`, keeping the same typed configuration. */
|
|
3
|
+
declare const CrudTableLazy: <T extends object, K extends keyof T>(props: CrudTableConfig<T, K>) => import("react").JSX.Element;
|
|
3
4
|
export default CrudTableLazy;
|
|
4
|
-
export type { CrudTableConfig
|
|
5
|
+
export type { CrudTableConfig };
|
package/dist/CrudTableLazy.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { t as e } from "./en_US-DGCMDOdX.js";
|
|
2
|
+
import { Suspense as t, lazy as n } from "react";
|
|
3
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
3
4
|
//#region lib/CrudTableLazy.tsx
|
|
4
|
-
var
|
|
5
|
-
fallback: /* @__PURE__ */
|
|
5
|
+
var i = n(() => import("./CrudTable.js")), a = (n) => /* @__PURE__ */ r(t, {
|
|
6
|
+
fallback: /* @__PURE__ */ r("div", {
|
|
6
7
|
style: {
|
|
7
8
|
textAlign: "center",
|
|
8
9
|
padding: "2rem"
|
|
9
10
|
},
|
|
10
|
-
children:
|
|
11
|
+
children: n.locale?.loading ?? e.loading
|
|
11
12
|
}),
|
|
12
|
-
children: /* @__PURE__ */
|
|
13
|
+
children: /* @__PURE__ */ r(i, { ...n })
|
|
13
14
|
});
|
|
14
15
|
//#endregion
|
|
15
|
-
export {
|
|
16
|
+
export { a as default };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { CrudDataSource, CrudDraft, CrudPage, CrudQuery } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* The operations a consumer may supply. Every entry is optional so a
|
|
4
|
+
* read-only table need not invent write handlers it will never call.
|
|
5
|
+
*/
|
|
6
|
+
export type CrudOperations<T, K extends keyof T> = Partial<CrudDataSource<T, K>>;
|
|
7
|
+
/**
|
|
8
|
+
* Raised when the table attempts an operation the consumer did not supply.
|
|
9
|
+
*
|
|
10
|
+
* Names the missing operation so the message points at the fix rather than
|
|
11
|
+
* surfacing as `undefined is not a function`.
|
|
12
|
+
*/
|
|
13
|
+
export declare class UnsupportedOperationError extends Error {
|
|
14
|
+
/** The operation that was attempted but not supplied. */
|
|
15
|
+
readonly operation: string;
|
|
16
|
+
constructor(operation: string);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Adapts a bag of consumer-supplied functions to the full interface.
|
|
20
|
+
*
|
|
21
|
+
* Exists so the rest of the library can depend on `CrudDataSource` without
|
|
22
|
+
* null-checking each method at every call site; absent operations fail here
|
|
23
|
+
* with a message naming what is missing.
|
|
24
|
+
*/
|
|
25
|
+
export declare class CustomDataSource<T extends object, K extends keyof T> implements CrudDataSource<T, K> {
|
|
26
|
+
private readonly operations;
|
|
27
|
+
constructor(operations: CrudOperations<T, K>);
|
|
28
|
+
/** Whether an operation was supplied, so callers can hide unavailable UI. */
|
|
29
|
+
supports(operation: keyof CrudDataSource<T, K>): boolean;
|
|
30
|
+
list(query: CrudQuery<T>): Promise<CrudPage<T>>;
|
|
31
|
+
listAll(query: Omit<CrudQuery<T>, 'page' | 'pageSize'>): Promise<readonly T[]>;
|
|
32
|
+
create(draft: CrudDraft<T>): Promise<T>;
|
|
33
|
+
update(id: T[K], draft: CrudDraft<T>): Promise<T>;
|
|
34
|
+
remove(id: T[K]): Promise<void>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { CrudDataSource, CrudDraft, CrudPage, CrudQuery, IdGenerator } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Shared behaviour for every source backed by a local collection.
|
|
4
|
+
*
|
|
5
|
+
* Subclasses supply only where the records live, via `read`/`write`. All
|
|
6
|
+
* querying, identity assignment and mutation semantics are defined once here
|
|
7
|
+
* so the static and localStorage strategies cannot drift apart.
|
|
8
|
+
*/
|
|
9
|
+
export declare abstract class InMemoryDataSource<T extends object, K extends keyof T> implements CrudDataSource<T, K> {
|
|
10
|
+
/** The property holding each record's identity. */
|
|
11
|
+
protected readonly key: K;
|
|
12
|
+
/** Assigns the identity for newly created records. */
|
|
13
|
+
protected readonly generateId: IdGenerator<T, K>;
|
|
14
|
+
protected constructor(key: K, generateId?: IdGenerator<T, K>);
|
|
15
|
+
/** Current contents of the backing collection. */
|
|
16
|
+
protected abstract read(): readonly T[];
|
|
17
|
+
/** Replace the backing collection. */
|
|
18
|
+
protected abstract write(records: readonly T[]): void;
|
|
19
|
+
/**
|
|
20
|
+
* Hook for values a subclass stamps onto every write, such as timestamps.
|
|
21
|
+
* Returns nothing extra by default.
|
|
22
|
+
*/
|
|
23
|
+
protected decorate(_record: CrudDraft<T>, _operation: 'create' | 'update'): CrudDraft<T>;
|
|
24
|
+
private indexOf;
|
|
25
|
+
list(query: CrudQuery<T>): Promise<CrudPage<T>>;
|
|
26
|
+
listAll(query: Omit<CrudQuery<T>, 'page' | 'pageSize'>): Promise<readonly T[]>;
|
|
27
|
+
create(draft: CrudDraft<T>): Promise<T>;
|
|
28
|
+
update(id: T[K], draft: CrudDraft<T>): Promise<T>;
|
|
29
|
+
remove(id: T[K]): Promise<void>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { InMemoryDataSource } from './InMemoryDataSource';
|
|
2
|
+
import { CrudDraft, IdGenerator } from './types';
|
|
3
|
+
/** Fields stamped onto records by the localStorage strategy. */
|
|
4
|
+
export interface Timestamped {
|
|
5
|
+
/** ISO timestamp set once, when the record is created. */
|
|
6
|
+
createdAt?: string;
|
|
7
|
+
/** ISO timestamp refreshed on every write. */
|
|
8
|
+
updatedAt?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A source persisting to `localStorage` under a fixed key.
|
|
12
|
+
*
|
|
13
|
+
* Reads go through storage on every call rather than through a cache, so a
|
|
14
|
+
* second tab writing the same key is picked up on the next query instead of
|
|
15
|
+
* being shadowed by stale in-memory state.
|
|
16
|
+
*
|
|
17
|
+
* Storage is best-effort: a read that fails or returns malformed JSON falls
|
|
18
|
+
* back to the seed rather than throwing, since an unreadable cache should not
|
|
19
|
+
* take the table down. Writes that fail (quota, private mode) *do* throw -
|
|
20
|
+
* silently dropping a write the user believes succeeded is worse than an error.
|
|
21
|
+
*/
|
|
22
|
+
export declare class LocalStorageDataSource<T extends object, K extends keyof T> extends InMemoryDataSource<T, K> {
|
|
23
|
+
private readonly storageKey;
|
|
24
|
+
private readonly seed;
|
|
25
|
+
constructor(storageKey: string, key: K, seed?: readonly T[], generateId?: IdGenerator<T, K>);
|
|
26
|
+
protected read(): readonly T[];
|
|
27
|
+
protected write(records: readonly T[]): void;
|
|
28
|
+
/** Stamps creation and modification times onto every write. */
|
|
29
|
+
protected decorate(_draft: CrudDraft<T>, operation: 'create' | 'update'): CrudDraft<T>;
|
|
30
|
+
}
|