datastake-daf 0.6.811 → 0.6.813
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/components/index.js +1509 -379
- package/dist/hooks/index.js +11 -4
- package/dist/pages/index.js +138 -16
- package/dist/services/index.js +56 -6
- package/dist/utils/index.js +28 -5
- package/package.json +1 -1
- package/src/@daf/core/components/AuthForm/index.jsx +12 -3
- package/src/@daf/core/components/Dashboard/Widget/FaunaWidget/index.jsx +1 -2
- package/src/@daf/core/components/Screens/Admin/AdminDashboard/components/UserStatistics/TopContributors/index.jsx +0 -1
- package/src/@daf/core/components/Screens/Admin/AdminDashboard/components/UserStatistics/UserGrowth/hook.js +0 -1
- package/src/@daf/core/components/Screens/Admin/AdminDashboard/components/UserStatistics/UserGrowth/index.jsx +1 -3
- package/src/@daf/core/components/Screens/Admin/AdminModals/CombineLocation/index.jsx +51 -51
- package/src/@daf/core/components/Screens/Admin/AdminModals/CombineSubjects/index.jsx +6 -1
- package/src/@daf/core/components/Screens/Admin/AdminModals/NewAccount/index.jsx +56 -31
- package/src/@daf/core/components/Screens/Admin/AdminModals/NewUser/index.jsx +36 -10
- package/src/@daf/core/components/Screens/Admin/AdminModals/TransferRights/index.jsx +1 -1
- package/src/@daf/core/components/Screens/Admin/AdminScreens/Accounts.jsx +37 -10
- package/src/@daf/core/components/Screens/Admin/AdminScreens/Dashboard.jsx +2 -2
- package/src/@daf/core/components/Screens/Admin/AdminScreens/Documents.jsx +81 -0
- package/src/@daf/core/components/Screens/Admin/AdminScreens/Events.jsx +77 -0
- package/src/@daf/core/components/Screens/Admin/AdminScreens/index.js +2 -0
- package/src/@daf/core/components/Screens/Admin/AdminTables/AccountTable/helper.js +22 -30
- package/src/@daf/core/components/Screens/Admin/AdminTables/AccountTable/index.jsx +25 -13
- package/src/@daf/core/components/Screens/Admin/AdminTables/DocumentsTable/column.js +127 -0
- package/src/@daf/core/components/Screens/Admin/AdminTables/DocumentsTable/helper.js +43 -0
- package/src/@daf/core/components/Screens/Admin/AdminTables/DocumentsTable/index.jsx +201 -0
- package/src/@daf/core/components/Screens/Admin/AdminTables/EventsTable/column.js +146 -0
- package/src/@daf/core/components/Screens/Admin/AdminTables/EventsTable/helper.js +58 -0
- package/src/@daf/core/components/Screens/Admin/AdminTables/EventsTable/index.jsx +176 -0
- package/src/@daf/core/components/Screens/Admin/AdminTables/LocationTable/index.jsx +17 -2
- package/src/@daf/core/components/Screens/Admin/AdminTables/SubjectsTable/index.jsx +27 -13
- package/src/@daf/core/components/Screens/Admin/AdminTables/UserTable/index.jsx +0 -1
- package/src/@daf/core/components/Screens/Admin/AdminTables/components/index.jsx +4 -2
- package/src/@daf/core/components/Screens/Admin/AdminTables/hook.js +3 -0
- package/src/@daf/core/components/Screens/Admin/AdminViews/components/Edit/index.jsx +12 -9
- package/src/@daf/core/components/Screens/Admin/AdminViews/components/Users/index.jsx +16 -4
- package/src/@daf/core/components/Screens/Admin/AdminViews/components/View/helpers.js +9 -17
- package/src/@daf/core/components/Screens/Admin/AdminViews/index.jsx +9 -8
- package/src/@daf/core/components/Screens/Admin/AppInvitation/index.jsx +124 -99
- package/src/@daf/core/components/Screens/Admin/adminRoutes.js +48 -1
- package/src/@daf/hooks/useAdminDashboard.js +7 -4
- package/src/@daf/pages/Summary/Activities/Monitoring/components/BiodiversityAndHabitat/index.jsx +2 -2
- package/src/@daf/pages/Summary/Activities/Monitoring/helper.js +24 -0
- package/src/@daf/pages/View/hooks/useViewActions.js +13 -0
- package/src/@daf/pages/View/hooks/useViewPermissions.js +16 -0
- package/src/@daf/pages/View/index.jsx +29 -4
- package/src/@daf/services/AdminService.js +47 -5
- package/src/@daf/services/DashboardService.js +3 -3
- package/src/@daf/utils/filters.js +13 -15
- package/src/constants/locales/en/translation.js +13 -0
- package/src/helpers/copyToClipboard.js +60 -0
- package/build/favicon.ico +0 -0
- package/build/logo192.png +0 -0
- package/build/logo512.png +0 -0
- package/build/manifest.json +0 -25
- package/build/robots.txt +0 -3
- package/dist/style/datastake/mapbox-gl.css +0 -330
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export const getTabs = ({ t }) => {
|
|
2
|
+
return [
|
|
3
|
+
{
|
|
4
|
+
key: "active",
|
|
5
|
+
label: t("Active"),
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
key: "pending",
|
|
9
|
+
label: t("Pending"),
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
key: 'suspended',
|
|
13
|
+
label: t("Suspended"),
|
|
14
|
+
}
|
|
15
|
+
];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const selectFiltersConfig = {
|
|
19
|
+
category: {
|
|
20
|
+
type: "select",
|
|
21
|
+
label: "Category",
|
|
22
|
+
placeholder: (t) => t("Category"),
|
|
23
|
+
style: { flex: 1 },
|
|
24
|
+
labelStyle: { flex: 1 },
|
|
25
|
+
getLabel: (option) => option.label,
|
|
26
|
+
getValue: (option) => option.value,
|
|
27
|
+
},
|
|
28
|
+
country: {
|
|
29
|
+
type: "select",
|
|
30
|
+
label: "Country",
|
|
31
|
+
placeholder: (t) => t("Country"),
|
|
32
|
+
style: { flex: 1 },
|
|
33
|
+
labelStyle: { flex: 1 },
|
|
34
|
+
getLabel: (option) => option.label,
|
|
35
|
+
getValue: (option) => option.value,
|
|
36
|
+
},
|
|
37
|
+
sources: {
|
|
38
|
+
type: "select",
|
|
39
|
+
label: "Sources",
|
|
40
|
+
placeholder: (t) => t("Sources"),
|
|
41
|
+
style: { flex: 1 },
|
|
42
|
+
labelStyle: { flex: 1 },
|
|
43
|
+
getLabel: (option) => option.label,
|
|
44
|
+
getValue: (option) => option.value,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const filtersConfig = {
|
|
49
|
+
name: "",
|
|
50
|
+
datastakeId: "",
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const defaultUrlParams = { activeTab: "active" };
|
|
54
|
+
|
|
55
|
+
export const checkboxConfig = {
|
|
56
|
+
name: "Name",
|
|
57
|
+
datastakeId: "ID",
|
|
58
|
+
};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { useState, useMemo } from "react";
|
|
2
|
+
import { useAdminTable } from "../hook";
|
|
3
|
+
import AdminTable from "../components/index.jsx";
|
|
4
|
+
import DAFTable from "../../../../Table/index.jsx";
|
|
5
|
+
import { theme, Tag, message } from "antd";
|
|
6
|
+
import CustomIcon from "../../../../Icon/CustomIcon.jsx";
|
|
7
|
+
import {
|
|
8
|
+
getTabs,
|
|
9
|
+
selectFiltersConfig,
|
|
10
|
+
filtersConfig,
|
|
11
|
+
defaultUrlParams,
|
|
12
|
+
checkboxConfig,
|
|
13
|
+
} from "./helper.js";
|
|
14
|
+
import { getColumns } from "./column.js";
|
|
15
|
+
const { useToken } = theme;
|
|
16
|
+
|
|
17
|
+
export default function EventsTable({
|
|
18
|
+
t = (text) => text,
|
|
19
|
+
isMobile,
|
|
20
|
+
goTo,
|
|
21
|
+
getRedirectLink,
|
|
22
|
+
location,
|
|
23
|
+
getData,
|
|
24
|
+
module,
|
|
25
|
+
config,
|
|
26
|
+
defaultPageSize = 20,
|
|
27
|
+
view,
|
|
28
|
+
headerTitle,
|
|
29
|
+
breadcrumbs,
|
|
30
|
+
refetchTrigger,
|
|
31
|
+
user,
|
|
32
|
+
options,
|
|
33
|
+
}) {
|
|
34
|
+
const [showFilters, setShowFilters] = useState(false);
|
|
35
|
+
const [hasError, setHasError] = useState(false);
|
|
36
|
+
const [selectedEvents, setSelectedEvents] = useState([]);
|
|
37
|
+
const { token } = useToken();
|
|
38
|
+
|
|
39
|
+
const getDataWithStringPagination = async ({ params }) => {
|
|
40
|
+
const { pagination, tab, filters, search, sort, ...otherParams } = params;
|
|
41
|
+
|
|
42
|
+
// Don't send pagination to API - we'll fetch all data and slice on frontend
|
|
43
|
+
let activeTab = tab || "active";
|
|
44
|
+
if (!tab && filters) {
|
|
45
|
+
try {
|
|
46
|
+
const parsedFilters = typeof filters === 'string' ? JSON.parse(filters) : filters;
|
|
47
|
+
activeTab = parsedFilters.activeTab || "active";
|
|
48
|
+
} catch (e) {
|
|
49
|
+
activeTab = "active";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Fetch all data without pagination - we'll slice on frontend based on URL params
|
|
54
|
+
const transformedParams = {
|
|
55
|
+
tab: activeTab,
|
|
56
|
+
...otherParams,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return getData({ params: transformedParams });
|
|
60
|
+
};
|
|
61
|
+
const {
|
|
62
|
+
filter,
|
|
63
|
+
// activeTab,
|
|
64
|
+
canClearSearch,
|
|
65
|
+
totalPending,
|
|
66
|
+
data,
|
|
67
|
+
loading,
|
|
68
|
+
initFetchDone,
|
|
69
|
+
fetchData,
|
|
70
|
+
fetchPendingAccounts,
|
|
71
|
+
setLoading,
|
|
72
|
+
} = useAdminTable({
|
|
73
|
+
goTo,
|
|
74
|
+
location,
|
|
75
|
+
selectFiltersConfig,
|
|
76
|
+
view,
|
|
77
|
+
defaultUrlParams,
|
|
78
|
+
module,
|
|
79
|
+
defaultPageSize,
|
|
80
|
+
filtersConfig,
|
|
81
|
+
getRedirectLink,
|
|
82
|
+
getData: getDataWithStringPagination,
|
|
83
|
+
refetchTrigger,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const selectOptions = useMemo(() => {
|
|
87
|
+
return {
|
|
88
|
+
category: config.options?.category,
|
|
89
|
+
country: config.options?.countries,
|
|
90
|
+
sources: [],
|
|
91
|
+
};
|
|
92
|
+
}, [config.options]);
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
const columns = useMemo(() => {
|
|
97
|
+
return getColumns({
|
|
98
|
+
t,
|
|
99
|
+
goTo,
|
|
100
|
+
token,
|
|
101
|
+
module,
|
|
102
|
+
selectedEvents,
|
|
103
|
+
setSelectedEvents,
|
|
104
|
+
getRedirectLink,
|
|
105
|
+
selectOptions,
|
|
106
|
+
entity: headerTitle,
|
|
107
|
+
options,
|
|
108
|
+
});
|
|
109
|
+
}, [t, goTo, module, token, selectedEvents, getRedirectLink, selectOptions, headerTitle, options]);
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<>
|
|
113
|
+
<AdminTable
|
|
114
|
+
filters={filter}
|
|
115
|
+
t={t}
|
|
116
|
+
headerTitle={headerTitle}
|
|
117
|
+
// actionButton={[
|
|
118
|
+
// {
|
|
119
|
+
// icon: "Merge",
|
|
120
|
+
// onClick: () => setIsModalOpen(true),
|
|
121
|
+
// tooltip: t("merge-subjects"),
|
|
122
|
+
// disabled: selectedEvents.length < 2,
|
|
123
|
+
// },
|
|
124
|
+
// ]}
|
|
125
|
+
// tabs={getTabs({ t })}
|
|
126
|
+
isMobile={isMobile}
|
|
127
|
+
// activeTab={activeTab}
|
|
128
|
+
showFilters={showFilters}
|
|
129
|
+
setShowFilters={setShowFilters}
|
|
130
|
+
hasError={hasError}
|
|
131
|
+
setHasError={setHasError}
|
|
132
|
+
canClearSearch={canClearSearch}
|
|
133
|
+
selectOptions={selectOptions}
|
|
134
|
+
checkboxConfig={checkboxConfig}
|
|
135
|
+
defaultTableFilters={{}}
|
|
136
|
+
breadcrumbs={breadcrumbs}
|
|
137
|
+
>
|
|
138
|
+
{selectedEvents.length > 0 && (
|
|
139
|
+
<div className="flex flex-row ml-6 mt-5" style={{ flexWrap: "wrap", gap: "8px" }}>
|
|
140
|
+
{selectedEvents.map((event) => (
|
|
141
|
+
<Tag
|
|
142
|
+
key={event.id}
|
|
143
|
+
className="flex flex-row gap-2 items-center"
|
|
144
|
+
onClick={() =>
|
|
145
|
+
setSelectedEvents((prev) => prev.filter((a) => a.id !== event.id))
|
|
146
|
+
}
|
|
147
|
+
style={{ cursor: "pointer" }}
|
|
148
|
+
>
|
|
149
|
+
<span>{event.title}</span>
|
|
150
|
+
<CustomIcon name="Close" size={10} />
|
|
151
|
+
</Tag>
|
|
152
|
+
))}
|
|
153
|
+
</div>
|
|
154
|
+
)}
|
|
155
|
+
<DAFTable
|
|
156
|
+
columns={columns}
|
|
157
|
+
data={data}
|
|
158
|
+
loading={loading}
|
|
159
|
+
hideOnLoading={false}
|
|
160
|
+
pagination={filter.pagination}
|
|
161
|
+
rowKey="id"
|
|
162
|
+
selectOptions={selectOptions}
|
|
163
|
+
doEmptyRows
|
|
164
|
+
setShowFilters={setShowFilters}
|
|
165
|
+
filtersConfig={selectFiltersConfig}
|
|
166
|
+
onFilterChange={filter.onFiltersChange}
|
|
167
|
+
showFilters={showFilters}
|
|
168
|
+
defaultFilters={filter.defaultFilters}
|
|
169
|
+
onChange={filter.onTableChange}
|
|
170
|
+
/>
|
|
171
|
+
</AdminTable>
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
</>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
@@ -53,7 +53,22 @@ export default function LocationTable({
|
|
|
53
53
|
console.error('Failed to parse pagination', e);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
const pageSize = Number(paginationObj.pageSize) || Number(paginationObj.take) || 20;
|
|
59
|
+
|
|
60
|
+
let pageNumber = 1;
|
|
61
|
+
|
|
62
|
+
if (paginationObj.page || paginationObj.current) {
|
|
63
|
+
pageNumber = Number(paginationObj.page) || Number(paginationObj.current);
|
|
64
|
+
} else if (typeof paginationObj.skip === 'number') {
|
|
56
65
|
|
|
66
|
+
pageNumber = Math.floor(paginationObj.skip / pageSize) + 1;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
pageNumber = pageNumber || 1;
|
|
70
|
+
|
|
71
|
+
|
|
57
72
|
let activeTab = tab || "active";
|
|
58
73
|
if (!tab && filters) {
|
|
59
74
|
try {
|
|
@@ -66,8 +81,8 @@ export default function LocationTable({
|
|
|
66
81
|
|
|
67
82
|
const transformedParams = {
|
|
68
83
|
pagination: {
|
|
69
|
-
skip:
|
|
70
|
-
take:
|
|
84
|
+
skip: pageNumber,
|
|
85
|
+
take: pageSize,
|
|
71
86
|
},
|
|
72
87
|
tab: activeTab,
|
|
73
88
|
};
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
} from "./helper.js";
|
|
14
14
|
import { getColumns } from "./columns.js";
|
|
15
15
|
import CombineSubjectsModal from "../../AdminModals/CombineSubjects/index.jsx";
|
|
16
|
-
|
|
17
16
|
const { useToken } = theme;
|
|
18
17
|
|
|
19
18
|
export default function SubjectsTable({
|
|
@@ -40,10 +39,7 @@ export default function SubjectsTable({
|
|
|
40
39
|
const { token } = useToken();
|
|
41
40
|
const [isCombineModalOpen, setIsModalOpen] = useState(false);
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const getDataWithStringPagination = async ({ params }) => {
|
|
42
|
+
const getDataWithStringPagination = async ({ params }) => {
|
|
47
43
|
const { pagination, tab, filters, search, sort, ...otherParams } = params;
|
|
48
44
|
|
|
49
45
|
let paginationObj = { page: 1, pageSize: 20 };
|
|
@@ -54,7 +50,21 @@ const getDataWithStringPagination = async ({ params }) => {
|
|
|
54
50
|
console.error('Failed to parse pagination', e);
|
|
55
51
|
}
|
|
56
52
|
}
|
|
57
|
-
|
|
53
|
+
|
|
54
|
+
const pageSize = Number(paginationObj.pageSize) || Number(paginationObj.take) || 20;
|
|
55
|
+
|
|
56
|
+
let pageNumber = 1;
|
|
57
|
+
|
|
58
|
+
if (paginationObj.page || paginationObj.current) {
|
|
59
|
+
pageNumber = Number(paginationObj.page) || Number(paginationObj.current);
|
|
60
|
+
} else if (typeof paginationObj.skip === 'number') {
|
|
61
|
+
|
|
62
|
+
pageNumber = Math.floor(paginationObj.skip / pageSize) + 1;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
pageNumber = pageNumber || 1;
|
|
66
|
+
|
|
67
|
+
|
|
58
68
|
let activeTab = tab || "active";
|
|
59
69
|
if (!tab && filters) {
|
|
60
70
|
try {
|
|
@@ -67,14 +77,16 @@ const getDataWithStringPagination = async ({ params }) => {
|
|
|
67
77
|
|
|
68
78
|
const transformedParams = {
|
|
69
79
|
pagination: {
|
|
70
|
-
skip:
|
|
71
|
-
take:
|
|
80
|
+
skip: pageNumber,
|
|
81
|
+
take: pageSize,
|
|
72
82
|
},
|
|
73
83
|
tab: activeTab,
|
|
74
84
|
};
|
|
75
85
|
|
|
76
86
|
return getData({ params: transformedParams });
|
|
77
87
|
};
|
|
88
|
+
|
|
89
|
+
|
|
78
90
|
const {
|
|
79
91
|
filter,
|
|
80
92
|
activeTab,
|
|
@@ -133,7 +145,7 @@ const getDataWithStringPagination = async ({ params }) => {
|
|
|
133
145
|
{
|
|
134
146
|
icon: "Merge",
|
|
135
147
|
onClick: () => setIsModalOpen(true),
|
|
136
|
-
tooltip: t("
|
|
148
|
+
tooltip: t("merge-subjects"),
|
|
137
149
|
disabled: selectedSubjects.length < 2,
|
|
138
150
|
},
|
|
139
151
|
]}
|
|
@@ -192,11 +204,13 @@ const getDataWithStringPagination = async ({ params }) => {
|
|
|
192
204
|
onSuccess={(data) => {
|
|
193
205
|
setIsModalOpen(false);
|
|
194
206
|
setLoading(true);
|
|
195
|
-
message.success(t("Subjects successfully merged."))
|
|
196
207
|
if (typeof mergeSubjectsFunction === 'function') {
|
|
197
|
-
mergeSubjectsFunction(data).
|
|
208
|
+
mergeSubjectsFunction(data).then(() => {
|
|
209
|
+
setTimeout(() => {
|
|
210
|
+
fetchData();
|
|
211
|
+
}, 500);
|
|
212
|
+
}).finally(() => {
|
|
198
213
|
setSelectedSubjects([]);
|
|
199
|
-
fetchData();
|
|
200
214
|
});
|
|
201
215
|
}
|
|
202
216
|
}}
|
|
@@ -207,4 +221,4 @@ const getDataWithStringPagination = async ({ params }) => {
|
|
|
207
221
|
/>
|
|
208
222
|
</>
|
|
209
223
|
);
|
|
210
|
-
}
|
|
224
|
+
}
|
|
@@ -22,6 +22,8 @@ export default function AdminTable({
|
|
|
22
22
|
breadcrumbs,
|
|
23
23
|
children,
|
|
24
24
|
}) {
|
|
25
|
+
|
|
26
|
+
console.log(tabs, "tabs");
|
|
25
27
|
return (
|
|
26
28
|
<>
|
|
27
29
|
<div className="semibold form-input-output daf-create-view">
|
|
@@ -29,7 +31,7 @@ export default function AdminTable({
|
|
|
29
31
|
<div className="column start table-content">
|
|
30
32
|
<div className="mt-6 ml-6 mr-6">
|
|
31
33
|
<div className="flex flex-row">
|
|
32
|
-
<div className="mr-2">
|
|
34
|
+
{tabs && tabs.length > 0 && <div className="mr-2">
|
|
33
35
|
<Tabs
|
|
34
36
|
t={t}
|
|
35
37
|
tabs={tabs}
|
|
@@ -38,7 +40,7 @@ export default function AdminTable({
|
|
|
38
40
|
filters.setActiveFilters((p) => ({ ...p, activeTab: val }))
|
|
39
41
|
}
|
|
40
42
|
/>
|
|
41
|
-
</div>
|
|
43
|
+
</div>}
|
|
42
44
|
<div className="flex-1">
|
|
43
45
|
<SearchFilters
|
|
44
46
|
t={t}
|
|
@@ -32,6 +32,7 @@ export function useAdminTable({
|
|
|
32
32
|
defaultPageSize: defaultPageSize || 20,
|
|
33
33
|
getRedirectLink,
|
|
34
34
|
});
|
|
35
|
+
console.log(filter, "filter.activeFilters");
|
|
35
36
|
|
|
36
37
|
const activeTab = useMemo(() => filter.activeFilters.activeTab, [filter.activeFilters]);
|
|
37
38
|
|
|
@@ -59,12 +60,14 @@ export function useAdminTable({
|
|
|
59
60
|
fetchPendingAccounts();
|
|
60
61
|
}, []);
|
|
61
62
|
|
|
63
|
+
|
|
62
64
|
const fetchData = useCallback(async () => {
|
|
63
65
|
try {
|
|
64
66
|
setLoading(true);
|
|
65
67
|
const params = filterParams({
|
|
66
68
|
activeFilters: filter.activeFilters,
|
|
67
69
|
});
|
|
70
|
+
console.log(params, "params");
|
|
68
71
|
const { data } = await getData({ params });
|
|
69
72
|
setData(data.data || data);
|
|
70
73
|
filter.setPagination((prev) => ({ ...prev, total: data?.meta?.total || data?.length || 0 }));
|
|
@@ -3,7 +3,7 @@ import { ExclamationCircleOutlined } from "@ant-design/icons";
|
|
|
3
3
|
import { useCallback, useEffect } from "react";
|
|
4
4
|
import { useForms } from "../../../../../../context/Forms/index.js";
|
|
5
5
|
import Users from "../Users/index.jsx";
|
|
6
|
-
|
|
6
|
+
import AdminService from "../../../../../../../services/AdminService.js";
|
|
7
7
|
export default function Edit({
|
|
8
8
|
t,
|
|
9
9
|
goTo,
|
|
@@ -37,14 +37,17 @@ export default function Edit({
|
|
|
37
37
|
}, [isChanged, addCheck, removeCheck]);
|
|
38
38
|
|
|
39
39
|
const deleteUser = useCallback(
|
|
40
|
-
(id) => {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
async (id) => {
|
|
41
|
+
try {
|
|
42
|
+
await AdminService.removeUserFromAccount({ accountId: data.id, userId: id });
|
|
43
|
+
message.success(t("User removed successfully"));
|
|
44
|
+
fetchData();
|
|
45
|
+
} catch (err) {
|
|
46
|
+
handleError(err);
|
|
47
|
+
}
|
|
44
48
|
},
|
|
45
|
-
[fetchData],
|
|
49
|
+
[fetchData, data.id, t, handleError],
|
|
46
50
|
);
|
|
47
|
-
|
|
48
51
|
const updateUser = useCallback((id, val) => {
|
|
49
52
|
setIsChanged(true);
|
|
50
53
|
setData((prev) => ({
|
|
@@ -71,9 +74,9 @@ export default function Edit({
|
|
|
71
74
|
|
|
72
75
|
const onSuspend = () => {
|
|
73
76
|
Modal.confirm({
|
|
74
|
-
title: t("
|
|
77
|
+
title: t("Are-you-sure-you-want-to-suspend-this-account?"),
|
|
75
78
|
icon: <ExclamationCircleOutlined />,
|
|
76
|
-
content: t("
|
|
79
|
+
content: <span style={{ color: "#888" }}>{t("Associated-users-will-lose-access-to-the-application-and-to-all-data-created-for-this-account.")}</span>,
|
|
77
80
|
okText: t("Yes"),
|
|
78
81
|
cancelText: t("No"),
|
|
79
82
|
onOk: async () => {
|
|
@@ -34,6 +34,7 @@ export default function Users({
|
|
|
34
34
|
inviteCompanyAccount = () => {},
|
|
35
35
|
companyId,
|
|
36
36
|
handleError = () => {},
|
|
37
|
+
|
|
37
38
|
}) {
|
|
38
39
|
const [hasError, setHasError] = useState(false);
|
|
39
40
|
const [showFilters, setShowFilters] = useState(false);
|
|
@@ -72,9 +73,9 @@ export default function Users({
|
|
|
72
73
|
const onDeleteUserClick = useCallback(
|
|
73
74
|
(id) => {
|
|
74
75
|
Modal.confirm({
|
|
75
|
-
title: t("
|
|
76
|
+
title: t("Are-you-sure-you-want-to-remove-the-user-from-this-account?"),
|
|
76
77
|
icon: <ExclamationCircleOutlined />,
|
|
77
|
-
content: t("
|
|
78
|
+
content: <span style={{ color: "#888" }}>{t("The-user-will-lose-access-to-the-application-and-to-all-data-created-for-this-account.")}</span>,
|
|
78
79
|
okText: t("Yes"),
|
|
79
80
|
cancelText: t("No"),
|
|
80
81
|
onOk: () => {
|
|
@@ -87,8 +88,15 @@ export default function Users({
|
|
|
87
88
|
);
|
|
88
89
|
|
|
89
90
|
const data = useMemo(() => {
|
|
90
|
-
const { users = [] } = accountData;
|
|
91
|
-
let filtered = [
|
|
91
|
+
const { users = [], pendingUsers = [] } = accountData;
|
|
92
|
+
let filtered = [
|
|
93
|
+
...users,
|
|
94
|
+
...pendingUsers.map(u => ({
|
|
95
|
+
...u,
|
|
96
|
+
status: 'pending',
|
|
97
|
+
id: u.invitationToken || u.email // ensure pending users have an ID
|
|
98
|
+
}))
|
|
99
|
+
];
|
|
92
100
|
|
|
93
101
|
if (!isEmptyOrSpaces(activeFilters.search)) {
|
|
94
102
|
const search = activeFilters.search.toLowerCase();
|
|
@@ -186,6 +194,10 @@ export default function Users({
|
|
|
186
194
|
inviteCompanyAccount={inviteCompanyAccount}
|
|
187
195
|
companyId={companyId}
|
|
188
196
|
handleError={handleError}
|
|
197
|
+
existingEmails={[
|
|
198
|
+
...(accountData?.users || []).map(u => u.email?.toLowerCase()),
|
|
199
|
+
...(accountData?.pendingUsers || []).map(u => u.email?.toLowerCase()),
|
|
200
|
+
].filter(Boolean)}
|
|
189
201
|
/>
|
|
190
202
|
</div>
|
|
191
203
|
);
|
|
@@ -1,23 +1,15 @@
|
|
|
1
1
|
import { Tag } from "antd";
|
|
2
2
|
|
|
3
3
|
export const renderStatus = ({ val, t = (s) => s }) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// return <Tag color="red">{t("Suspended")}</Tag>;
|
|
12
|
-
// case "pending":
|
|
13
|
-
// return <Tag color="orange">{t("Pending")}</Tag>;
|
|
14
|
-
// default:
|
|
15
|
-
// return <Tag color="default">{t("Unknown")}</Tag>;
|
|
16
|
-
// }
|
|
17
|
-
|
|
18
|
-
if (val) {
|
|
4
|
+
if (val === 'pending') {
|
|
5
|
+
return <Tag color="orange">{t("Pending")}</Tag>;
|
|
6
|
+
}
|
|
7
|
+
if (val === 'unsaved') {
|
|
8
|
+
return <Tag color="red">{t("Unsaved")}</Tag>;
|
|
9
|
+
}
|
|
10
|
+
if (val === 'active' || val === true) {
|
|
19
11
|
return <Tag color="green">{t("Active")}</Tag>;
|
|
20
|
-
} else {
|
|
21
|
-
return <Tag color="red">{t("Suspended")}</Tag>;
|
|
22
12
|
}
|
|
13
|
+
|
|
14
|
+
return <Tag color="red">{t("Suspended")}</Tag>;
|
|
23
15
|
};
|
|
@@ -172,14 +172,15 @@ function AdminView({
|
|
|
172
172
|
try {
|
|
173
173
|
const { pendingCompanyId, status, ...userDataToInvite } = user;
|
|
174
174
|
console.log('Sending invitation for:', user.email, userDataToInvite);
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
182
|
-
|
|
175
|
+
// Use the standalone invite function, don't mix it with updateAccount
|
|
176
|
+
// await inviteCompanyAccount({
|
|
177
|
+
// companyId: editData.id,
|
|
178
|
+
// data: {
|
|
179
|
+
// ...userDataToInvite,
|
|
180
|
+
// pendingCompanyId,
|
|
181
|
+
// },
|
|
182
|
+
// });
|
|
183
|
+
// console.log('Invitation sent successfully for:', user.email);
|
|
183
184
|
} catch (inviteError) {
|
|
184
185
|
console.error('Failed to invite user:', user.email, inviteError);
|
|
185
186
|
handleError(inviteError);
|