@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.
- package/dist/tools/safetyRun.d.ts +2 -1
- package/dist/tools/safetyRun.js +2 -1
- package/dist/tools/safetyRun.js.map +1 -1
- package/package.json +2 -3
- package/src/components/ChangesModal/ChangesModal.tsx +0 -260
- package/src/components/ChangesModal/ChangesTab.tsx +0 -51
- package/src/components/ChangesModal/ConflictsTab.tsx +0 -176
- package/src/components/ChangesModal/ErrorsTab.tsx +0 -49
- package/src/components/ChangesModal/NewRecordsTab.tsx +0 -48
- package/src/components/ChangesModal/ResultsTab.tsx +0 -28
- package/src/components/ChangesModal/index.ts +0 -1
- package/src/components/Comment/Comment.tsx +0 -53
- package/src/components/Comment/CommentAvatar.tsx +0 -34
- package/src/components/Comment/CommentForm.tsx +0 -36
- package/src/components/Comment/CommentFormModal.tsx +0 -31
- package/src/components/Comment/index.ts +0 -5
- package/src/components/Descriptions/Descriptions.tsx +0 -328
- package/src/components/Descriptions/DescriptionsCreateModal.tsx +0 -65
- package/src/components/Descriptions/descriptionTypes.ts +0 -73
- package/src/components/Descriptions/index.ts +0 -5
- package/src/components/Descriptions/useContentViewMode.tsx +0 -28
- package/src/components/Descriptions/useDescriptionColumns.ts +0 -42
- package/src/components/Inputs/DateRange.tsx +0 -75
- package/src/components/Inputs/MultiStringSelect.tsx +0 -20
- package/src/components/Inputs/NumberInputHandlingNewRecord.tsx +0 -11
- package/src/components/Inputs/NumberSwitcher.tsx +0 -27
- package/src/components/Inputs/Password.tsx +0 -33
- package/src/components/Inputs/RelationSelect.tsx +0 -108
- package/src/components/Inputs/SearchSelect.tsx +0 -93
- package/src/components/Inputs/filterDropdowns.tsx +0 -144
- package/src/components/Inputs/index.ts +0 -9
- package/src/components/Inputs/useCheckConnection.tsx +0 -79
- package/src/components/List/List.tsx +0 -266
- package/src/components/List/index.ts +0 -3
- package/src/components/List/listTypes.ts +0 -31
- package/src/components/QuestionMarkHint/QuestionMarkHint.tsx +0 -33
- package/src/components/QuestionMarkHint/index.ts +0 -1
- package/src/components/Table/BulkDeleteButton.tsx +0 -55
- package/src/components/Table/BulkEditButton.tsx +0 -160
- package/src/components/Table/CreateEntityModal.tsx +0 -85
- package/src/components/Table/DeleteButton.tsx +0 -44
- package/src/components/Table/Table.tsx +0 -294
- package/src/components/Table/getTableDataQueryParams.ts +0 -79
- package/src/components/Table/index.ts +0 -7
- package/src/components/Table/tableTools.ts +0 -244
- package/src/components/Table/tableTypes.ts +0 -148
- package/src/components/Table/useBulkEditing.tsx +0 -128
- package/src/components/Table/useColumnsSets.tsx +0 -142
- package/src/components/Table/useCreation.tsx +0 -114
- package/src/components/Table/useEditableTable.tsx +0 -86
- package/src/components/Table/useImportExport.tsx +0 -315
- package/src/components/index.ts +0 -6
- package/src/index.ts +0 -2
- package/src/tools/ApiError.ts +0 -18
- package/src/tools/WebsocketClient.ts +0 -146
- package/src/tools/index.ts +0 -6
- package/src/tools/numberTools.ts +0 -6
- package/src/tools/safetyRun.ts +0 -5
- package/src/tools/useFullscreen.tsx +0 -62
- package/src/tools/useTabs.ts +0 -17
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import React, { MutableRefObject } from "react";
|
|
2
|
-
import { ActionType, ProTableProps } from "@ant-design/pro-table";
|
|
3
|
-
import { QueryJoin, QuerySortArr } from "@nestjsx/crud-request";
|
|
4
|
-
import { Operators } from "./tableTools";
|
|
5
|
-
import { TColumnsSet } from "./useColumnsSets";
|
|
6
|
-
import { ColumnStateType } from "@ant-design/pro-table/es/typing";
|
|
7
|
-
import { RowEditableConfig } from "@ant-design/pro-utils";
|
|
8
|
-
import { ProColumns } from "@ant-design/pro-components";
|
|
9
|
-
import { TImportResponse, TRelationalFields } from "../ChangesModal";
|
|
10
|
-
export type IWithId = {
|
|
11
|
-
id: string | number,
|
|
12
|
-
}
|
|
13
|
-
export type TGetAllParams = {
|
|
14
|
-
/**
|
|
15
|
-
* Selects resource fields. <a href="https://github.com/nestjsx/crud/wiki/Requests#select" target="_blank">Docs</a>
|
|
16
|
-
*/
|
|
17
|
-
fields?: Array<string>,
|
|
18
|
-
/**
|
|
19
|
-
* Adds search condition. <a href="https://github.com/nestjsx/crud/wiki/Requests#search" target="_blank">Docs</a>
|
|
20
|
-
*/
|
|
21
|
-
s?: string,
|
|
22
|
-
/**
|
|
23
|
-
* Adds filter condition. <a href="https://github.com/nestjsx/crud/wiki/Requests#filter" target="_blank">Docs</a>
|
|
24
|
-
*/
|
|
25
|
-
filter?: Array<string>,
|
|
26
|
-
/**
|
|
27
|
-
* Adds OR condition. <a href="https://github.com/nestjsx/crud/wiki/Requests#or" target="_blank">Docs</a>
|
|
28
|
-
*/
|
|
29
|
-
or?: Array<string>,
|
|
30
|
-
/**
|
|
31
|
-
* Adds sort by field. <a href="https://github.com/nestjsx/crud/wiki/Requests#sort" target="_blank">Docs</a>
|
|
32
|
-
*/
|
|
33
|
-
sort?: Array<string>,
|
|
34
|
-
/**
|
|
35
|
-
* Adds relational resources. <a href="https://github.com/nestjsx/crud/wiki/Requests#join" target="_blank">Docs</a>
|
|
36
|
-
*/
|
|
37
|
-
join?: Array<string>,
|
|
38
|
-
/**
|
|
39
|
-
* Limit amount of resources. <a href="https://github.com/nestjsx/crud/wiki/Requests#limit" target="_blank">Docs</a>
|
|
40
|
-
*/
|
|
41
|
-
limit?: number,
|
|
42
|
-
/**
|
|
43
|
-
* Offset amount of resources. <a href="https://github.com/nestjsx/crud/wiki/Requests#offset" target="_blank">Docs</a>
|
|
44
|
-
*/
|
|
45
|
-
offset?: number,
|
|
46
|
-
/**
|
|
47
|
-
* Page portion of resources. <a href="https://github.com/nestjsx/crud/wiki/Requests#page" target="_blank">Docs</a>
|
|
48
|
-
*/
|
|
49
|
-
page?: number,
|
|
50
|
-
/**
|
|
51
|
-
* Reset cache (if was enabled). <a href="https://github.com/nestjsx/crud/wiki/Requests#cache" target="_blank">Docs</a>
|
|
52
|
-
*/
|
|
53
|
-
cache?: number,
|
|
54
|
-
}
|
|
55
|
-
export type TFilters = {
|
|
56
|
-
[key: string]: number | string | boolean | (string | number | boolean)[] | null;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export type TGetRequestParams = {
|
|
60
|
-
baseFilters?: TFilters;
|
|
61
|
-
join?: QueryJoin | QueryJoin[];
|
|
62
|
-
};
|
|
63
|
-
export type TGetAllRequestParams = TGetRequestParams & {
|
|
64
|
-
keyword?: string;
|
|
65
|
-
}
|
|
66
|
-
export type TFilterParams = {
|
|
67
|
-
current?: number;
|
|
68
|
-
pageSize?: number;
|
|
69
|
-
sortMap?: { [key: string]: string };
|
|
70
|
-
} & TGetAllRequestParams;
|
|
71
|
-
export type TSort = {
|
|
72
|
-
[key: string]: 'ascend' | 'descend' | null,
|
|
73
|
-
};
|
|
74
|
-
export type TSearchableColumn = {
|
|
75
|
-
field: string | string[],
|
|
76
|
-
searchField?: string | null,
|
|
77
|
-
operator: typeof Operators[keyof typeof Operators],
|
|
78
|
-
filterField?: string,
|
|
79
|
-
filterOperator?: typeof Operators[keyof typeof Operators],
|
|
80
|
-
numeric?: boolean,
|
|
81
|
-
uuid?: boolean,
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
interface BaseProps<Entity,
|
|
85
|
-
CreateDto,
|
|
86
|
-
UpdateDto,
|
|
87
|
-
TEntityParams = {},
|
|
88
|
-
TPathParams = {}> extends ProTableProps<Entity, TEntityParams & TFilterParams> {
|
|
89
|
-
getAll: ({}: TGetAllParams & TPathParams) => Promise<{ data: Entity[] }>;
|
|
90
|
-
pathParams: TPathParams;
|
|
91
|
-
idColumnName?: string & keyof Entity | (string & keyof Entity)[];
|
|
92
|
-
createNewDefaultParams?: Partial<Entity>;
|
|
93
|
-
editableRecord?: Partial<Entity>;
|
|
94
|
-
defaultSort?: QuerySortArr;
|
|
95
|
-
searchableColumns?: TSearchableColumn[];
|
|
96
|
-
viewOnly?: boolean;
|
|
97
|
-
columnsSets?: TColumnsSet<Entity>[];
|
|
98
|
-
popupCreation?: boolean;
|
|
99
|
-
columnsState?: ColumnStateType;
|
|
100
|
-
columnsSetSelect?: () => React.ReactNode;
|
|
101
|
-
editPopupTitle?: string;
|
|
102
|
-
createPopupTitle?: string;
|
|
103
|
-
descriptionsMainTitle?: ProColumns<Entity>['title'] | null;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export interface EditableProps<Entity, CreateDto, UpdateDto, TPathParams = {}, ImportRequestParams = {}> {
|
|
107
|
-
actionRef?: MutableRefObject<ActionType | undefined>;
|
|
108
|
-
editable?: RowEditableConfig<Entity>;
|
|
109
|
-
afterSave?: (record: Entity) => Promise<void>;
|
|
110
|
-
onCreate?: ({}: { requestBody: CreateDto } & TPathParams) => Promise<Entity>;
|
|
111
|
-
exportUrl?: string;
|
|
112
|
-
exportParams?: {
|
|
113
|
-
[key: string]: string | number
|
|
114
|
-
};
|
|
115
|
-
onUpdate: ({}: Partial<Entity> & {
|
|
116
|
-
requestBody: UpdateDto,
|
|
117
|
-
index?: number,
|
|
118
|
-
} & TPathParams) => Promise<Entity>;
|
|
119
|
-
onDelete: ({}: Partial<Entity> & TPathParams) => Promise<void>;
|
|
120
|
-
entityToCreateDto: (entity: Entity) => CreateDto;
|
|
121
|
-
entityToUpdateDto: (entity: Entity) => UpdateDto;
|
|
122
|
-
onUpdateMany: ({}: Partial<Entity> & {
|
|
123
|
-
requestBody: { updateValues: Partial<UpdateDto>[], records: Entity[] }
|
|
124
|
-
} & TPathParams) => Promise<void>,
|
|
125
|
-
onDeleteMany: ({}: Partial<Entity> & { requestBody: { records: Entity[] } } & TPathParams) => Promise<void>,
|
|
126
|
-
importConfig?: {
|
|
127
|
-
onImport?: (params: ImportRequestParams) => Promise<TImportResponse>;
|
|
128
|
-
relationalFields?: TRelationalFields,
|
|
129
|
-
changedRecordsColumnsConfig: ProColumns<Entity>[],
|
|
130
|
-
createdRecordsColumnsConfig: ProColumns<Entity>[],
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Conditional type to merge base and editable props conditionally
|
|
135
|
-
type ConditionalProps<Entity,
|
|
136
|
-
CreateDto,
|
|
137
|
-
UpdateDto,
|
|
138
|
-
TEntityParams,
|
|
139
|
-
TPathParams> = { viewOnly: true } extends { viewOnly: boolean }
|
|
140
|
-
? BaseProps<Entity, CreateDto, UpdateDto, TEntityParams, TPathParams> & Partial<EditableProps<Entity, CreateDto, UpdateDto, TPathParams>>
|
|
141
|
-
: BaseProps<Entity, CreateDto, UpdateDto, TEntityParams, TPathParams> & EditableProps<Entity, CreateDto, UpdateDto, TPathParams>;
|
|
142
|
-
|
|
143
|
-
// Main type
|
|
144
|
-
export type TTableProps<Entity,
|
|
145
|
-
CreateDto,
|
|
146
|
-
UpdateDto,
|
|
147
|
-
TEntityParams = {},
|
|
148
|
-
TPathParams = {}> = ConditionalProps<Entity, CreateDto, UpdateDto, TEntityParams, TPathParams>
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { message, Popover, Space } from "antd";
|
|
2
|
-
import { QuestionCircleTwoTone } from "@ant-design/icons";
|
|
3
|
-
import _ from "lodash";
|
|
4
|
-
import BulkEditButton from "./BulkEditButton";
|
|
5
|
-
import { ActionType, ProTableProps } from "@ant-design/pro-table";
|
|
6
|
-
import BulkDeleteButton from "./BulkDeleteButton";
|
|
7
|
-
import { MutableRefObject, useState } from "react";
|
|
8
|
-
import { TGetAllParams } from "./tableTypes";
|
|
9
|
-
|
|
10
|
-
export function useBulkEditing<Entity, TPathParams, UpdateDto, U>({
|
|
11
|
-
actionRef,
|
|
12
|
-
columns,
|
|
13
|
-
idColumnName,
|
|
14
|
-
onDeleteMany,
|
|
15
|
-
onUpdateMany,
|
|
16
|
-
entityToUpdateDto,
|
|
17
|
-
pathParams,
|
|
18
|
-
}: {
|
|
19
|
-
actionRef?: MutableRefObject<ActionType | undefined>;
|
|
20
|
-
columns: ProTableProps<Entity, U>['columns'],
|
|
21
|
-
idColumnName?: string & keyof Entity | (string & keyof Entity)[];
|
|
22
|
-
onDeleteMany: ({}: Partial<Entity> & {
|
|
23
|
-
requestBody: { records: Entity[] }
|
|
24
|
-
} & TPathParams) => Promise<void>,
|
|
25
|
-
onUpdateMany: ({}: Partial<Entity> & {
|
|
26
|
-
requestBody: { updateValues: Partial<UpdateDto>[], records: Entity[] }
|
|
27
|
-
} & TPathParams) => Promise<void>,
|
|
28
|
-
entityToUpdateDto: (entity: Entity) => UpdateDto;
|
|
29
|
-
pathParams: TPathParams,
|
|
30
|
-
}) {
|
|
31
|
-
const [allSelected, setAllSelected] = useState(false);
|
|
32
|
-
const [selectedRecords, setSelectedRecords] = useState<Entity[]>([]);
|
|
33
|
-
const [lastRequest, setLastRequest] = useState<[TGetAllParams & TPathParams, any] | []>([]);
|
|
34
|
-
const [messageApi, contextHolder] = message.useMessage();
|
|
35
|
-
|
|
36
|
-
const bulkEditButton = <BulkEditButton<Entity, TPathParams>
|
|
37
|
-
selectedRecords={selectedRecords}
|
|
38
|
-
lastRequest={lastRequest}
|
|
39
|
-
allSelected={allSelected}
|
|
40
|
-
columns={columns}
|
|
41
|
-
idColumnName={idColumnName}
|
|
42
|
-
// @ts-ignore
|
|
43
|
-
onSubmit={values => onUpdateMany({
|
|
44
|
-
...pathParams,
|
|
45
|
-
...lastRequest[0],
|
|
46
|
-
requestBody: {
|
|
47
|
-
updateValues: _.pickBy(
|
|
48
|
-
// @ts-ignore
|
|
49
|
-
entityToUpdateDto({
|
|
50
|
-
...pathParams,
|
|
51
|
-
...values,
|
|
52
|
-
}),
|
|
53
|
-
(value, key) => _.has(values, key),
|
|
54
|
-
),
|
|
55
|
-
records: allSelected ? [] : selectedRecords,
|
|
56
|
-
},
|
|
57
|
-
}).then(() => {
|
|
58
|
-
messageApi.open({
|
|
59
|
-
type: 'success',
|
|
60
|
-
content: 'Operation Successful',
|
|
61
|
-
});
|
|
62
|
-
actionRef?.current?.reload();
|
|
63
|
-
})}
|
|
64
|
-
/>;
|
|
65
|
-
|
|
66
|
-
const bulkDeleteButton = <BulkDeleteButton<Entity, TPathParams>
|
|
67
|
-
selectedRecords={selectedRecords}
|
|
68
|
-
lastRequest={lastRequest}
|
|
69
|
-
allSelected={allSelected}
|
|
70
|
-
// @ts-ignore
|
|
71
|
-
onDelete={() => onDeleteMany({
|
|
72
|
-
...pathParams,
|
|
73
|
-
...lastRequest[0],
|
|
74
|
-
requestBody: {
|
|
75
|
-
records: allSelected ? [] : selectedRecords,
|
|
76
|
-
},
|
|
77
|
-
}).then(() => {
|
|
78
|
-
messageApi.open({
|
|
79
|
-
type: 'success',
|
|
80
|
-
content: 'Operation Successful',
|
|
81
|
-
});
|
|
82
|
-
actionRef?.current?.reload();
|
|
83
|
-
})}
|
|
84
|
-
/>;
|
|
85
|
-
|
|
86
|
-
const rowSelection: ProTableProps<Entity, U>['rowSelection'] = {
|
|
87
|
-
selectedRowKeys: selectedRecords.map(record => Array.isArray(idColumnName) ? idColumnName.map(colName => record[colName]).join('-') : record[idColumnName!]) as React.Key[],
|
|
88
|
-
selections: [
|
|
89
|
-
{
|
|
90
|
-
key: 'all',
|
|
91
|
-
text: (
|
|
92
|
-
<Space>
|
|
93
|
-
Select ALL
|
|
94
|
-
<Popover
|
|
95
|
-
content={(
|
|
96
|
-
<div style={{ width: '100%' }}>
|
|
97
|
-
This includes records from ALL pages of the table.
|
|
98
|
-
</div>
|
|
99
|
-
)}
|
|
100
|
-
title={'Select All'}
|
|
101
|
-
trigger={['hover', 'click']}
|
|
102
|
-
zIndex={1080}
|
|
103
|
-
>
|
|
104
|
-
<QuestionCircleTwoTone />
|
|
105
|
-
</Popover>
|
|
106
|
-
</Space>
|
|
107
|
-
),
|
|
108
|
-
onSelect: () => {
|
|
109
|
-
setSelectedRecords(lastRequest[1].data);
|
|
110
|
-
setAllSelected(true);
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
],
|
|
114
|
-
onChange: (rowKeys, records) => {
|
|
115
|
-
setSelectedRecords(records);
|
|
116
|
-
allSelected && setAllSelected(false);
|
|
117
|
-
},
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
return {
|
|
121
|
-
rowSelection,
|
|
122
|
-
setSelectedRecords,
|
|
123
|
-
setLastRequest,
|
|
124
|
-
messagesContext: contextHolder,
|
|
125
|
-
bulkEditButton,
|
|
126
|
-
bulkDeleteButton,
|
|
127
|
-
}
|
|
128
|
-
}
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { ColumnsState, ProColumns } from "@ant-design/pro-components";
|
|
2
|
-
import React, { useMemo, useState } from "react";
|
|
3
|
-
import { Select } from "antd";
|
|
4
|
-
import { ColumnStateType } from "@ant-design/pro-table/es/typing";
|
|
5
|
-
import { TIndexableRecord } from "./tableTools";
|
|
6
|
-
import QuestionMarkHint from "../QuestionMarkHint/QuestionMarkHint";
|
|
7
|
-
import { SettingOutlined } from "@ant-design/icons";
|
|
8
|
-
|
|
9
|
-
export type TColumnsSet<Entity> = {
|
|
10
|
-
name: string,
|
|
11
|
-
columns: (keyof Entity)[],
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
type TUseColumnsSetsParams<Entity> = {
|
|
15
|
-
columns: ProColumns<Entity>[],
|
|
16
|
-
columnsSets?: TColumnsSet<Entity>[],
|
|
17
|
-
defaultColumnState?: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export type TColumnsStates = Record<string, ColumnsState>;
|
|
21
|
-
|
|
22
|
-
type TUseColumnsSetsResult<Entity> = {
|
|
23
|
-
columnsSetSelect: () => React.ReactNode,
|
|
24
|
-
chosenColumnsSet: TColumnsStates | undefined,
|
|
25
|
-
setChosenColumnsSet: React.Dispatch<React.SetStateAction<TColumnsStates | undefined>>,
|
|
26
|
-
setChosenColumnsSetByName: (value: string) => void,
|
|
27
|
-
columnsState: ColumnStateType,
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
type TColumnsState = Partial<Record<string, ColumnsState>>;
|
|
31
|
-
|
|
32
|
-
function getColumnsStates<T>(
|
|
33
|
-
columns: TIndexableRecord[],
|
|
34
|
-
shownCols: Set<keyof T>,
|
|
35
|
-
state: TColumnsState = {},
|
|
36
|
-
): {state: Record<string, ColumnsState>, someColumnsShown: boolean} {
|
|
37
|
-
let someColumnsShown = false;
|
|
38
|
-
columns.forEach(col => {
|
|
39
|
-
const idx = Array.isArray(col.dataIndex) ? col.dataIndex.join(',') : col.dataIndex;
|
|
40
|
-
let childrenColumnsShown = false;
|
|
41
|
-
if ('children' in col && Array.isArray(col.children)) {
|
|
42
|
-
const { someColumnsShown } = getColumnsStates(col.children, shownCols, state);
|
|
43
|
-
if (someColumnsShown) {
|
|
44
|
-
childrenColumnsShown = true;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (idx) {
|
|
49
|
-
if (shownCols.has(idx as keyof T) || childrenColumnsShown) {
|
|
50
|
-
someColumnsShown = true;
|
|
51
|
-
} else {
|
|
52
|
-
state[idx as string] = { show: false };
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}, state);
|
|
56
|
-
|
|
57
|
-
return { state, someColumnsShown };
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export default function useColumnsSets<Entity>({
|
|
61
|
-
columns,
|
|
62
|
-
columnsSets,
|
|
63
|
-
defaultColumnState,
|
|
64
|
-
}: TUseColumnsSetsParams<Entity>): TUseColumnsSetsResult<Entity> {
|
|
65
|
-
const columnsSetsByName: Map<string, TColumnsStates> = useMemo(
|
|
66
|
-
() => new Map<string, TColumnsStates>(
|
|
67
|
-
columnsSets?.map(({
|
|
68
|
-
name,
|
|
69
|
-
columns: columnsSet
|
|
70
|
-
}) => [
|
|
71
|
-
name,
|
|
72
|
-
getColumnsStates<Entity>(columns as TIndexableRecord[], new Set(columnsSet)).state,
|
|
73
|
-
])
|
|
74
|
-
), [columns]
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
const [chosenSetName, setChosenSetName] = useState<string | undefined>(
|
|
78
|
-
defaultColumnState || columnsSets?.[0].name || undefined
|
|
79
|
-
);
|
|
80
|
-
const [chosenColumnsSet, setChosenColumnsSet] = useState<TColumnsStates | undefined>(
|
|
81
|
-
columnsSetsByName.get(chosenSetName || '') || undefined
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
const setChosenColumnsSetByName = (value: string) => {
|
|
85
|
-
setChosenSetName(value);
|
|
86
|
-
setChosenColumnsSet(columnsSetsByName.get(value));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const options = Array.from(columnsSetsByName.keys()).map(name => ({
|
|
90
|
-
value: name,
|
|
91
|
-
label: name,
|
|
92
|
-
}));
|
|
93
|
-
|
|
94
|
-
const columnsSetSelect = () => columnsSetsByName.size > 1 ? <>
|
|
95
|
-
<Select
|
|
96
|
-
key="columnsSetSelect"
|
|
97
|
-
style={{ width: 200 }}
|
|
98
|
-
value={chosenSetName}
|
|
99
|
-
onChange={(value: string) => setChosenColumnsSetByName(value)}
|
|
100
|
-
options={options}
|
|
101
|
-
/>
|
|
102
|
-
<QuestionMarkHint intlPrefix={'tables.columnsSetSelect'} values={{
|
|
103
|
-
gearIcon: <SettingOutlined />,
|
|
104
|
-
}} />
|
|
105
|
-
</> : null;
|
|
106
|
-
|
|
107
|
-
const columnsState = {
|
|
108
|
-
value: chosenColumnsSet,
|
|
109
|
-
// value contains only hidden columns and one which is just changed
|
|
110
|
-
onChange: (value: TColumnsStates) => {
|
|
111
|
-
const checkParentVisibility = (columns: TIndexableRecord[]) => {
|
|
112
|
-
let someColumnsShown = false;
|
|
113
|
-
|
|
114
|
-
columns.forEach(col => {
|
|
115
|
-
const idx = Array.isArray(col.dataIndex) ? col.dataIndex.join(',') : col.dataIndex as string;
|
|
116
|
-
if (idx && value[idx]?.show) {
|
|
117
|
-
someColumnsShown = true;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if ('children' in col && Array.isArray(col.children)) {
|
|
121
|
-
const someChildColumnsShown = checkParentVisibility(col.children);
|
|
122
|
-
if (someChildColumnsShown) {
|
|
123
|
-
value[idx] = { show: true };
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
return someColumnsShown;
|
|
129
|
-
};
|
|
130
|
-
checkParentVisibility(columns as TIndexableRecord[]);
|
|
131
|
-
setChosenColumnsSet(value);
|
|
132
|
-
},
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
return {
|
|
136
|
-
columnsSetSelect,
|
|
137
|
-
chosenColumnsSet,
|
|
138
|
-
setChosenColumnsSet,
|
|
139
|
-
setChosenColumnsSetByName,
|
|
140
|
-
columnsState,
|
|
141
|
-
}
|
|
142
|
-
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { MutableRefObject, useState } from 'react';
|
|
2
|
-
import { Button } from 'antd';
|
|
3
|
-
import { ActionType } from "@ant-design/pro-table";
|
|
4
|
-
import { PlusOutlined } from "@ant-design/icons";
|
|
5
|
-
import { FormattedMessage } from "react-intl";
|
|
6
|
-
import type { SizeType } from "antd/es/config-provider/SizeContext";
|
|
7
|
-
import { CreateEntityModal, CreateEntityModalProps } from "./CreateEntityModal";
|
|
8
|
-
import { DescriptionsRefType } from "../Descriptions";
|
|
9
|
-
import { ApiError } from '../../tools'
|
|
10
|
-
|
|
11
|
-
let creatingRecordsCount = 0;
|
|
12
|
-
export const KEY_SYMBOL = Symbol('key');
|
|
13
|
-
const NEW_RECORD = 'NEW_RECORD';
|
|
14
|
-
|
|
15
|
-
export function getNewId(): string {
|
|
16
|
-
return NEW_RECORD + creatingRecordsCount++;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function isRecordNew(record: Record<string | symbol, any>): boolean {
|
|
20
|
-
return record[KEY_SYMBOL]?.startsWith?.(NEW_RECORD) || record.id?.startsWith?.(NEW_RECORD) || false;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function useCreation<Entity, CreateDto, TPathParams = {}>({
|
|
24
|
-
title,
|
|
25
|
-
mainTitle,
|
|
26
|
-
columns,
|
|
27
|
-
idColumnName,
|
|
28
|
-
onCreate,
|
|
29
|
-
pathParams,
|
|
30
|
-
entityToCreateDto,
|
|
31
|
-
actionRef,
|
|
32
|
-
createButtonSize,
|
|
33
|
-
popupCreation,
|
|
34
|
-
createNewDefaultParams,
|
|
35
|
-
}: {
|
|
36
|
-
actionRef?: MutableRefObject<ActionType | undefined>;
|
|
37
|
-
pathParams: TPathParams;
|
|
38
|
-
entityToCreateDto: (entity: Entity) => CreateDto;
|
|
39
|
-
onCreate?: ({}: { requestBody: CreateDto } & TPathParams) => Promise<Entity>;
|
|
40
|
-
createButtonSize: SizeType;
|
|
41
|
-
popupCreation?: boolean;
|
|
42
|
-
createNewDefaultParams?: Partial<Entity>;
|
|
43
|
-
} & Omit<CreateEntityModalProps<Entity>, 'onSubmit' | 'onCancel' | 'entity'>) {
|
|
44
|
-
const [createPopupData, setCreatePopupData] = useState<Partial<Entity> | undefined>();
|
|
45
|
-
|
|
46
|
-
const onCreateSubmit = async (data: Entity, descriptionsRef: MutableRefObject<DescriptionsRefType<Entity>>) => {
|
|
47
|
-
try {
|
|
48
|
-
await onCreate?.({
|
|
49
|
-
...pathParams,
|
|
50
|
-
requestBody: entityToCreateDto({
|
|
51
|
-
...pathParams,
|
|
52
|
-
...data,
|
|
53
|
-
})
|
|
54
|
-
});
|
|
55
|
-
setCreatePopupData(undefined);
|
|
56
|
-
await actionRef?.current?.reload();
|
|
57
|
-
} catch (e: any) {
|
|
58
|
-
console.error(e);
|
|
59
|
-
|
|
60
|
-
// Handle common error
|
|
61
|
-
if (e.body && e.body.statusCode && e.body.errors) {
|
|
62
|
-
const error = e as ApiError;
|
|
63
|
-
const { statusCode, errors } = error.body;
|
|
64
|
-
// Validation error. Highlight corresponding form fields
|
|
65
|
-
if (statusCode === 400) {
|
|
66
|
-
const formErrors = errors.map(error => ({
|
|
67
|
-
name: error.field,
|
|
68
|
-
errors: [error.message],
|
|
69
|
-
}));
|
|
70
|
-
|
|
71
|
-
// @ts-ignore
|
|
72
|
-
descriptionsRef.current.setFieldErrors(formErrors);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const createButton = <Button
|
|
79
|
-
size={createButtonSize}
|
|
80
|
-
type="primary"
|
|
81
|
-
key="create"
|
|
82
|
-
onClick={() => {
|
|
83
|
-
if (popupCreation) {
|
|
84
|
-
setCreatePopupData(createNewDefaultParams);
|
|
85
|
-
} else {
|
|
86
|
-
actionRef?.current?.addEditRecord({
|
|
87
|
-
[KEY_SYMBOL]: getNewId(),
|
|
88
|
-
...createNewDefaultParams,
|
|
89
|
-
}, {
|
|
90
|
-
position: 'top',
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
}}
|
|
94
|
-
>
|
|
95
|
-
<PlusOutlined /> <FormattedMessage id={'table.newButton'} />
|
|
96
|
-
</Button>;
|
|
97
|
-
|
|
98
|
-
const modal = <CreateEntityModal<Entity, CreateDto, Entity, TPathParams>
|
|
99
|
-
entity={createPopupData}
|
|
100
|
-
title={title}
|
|
101
|
-
mainTitle={mainTitle}
|
|
102
|
-
columns={columns}
|
|
103
|
-
idColumnName={idColumnName}
|
|
104
|
-
onCancel={() => {
|
|
105
|
-
setCreatePopupData(undefined);
|
|
106
|
-
}}
|
|
107
|
-
onSubmit={onCreateSubmit}
|
|
108
|
-
/>;
|
|
109
|
-
|
|
110
|
-
return {
|
|
111
|
-
creationModal: modal,
|
|
112
|
-
createButton,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { EditableProps } from "./tableTypes";
|
|
2
|
-
import type { RowEditableConfig } from "@ant-design/pro-utils";
|
|
3
|
-
import { flushSync } from "react-dom";
|
|
4
|
-
import { Button, Tooltip } from "antd";
|
|
5
|
-
import { DeleteOutlined, StopOutlined } from "@ant-design/icons";
|
|
6
|
-
import { FormattedMessage, useIntl } from "react-intl";
|
|
7
|
-
import React, { useState } from "react";
|
|
8
|
-
import { isRecordNew } from "./useCreation";
|
|
9
|
-
|
|
10
|
-
export function useEditableTable<Entity, CreateDto, UpdateDto, TPathParams = {}>(
|
|
11
|
-
{
|
|
12
|
-
actionRef,
|
|
13
|
-
pathParams,
|
|
14
|
-
onCreate,
|
|
15
|
-
onUpdate,
|
|
16
|
-
onDelete,
|
|
17
|
-
entityToCreateDto,
|
|
18
|
-
entityToUpdateDto,
|
|
19
|
-
afterSave,
|
|
20
|
-
editable,
|
|
21
|
-
}: {
|
|
22
|
-
pathParams: TPathParams,
|
|
23
|
-
} & EditableProps<Entity, CreateDto, UpdateDto, TPathParams>
|
|
24
|
-
) {
|
|
25
|
-
const [editableKeys, setEditableRowKeys] = useState<React.Key[]>([]);
|
|
26
|
-
const intl = useIntl();
|
|
27
|
-
|
|
28
|
-
const editableConfig: RowEditableConfig<Entity> = {
|
|
29
|
-
type: 'multiple',
|
|
30
|
-
editableKeys,
|
|
31
|
-
onChange: setEditableRowKeys,
|
|
32
|
-
async onSave(
|
|
33
|
-
id,
|
|
34
|
-
record,
|
|
35
|
-
origin,
|
|
36
|
-
newLine,
|
|
37
|
-
) {
|
|
38
|
-
if (newLine) {
|
|
39
|
-
await onCreate?.({
|
|
40
|
-
...pathParams,
|
|
41
|
-
requestBody: entityToCreateDto(record),
|
|
42
|
-
});
|
|
43
|
-
} else {
|
|
44
|
-
await onUpdate({
|
|
45
|
-
...pathParams,
|
|
46
|
-
...record,
|
|
47
|
-
requestBody: entityToUpdateDto({
|
|
48
|
-
...pathParams,
|
|
49
|
-
...record,
|
|
50
|
-
}),
|
|
51
|
-
})
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (typeof afterSave === 'function') {
|
|
55
|
-
await afterSave(record);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
flushSync(() => {
|
|
59
|
-
actionRef?.current?.reload();
|
|
60
|
-
});
|
|
61
|
-
},
|
|
62
|
-
async onCancel(
|
|
63
|
-
id,
|
|
64
|
-
record,
|
|
65
|
-
origin,
|
|
66
|
-
) {
|
|
67
|
-
if (record) {
|
|
68
|
-
Object.assign(record, origin);
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
async onDelete(id, row) {
|
|
72
|
-
if (isRecordNew(row)) return;
|
|
73
|
-
await onDelete({ ...row, ...pathParams });
|
|
74
|
-
},
|
|
75
|
-
deletePopconfirmMessage: intl.formatMessage({ id: 'table.deletePopconfirmMessage' }),
|
|
76
|
-
onlyAddOneLineAlertMessage: intl.formatMessage({ id: 'table.onlyAddOneLineAlertMessage' }),
|
|
77
|
-
cancelText: <Tooltip title={intl.formatMessage({ id: 'table.cancelText' })}><StopOutlined /></Tooltip>,
|
|
78
|
-
deleteText: <Tooltip title={intl.formatMessage({ id: 'table.deleteText' })}><DeleteOutlined /></Tooltip>,
|
|
79
|
-
saveText: <Button size={"small"} type={"primary"}><FormattedMessage id={'table.saveText'} /></Button>,
|
|
80
|
-
...editable,
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return {
|
|
84
|
-
editableConfig,
|
|
85
|
-
};
|
|
86
|
-
}
|