@boarteam/boar-pack-common-frontend 4.0.0 → 4.1.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.
Files changed (60) hide show
  1. package/dist/tools/safetyRun.d.ts +2 -1
  2. package/dist/tools/safetyRun.js +2 -1
  3. package/dist/tools/safetyRun.js.map +1 -1
  4. package/package.json +2 -3
  5. package/src/components/ChangesModal/ChangesModal.tsx +0 -260
  6. package/src/components/ChangesModal/ChangesTab.tsx +0 -51
  7. package/src/components/ChangesModal/ConflictsTab.tsx +0 -176
  8. package/src/components/ChangesModal/ErrorsTab.tsx +0 -49
  9. package/src/components/ChangesModal/NewRecordsTab.tsx +0 -48
  10. package/src/components/ChangesModal/ResultsTab.tsx +0 -28
  11. package/src/components/ChangesModal/index.ts +0 -1
  12. package/src/components/Comment/Comment.tsx +0 -53
  13. package/src/components/Comment/CommentAvatar.tsx +0 -34
  14. package/src/components/Comment/CommentForm.tsx +0 -36
  15. package/src/components/Comment/CommentFormModal.tsx +0 -31
  16. package/src/components/Comment/index.ts +0 -5
  17. package/src/components/Descriptions/Descriptions.tsx +0 -328
  18. package/src/components/Descriptions/DescriptionsCreateModal.tsx +0 -65
  19. package/src/components/Descriptions/descriptionTypes.ts +0 -73
  20. package/src/components/Descriptions/index.ts +0 -5
  21. package/src/components/Descriptions/useContentViewMode.tsx +0 -28
  22. package/src/components/Descriptions/useDescriptionColumns.ts +0 -42
  23. package/src/components/Inputs/DateRange.tsx +0 -75
  24. package/src/components/Inputs/MultiStringSelect.tsx +0 -20
  25. package/src/components/Inputs/NumberInputHandlingNewRecord.tsx +0 -11
  26. package/src/components/Inputs/NumberSwitcher.tsx +0 -27
  27. package/src/components/Inputs/Password.tsx +0 -33
  28. package/src/components/Inputs/RelationSelect.tsx +0 -108
  29. package/src/components/Inputs/SearchSelect.tsx +0 -93
  30. package/src/components/Inputs/filterDropdowns.tsx +0 -144
  31. package/src/components/Inputs/index.ts +0 -9
  32. package/src/components/Inputs/useCheckConnection.tsx +0 -79
  33. package/src/components/List/List.tsx +0 -266
  34. package/src/components/List/index.ts +0 -3
  35. package/src/components/List/listTypes.ts +0 -31
  36. package/src/components/QuestionMarkHint/QuestionMarkHint.tsx +0 -33
  37. package/src/components/QuestionMarkHint/index.ts +0 -1
  38. package/src/components/Table/BulkDeleteButton.tsx +0 -55
  39. package/src/components/Table/BulkEditButton.tsx +0 -160
  40. package/src/components/Table/CreateEntityModal.tsx +0 -85
  41. package/src/components/Table/DeleteButton.tsx +0 -44
  42. package/src/components/Table/Table.tsx +0 -294
  43. package/src/components/Table/getTableDataQueryParams.ts +0 -79
  44. package/src/components/Table/index.ts +0 -7
  45. package/src/components/Table/tableTools.ts +0 -244
  46. package/src/components/Table/tableTypes.ts +0 -148
  47. package/src/components/Table/useBulkEditing.tsx +0 -128
  48. package/src/components/Table/useColumnsSets.tsx +0 -142
  49. package/src/components/Table/useCreation.tsx +0 -114
  50. package/src/components/Table/useEditableTable.tsx +0 -86
  51. package/src/components/Table/useImportExport.tsx +0 -315
  52. package/src/components/index.ts +0 -6
  53. package/src/index.ts +0 -2
  54. package/src/tools/ApiError.ts +0 -18
  55. package/src/tools/WebsocketClient.ts +0 -146
  56. package/src/tools/index.ts +0 -6
  57. package/src/tools/numberTools.ts +0 -6
  58. package/src/tools/safetyRun.ts +0 -5
  59. package/src/tools/useFullscreen.tsx +0 -62
  60. package/src/tools/useTabs.ts +0 -17
@@ -1,266 +0,0 @@
1
- import { ActionType } from "@ant-design/pro-table";
2
- import React, { useEffect, useRef, useState } from "react";
3
- import { Button, Tooltip } from "antd";
4
- import { DeleteOutlined, PlusOutlined, StopOutlined } from "@ant-design/icons";
5
- import { FormattedMessage, useIntl } from "react-intl";
6
- import { flushSync } from "react-dom";
7
- import { ProList } from "@ant-design/pro-components";
8
- import { getNewId, KEY_SYMBOL } from "../Table";
9
- import { createStyles } from "antd-style";
10
- import { TListProps } from "./listTypes";
11
- import {
12
- applyKeywordToSearch,
13
- buildJoinFields, collectFieldsFromColumns,
14
- getFiltersSearch,
15
- TFilterParams,
16
- TFilters,
17
- TGetAllParams,
18
- TSort
19
- } from "../Table";
20
- // import DescriptionsCreateModal from "../Descriptions/DescriptionsCreateModal";
21
-
22
- const useStyles = createStyles(() => {
23
- return {
24
- list: {
25
- '.ant-pro-list-row-editable .ant-form-item': {
26
- width: '100%',
27
- },
28
- '.ant-pro-checkcard-body': {
29
- padding: '12px !important',
30
- }
31
- }
32
- }
33
- })
34
-
35
- const List = <Entity extends Record<string | symbol, any>,
36
- CreateDto = Entity,
37
- UpdateDto = Entity,
38
- TEntityParams = {},
39
- TPathParams extends Record<string, string | number> = {},
40
- TKey = string,
41
- >(
42
- {
43
- getAll,
44
- onCreate,
45
- onUpdate,
46
- onDelete,
47
- pathParams,
48
- idColumnName = 'id',
49
- entityToCreateDto,
50
- entityToUpdateDto,
51
- createNewDefaultParams,
52
- afterSave,
53
- actionRef: actionRefProp,
54
- editable,
55
- defaultSort = ['createdAt', 'DESC'],
56
- searchableColumns = [],
57
- viewOnly = false,
58
- columns = [],
59
- // columnsSets,
60
- popupCreation = false,
61
- toolBarRender,
62
- metas,
63
- ...rest
64
- }: TListProps<Entity,
65
- CreateDto,
66
- UpdateDto,
67
- TEntityParams,
68
- TPathParams>
69
- ) => {
70
- const actionRefComponent = useRef<ActionType>();
71
- const actionRef = actionRefProp || actionRefComponent;
72
- // const [createPopupData, setCreatePopupData] = useState<Partial<Entity> | undefined>();
73
- const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);
74
- const [editableData, setEditableData] = useState<(Entity)[]>([]);
75
- const intl = useIntl();
76
-
77
- useEffect(() => {
78
- actionRef?.current?.reload();
79
- }, [JSON.stringify(pathParams)]);
80
-
81
- const request = async (
82
- params: TFilterParams,
83
- sort: TSort = {},
84
- filters: TFilters = {},
85
- ) => {
86
- const {
87
- current,
88
- pageSize,
89
- keyword,
90
- baseFilters,
91
- join,
92
- sortMap,
93
- } = params;
94
-
95
- const queryParams: TGetAllParams & TPathParams = {
96
- ...pathParams,
97
- page: current,
98
- limit: pageSize,
99
- };
100
-
101
- const sortBy = Object
102
- .entries(sort)
103
- .reduce<string[]>(
104
- (data: string[], [key, direction]) => {
105
- data.push(`${sortMap?.[key] || key},${direction === 'ascend' ? 'ASC' : 'DESC'}`);
106
- return data;
107
- },
108
- []
109
- );
110
- if (!sortBy.length && defaultSort) {
111
- sortBy.push(defaultSort.join(','));
112
- }
113
- queryParams.sort = sortBy;
114
-
115
- let search = getFiltersSearch({
116
- baseFilters,
117
- filters,
118
- searchableColumns,
119
- });
120
- search = applyKeywordToSearch(search, searchableColumns!, null, keyword);
121
- queryParams.s = JSON.stringify(search);
122
-
123
- const { joinSelect, joinFields } = buildJoinFields(join);
124
- queryParams.join = joinSelect;
125
-
126
- queryParams.fields = columns && collectFieldsFromColumns(
127
- columns,
128
- idColumnName,
129
- joinFields,
130
- ) || [];
131
-
132
- return getAll(queryParams);
133
- }
134
-
135
- const createButton = <Button
136
- size='middle'
137
- type="primary"
138
- key="create"
139
- onClick={() => {
140
- // if (popupCreation) {
141
- // setCreatePopupData(createNewDefaultParams);
142
- // } else {
143
- const newId = getNewId();
144
- actionRef?.current?.addEditRecord({
145
- [idColumnName]: newId,
146
- [KEY_SYMBOL]: newId,
147
- ...createNewDefaultParams,
148
- }, {
149
- position: 'top',
150
- });
151
- // }
152
- }}
153
- >
154
- <PlusOutlined /> <FormattedMessage id={'table.newButton'} />
155
- </Button>;
156
-
157
- return (<>
158
- <ProList<Entity>
159
- className={useStyles().styles.list}
160
- actionRef={actionRef}
161
- // todo: fix ts
162
- // @ts-ignore
163
- request={request}
164
- rowKey={record => record[KEY_SYMBOL] ?? record[idColumnName]}
165
- bordered
166
- search={false}
167
- options={{
168
- fullScreen: true,
169
- reload: true,
170
- search: {
171
- allowClear: true,
172
- },
173
- }}
174
- editable={{
175
- type: 'multiple',
176
- editableKeys,
177
- onChange: setEditableRowKeys,
178
- onValuesChange(entity, data) {
179
- setEditableData(data);
180
- },
181
- async onSave(
182
- id,
183
- record,
184
- origin,
185
- newLine,
186
- ) {
187
- const data = editableData.find(entity => entity[idColumnName] === id) || record;
188
- if (newLine) {
189
- await onCreate?.({
190
- ...pathParams,
191
- requestBody: entityToCreateDto(data)
192
- });
193
- } else {
194
- await onUpdate({
195
- ...pathParams,
196
- ...{ [idColumnName]: String(id) } as Record<keyof Entity, string>,
197
- requestBody: entityToUpdateDto({
198
- ...pathParams,
199
- ...data,
200
- }),
201
- })
202
- }
203
-
204
- if (typeof afterSave === 'function') {
205
- await afterSave(data);
206
- }
207
-
208
- flushSync(() => {
209
- actionRef?.current?.reload();
210
- });
211
- },
212
- async onCancel(
213
- id,
214
- record,
215
- origin,
216
- ) {
217
- editableData.forEach(entity => {
218
- if (entity[idColumnName] === id) {
219
- Object.assign(entity, origin);
220
- }
221
- })
222
- },
223
- async onDelete(id) {
224
- await onDelete({ ...{ [idColumnName]: String(id) } as Record<keyof Entity, string>, ...pathParams });
225
- },
226
- deletePopconfirmMessage: intl.formatMessage({ id: 'table.deletePopconfirmMessage' }),
227
- onlyAddOneLineAlertMessage: intl.formatMessage({ id: 'table.onlyAddOneLineAlertMessage' }),
228
- cancelText: <Tooltip title={intl.formatMessage({ id: 'table.cancelText' })}><StopOutlined /></Tooltip>,
229
- deleteText: <Tooltip title={intl.formatMessage({ id: 'table.deleteText' })}><DeleteOutlined /></Tooltip>,
230
- saveText: <Button size={"small"} type={"primary"}><FormattedMessage id={'table.saveText'} /></Button>,
231
- ...editable,
232
- }}
233
- toolBarRender={(...args) => [
234
- ...toolBarRender && toolBarRender(...args) || [],
235
- !viewOnly && createButton || null,
236
- ]}
237
- grid={{ gutter: 16, column: 1 }}
238
- metas={metas}
239
- {...rest}
240
- />
241
- {/*<DescriptionsCreateModal<Entity>*/}
242
- {/* data={createPopupData}*/}
243
- {/* onClose={() => setCreatePopupData(undefined)}*/}
244
- {/* onSubmit={async (data) => {*/}
245
- {/* try {*/}
246
- {/* await onCreate?.({*/}
247
- {/* ...pathParams,*/}
248
- {/* requestBody: entityToCreateDto({*/}
249
- {/* ...pathParams,*/}
250
- {/* ...data,*/}
251
- {/* })*/}
252
- {/* });*/}
253
- {/* actionRef?.current?.reload();*/}
254
- {/* setCreatePopupData(undefined);*/}
255
- {/* }*/}
256
- {/* catch (e) {*/}
257
- {/* console.error(e);*/}
258
- {/* }*/}
259
- {/* }}*/}
260
- {/* idColumnName={idColumnName}*/}
261
- {/* columns={columns ?? []}*/}
262
- {/*/>*/}
263
- </>);
264
- };
265
-
266
- export default List;
@@ -1,3 +0,0 @@
1
- export * from './List';
2
- export { default as List } from './List';
3
- export * from './listTypes';
@@ -1,31 +0,0 @@
1
- import { MutableRefObject } from "react";
2
- import { ActionType } from "@ant-design/pro-table";
3
- import { QuerySortArr } from "@nestjsx/crud-request";
4
- import { RowEditableConfig } from "@ant-design/pro-utils";
5
- import { ProListProps } from "@ant-design/pro-components";
6
- import { TFilterParams, TGetAllParams, TSearchableColumn } from "../Table";
7
-
8
- export interface TListProps<
9
- Entity,
10
- CreateDto,
11
- UpdateDto,
12
- TEntityParams = {},
13
- TPathParams = {}
14
- > extends ProListProps<Entity, TEntityParams & TFilterParams> {
15
- getAll: ({}: TGetAllParams & TPathParams) => Promise<{ data: Entity[] }>,
16
- onCreate?: ({}: { requestBody: CreateDto } & TPathParams) => Promise<Entity>,
17
- onUpdate: ({}: Record<keyof Entity, string> & { requestBody: UpdateDto } & TPathParams) => Promise<Entity>,
18
- onDelete: ({}: Record<keyof Entity, string> & TPathParams) => Promise<void>,
19
- pathParams: TPathParams,
20
- idColumnName?: string & keyof Entity,
21
- entityToCreateDto: (entity: Entity) => CreateDto,
22
- entityToUpdateDto: (entity: Entity) => UpdateDto,
23
- createNewDefaultParams?: Partial<Entity>,
24
- afterSave?: (record: Entity) => Promise<void>,
25
- actionRef?: MutableRefObject<ActionType | undefined>,
26
- editable?: RowEditableConfig<Entity>,
27
- defaultSort?: QuerySortArr,
28
- searchableColumns?: TSearchableColumn[],
29
- popupCreation?: boolean,
30
- viewOnly?: boolean,
31
- }
@@ -1,33 +0,0 @@
1
- import React from "react";
2
- import { Popover } from "antd";
3
- import { QuestionCircleTwoTone } from "@ant-design/icons";
4
- import { PrimitiveType } from "intl-messageformat";
5
- import { useIntl } from "react-intl";
6
-
7
- export const QuestionMarkHint: React.FC<{
8
- intlPrefix: string,
9
- values?: Record<string, PrimitiveType | React.ReactElement>
10
- }> = ({
11
- intlPrefix,
12
- values,
13
- }) => {
14
- const intl = useIntl();
15
- return (
16
- <Popover
17
- content={(
18
- <div
19
- style={{
20
- maxWidth: 300,
21
- }}
22
- >{intl.formatMessage({ id: `${intlPrefix}.hint.message` }, values)}</div>
23
- )}
24
- title={intl.formatMessage({ id: `${intlPrefix}.hint.title` })}
25
- trigger={['hover', 'click']}
26
- zIndex={1080}
27
- >
28
- <QuestionCircleTwoTone />
29
- </Popover>
30
- )
31
- }
32
-
33
- export default QuestionMarkHint;
@@ -1 +0,0 @@
1
- export * from './QuestionMarkHint';
@@ -1,55 +0,0 @@
1
- import { Button, Popconfirm } from "antd";
2
- import { LoadingOutlined } from "@ant-design/icons";
3
- import { TGetAllParams } from "./tableTypes";
4
- import { createStyles } from "antd-style";
5
- import { useState } from "react";
6
-
7
- const useStyles = createStyles(() => {
8
- return {
9
- popconfirm: {
10
- '.ant-popconfirm-description': {
11
- marginTop: '0 !important',
12
- },
13
- }
14
- }
15
- })
16
-
17
- const BulkDeleteButton = <Entity extends Record<string | symbol, any>, TPathParams>(
18
- {
19
- selectedRecords,
20
- lastRequest,
21
- allSelected,
22
- onDelete,
23
- } : {
24
- selectedRecords: Entity[],
25
- allSelected: boolean,
26
- lastRequest: [TGetAllParams & TPathParams, any] | [],
27
- onDelete: () => Promise<void>
28
- }) => {
29
- const { styles } = useStyles();
30
- const [loading, setLoading] = useState(false);
31
- const recordsCount = allSelected ? lastRequest[1].total : selectedRecords.length;
32
-
33
- return (<>
34
- <Popconfirm
35
- overlayClassName={styles.popconfirm}
36
- title={false}
37
- description={`Are you sure you want to delete ${recordsCount} ${recordsCount === 1 ? 'record' : 'records'}?`}
38
- onConfirm={() => {
39
- setLoading(true);
40
- onDelete().finally(() => setLoading(false));
41
- }}
42
- okText="Yes"
43
- cancelText="No"
44
- >
45
- <Button
46
- disabled={recordsCount === 0}
47
- >
48
- {recordsCount > 0 ? `Delete ${recordsCount} ${recordsCount === 1 ? 'Record' : 'Records'}` : 'Bulk Delete'}
49
- {loading && <LoadingOutlined />}
50
- </Button>
51
- </Popconfirm>
52
- </>);
53
- };
54
-
55
- export default BulkDeleteButton;
@@ -1,160 +0,0 @@
1
- import { ProColumns } from "@ant-design/pro-table";
2
- import React, { useEffect, useState } from "react";
3
- import { Button, Checkbox, Modal, Popconfirm } from "antd";
4
- import { LoadingOutlined } from "@ant-design/icons";
5
- import { columnsToDescriptionItemProps } from "../Descriptions";
6
- import { useForm } from "antd/lib/form/Form";
7
- import { ProDescriptions } from "@ant-design/pro-components";
8
- import { TGetAllParams } from "./tableTypes";
9
- import { createStyles } from "antd-style";
10
-
11
- type TBulkEditConfig<Entity> = { type: 'records', value: Entity[], count: number } | { type: 'query', value: Record<string, any>, count: number } | null;
12
-
13
- const useStyles = createStyles(() => {
14
- return {
15
- popconfirm: {
16
- '.ant-popconfirm-description': {
17
- marginTop: '0 !important',
18
- },
19
- }
20
- }
21
- })
22
-
23
- const BulkEditDialog = <Entity extends Record<string | symbol, any>>(
24
- {
25
- columns,
26
- idColumnName,
27
- config,
28
- onClose,
29
- onSubmit,
30
- }: {
31
- idColumnName: string & keyof Entity | (string & keyof Entity)[],
32
- columns: ProColumns<Entity>[],
33
- config: TBulkEditConfig<Entity>,
34
- onClose: () => void,
35
- onSubmit: (value: Partial<Entity>) => Promise<void>
36
- }) => {
37
- const [loading, setLoading] = useState(false);
38
- const sections = columnsToDescriptionItemProps(columns, 'General');
39
- const { styles } = useStyles();
40
-
41
- const [editableKeys, setEditableKeys] = useState<Set<string>>(new Set);
42
-
43
- const [form] = useForm();
44
- useEffect(() => {
45
- setEditableKeys(new Set);
46
- form.resetFields();
47
- }, [config]);
48
-
49
- const handleCheckboxChange = (dataIndex: string, checked: boolean) => {
50
- setEditableKeys(prev => {
51
- const next = new Set(prev);
52
- checked ? next.add(dataIndex) : next.delete(dataIndex);
53
- return next;
54
- });
55
- };
56
-
57
- const handleUpdate = async () => {
58
- await form.validateFields();
59
- setLoading(true);
60
- await onSubmit(form.getFieldsValue()).finally(() => setLoading(false));
61
- onClose();
62
- };
63
-
64
- return (
65
- <Modal
66
- title={`Updating ${config?.count} ${config?.count === 1 ? 'record' : 'records'}...`}
67
- open={config !== null}
68
- onCancel={onClose}
69
- width='80%'
70
- footer={[
71
- <Popconfirm
72
- overlayClassName={styles.popconfirm}
73
- title={false}
74
- description={`Are you sure you want to update ${config?.count} ${config?.count === 1 ? 'record' : 'records'}?`}
75
- onConfirm={() => handleUpdate()}
76
- okText="Yes"
77
- cancelText="No"
78
- >
79
- <Button key='submit' type="primary">Update {loading && <LoadingOutlined />}</Button>
80
- </Popconfirm>
81
- ]}
82
- >
83
- {sections.map((section) => {
84
- return (
85
- <ProDescriptions<Entity>
86
- extra={'Click on the field first and then type a new desired value.'}
87
- key={Array.isArray(idColumnName) ? idColumnName.join('-') : idColumnName}
88
- title={section.title as React.ReactNode}
89
- size={"small"}
90
- bordered
91
- column={3}
92
- style={{ marginBottom: 20 }}
93
- labelStyle={{ width: '15%' }}
94
- contentStyle={{ width: '25%' }}
95
- editable={{
96
- form,
97
- editableKeys: [...editableKeys],
98
- actionRender: () => [],
99
- }}
100
- columns={section.columns.filter(column => column?.editable === undefined).map(column => ({
101
- ...column,
102
- render: (...params: any[]) => !editableKeys.has(column.dataIndex as string) ? '(This field will not be changed)' : (column.render as Function)(...params),
103
- editable: false,
104
- title: (
105
- <Checkbox
106
- checked={editableKeys.has(column.dataIndex as string)}
107
- onChange={e => handleCheckboxChange(column.dataIndex as string, e.target.checked)}
108
- >
109
- {column.title as React.ReactNode}
110
- </Checkbox>
111
- ),
112
- }))}
113
- />
114
- )
115
- })}
116
- </Modal>
117
- );
118
- }
119
-
120
- const BulkEditButton = <Entity extends Record<string | symbol, any>, TPathParams>(
121
- {
122
- selectedRecords,
123
- lastRequest,
124
- allSelected,
125
- columns,
126
- idColumnName,
127
- onSubmit,
128
- } : {
129
- selectedRecords: Entity[],
130
- lastRequest: [TGetAllParams & TPathParams, any] | [],
131
- idColumnName: string & keyof Entity | (string & keyof Entity)[],
132
- allSelected: boolean,
133
- columns: ProColumns<Entity>[],
134
- onSubmit: (value: Partial<Entity>) => Promise<void>
135
- }) => {
136
- const [bulkEditConfig, setBulkEditConfig] = useState<TBulkEditConfig<Entity>>(null);
137
- const recordsCount = allSelected ? lastRequest[1].total : selectedRecords.length;
138
-
139
- return (<>
140
- <Button
141
- disabled={recordsCount === 0}
142
- onClick={() => setBulkEditConfig(
143
- !allSelected
144
- ? { type: 'records', value: selectedRecords, count: selectedRecords.length }
145
- : { type: 'query', value: lastRequest[0], count: lastRequest[1].total }
146
- )}
147
- >
148
- {recordsCount > 0 ? `Edit ${recordsCount} ${recordsCount === 1 ? 'Record' : 'Records'}` : 'Bulk Edit'}
149
- </Button>
150
- <BulkEditDialog<Entity>
151
- config={bulkEditConfig}
152
- onClose={() => setBulkEditConfig(null)}
153
- columns={columns}
154
- idColumnName={idColumnName}
155
- onSubmit={onSubmit}
156
- />
157
- </>);
158
- };
159
-
160
- export default BulkEditButton;
@@ -1,85 +0,0 @@
1
- import { ProColumns } from "@ant-design/pro-components";
2
- import { Button, Modal } from "antd";
3
- import { MutableRefObject, useRef } from "react";
4
- import { Descriptions, DescriptionsRefType } from "../Descriptions";
5
- import { buildFieldsFromColumnsForDescriptionsDisplay } from "./tableTools";
6
-
7
- export interface CreateEntityModalProps<Entity> {
8
- /** Whether the modal is visible */
9
- open?: boolean;
10
- /** The entity (or partial entity) data to edit */
11
- entity: Partial<Entity> | undefined;
12
- /** Modal title */
13
- title: string;
14
- /** Main title for the Descriptions component */
15
- mainTitle?: ProColumns<Entity>['title'] | null;
16
- /** Table columns used to render the fields */
17
- columns: any[];
18
- /** Column key (or keys) used as an ID */
19
- idColumnName: string | string[];
20
- /** Called when the modal is cancelled (closed) */
21
- onCancel: () => void;
22
- /**
23
- * Called when the form is submitted.
24
- * Receives the validated form data.
25
- */
26
- onSubmit: (data: any, descriptionsRef: MutableRefObject<DescriptionsRefType<Entity>>) => Promise<void>;
27
- }
28
-
29
- export function CreateEntityModal<
30
- Entity,
31
- CreateDto = Entity,
32
- UpdateDto = Entity,
33
- TPathParams = object
34
- >({
35
- entity,
36
- open = entity !== undefined,
37
- title,
38
- mainTitle,
39
- columns,
40
- idColumnName,
41
- onCancel,
42
- onSubmit,
43
- }: CreateEntityModalProps<Entity>) {
44
- const descriptionsRef = useRef<DescriptionsRefType<Entity>>(null);
45
-
46
- // Calculate the editable keys from the columns and idColumnName
47
- const editableKeys = [...buildFieldsFromColumnsForDescriptionsDisplay(columns, idColumnName)];
48
-
49
- return (
50
- <Modal
51
- title={title}
52
- open={open}
53
- width="80%"
54
- closeIcon={true}
55
- footer={[
56
- <Button key="submit" type="primary" onClick={() => descriptionsRef.current?.submit()}>
57
- Create
58
- </Button>,
59
- ]}
60
- onCancel={() => {
61
- descriptionsRef.current?.reset();
62
- onCancel();
63
- }}
64
- >
65
- <Descriptions<Entity, CreateDto, UpdateDto, TPathParams>
66
- ref={descriptionsRef}
67
- mainTitle={mainTitle}
68
- columns={columns ?? []}
69
- entity={entity}
70
- size="small"
71
- bordered
72
- column={2}
73
- style={{ marginBottom: 20 }}
74
- labelStyle={{ width: '15%' }}
75
- contentStyle={{ width: '25%' }}
76
- canEdit={true}
77
- onCreate={(data) => onSubmit(data, descriptionsRef)}
78
- editable={{
79
- editableKeys,
80
- actionRender: () => [],
81
- }}
82
- />
83
- </Modal>
84
- );
85
- }
@@ -1,44 +0,0 @@
1
- import { Popconfirm, Tooltip } from "antd";
2
- import { DeleteOutlined, LoadingOutlined } from "@ant-design/icons";
3
- import { createStyles } from "antd-style";
4
- import { useState } from "react";
5
- import { useIntl } from "react-intl";
6
-
7
- const useStyles = createStyles(() => {
8
- return {
9
- popconfirm: {
10
- '.ant-popconfirm-description': {
11
- marginTop: '0 !important',
12
- },
13
- }
14
- }
15
- })
16
-
17
- const DeleteButton = (
18
- {
19
- onDelete,
20
- }: {
21
- onDelete: () => Promise<void>
22
- }) => {
23
- const {styles} = useStyles();
24
- const [loading, setLoading] = useState(false);
25
- const intl = useIntl();
26
-
27
- return (<a key="deleteButton">
28
- {!loading && <Popconfirm
29
- overlayClassName={styles.popconfirm}
30
- title={false}
31
- description={intl.formatMessage({id: "table.deletePopconfirmMessage"})}
32
- onConfirm={() => {
33
- setLoading(true);
34
- onDelete().finally(() => setLoading(false));
35
- }}>
36
- <Tooltip title={intl.formatMessage({id: "table.deleteText"})}>
37
- <DeleteOutlined/>
38
- </Tooltip>
39
- </Popconfirm>}
40
- {loading && <LoadingOutlined/>}
41
- </a>
42
- );
43
- };
44
- export default DeleteButton;