datastake-daf 0.6.782 → 0.6.783
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 +348 -284
- package/dist/pages/index.js +2574 -255
- package/dist/utils/index.js +13 -0
- package/package.json +1 -1
- package/src/@daf/core/components/Dashboard/Map/ChainIcon/Markers/StakeholderMarker.js +9 -76
- package/src/@daf/core/components/Dashboard/Map/ChainIcon/index.js +116 -8
- package/src/@daf/core/components/Dashboard/Map/ChainIcon/utils.js +73 -17
- package/src/@daf/core/components/Dashboard/Map/helper.js +1 -0
- package/src/@daf/core/components/Dashboard/Map/hook.js +64 -29
- package/src/@daf/core/components/Dashboard/Map/style.js +20 -5
- package/src/@daf/pages/Template/components/LinkingTemplate/columns.js +95 -0
- package/src/@daf/pages/Template/components/LinkingTemplate/config.js +75 -0
- package/src/@daf/pages/Template/components/LinkingTemplate/index.jsx +119 -0
- package/src/@daf/pages/Template/index.jsx +19 -0
- package/src/@daf/pages/View/hooks/useCallToGetData.js +73 -0
- package/src/@daf/pages/View/hooks/usePrepareForm.js +86 -0
- package/src/@daf/pages/View/hooks/useSubmitSubject.js +40 -0
- package/src/@daf/pages/View/hooks/useViewActions.js +83 -0
- package/src/@daf/pages/View/hooks/useViewPermissions.js +74 -0
- package/src/@daf/pages/View/hooks/useViewUrlParams.js +93 -0
- package/src/@daf/pages/View/index.jsx +325 -0
- package/src/@daf/utils/object.js +3 -1
- package/src/pages.js +4 -1
- package/src/utils.js +1 -1
- package/dist/style/datastake/mapbox-gl.css +0 -330
- package/src/@daf/hooks/useViewFormUrlParams.js +0 -84
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { renderType } from './config.js';
|
|
2
|
+
import { renderDateFormatted } from '../../../../../helpers/Forms.js';
|
|
3
|
+
import CustomIcon from '../../../../core/components/Icon/CustomIcon.jsx';
|
|
4
|
+
|
|
5
|
+
export const getColumns = ({ t, redirect = () => "", mod, mode = "app", options }) => [
|
|
6
|
+
{
|
|
7
|
+
title: "ID",
|
|
8
|
+
dataIndex: "datastakeId",
|
|
9
|
+
key: "datastakeId",
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
title: t("Type"),
|
|
13
|
+
dataIndex: "type",
|
|
14
|
+
key: "type",
|
|
15
|
+
render: (type, all) => renderType({ item: all, t, type }),
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
title: t("Name"),
|
|
19
|
+
dataIndex: "name",
|
|
20
|
+
key: "name",
|
|
21
|
+
render: (name, all) => {
|
|
22
|
+
if (all.empty) {
|
|
23
|
+
return <div className="daf-default-cell" />;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (all?.form === "products") {
|
|
27
|
+
const { minerals } = options;
|
|
28
|
+
const mineral = minerals.find(
|
|
29
|
+
(mineral) => mineral.value === all?.typeOfProduct,
|
|
30
|
+
)?.label;
|
|
31
|
+
return mineral || "--";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return name || "--";
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
title: t("Last Update"),
|
|
39
|
+
dataIndex: "updatedAt",
|
|
40
|
+
key: "updateAt",
|
|
41
|
+
render: (updatedAt, all) => {
|
|
42
|
+
if (all.empty) {
|
|
43
|
+
return <div className="daf-default-cell" />;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<div className="daf-default-cell">
|
|
48
|
+
{renderDateFormatted(updatedAt, "DD MMM YYYY")}
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
title: "",
|
|
55
|
+
dataIndex: "actions",
|
|
56
|
+
width: 50,
|
|
57
|
+
key: "actions",
|
|
58
|
+
render: (_, all) => {
|
|
59
|
+
if (all.empty) {
|
|
60
|
+
return <div className="daf-default-cell" />;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return mode === "proxy" ? (
|
|
64
|
+
<a
|
|
65
|
+
onClick={() =>
|
|
66
|
+
redirect({
|
|
67
|
+
id: all.datastakeId,
|
|
68
|
+
type: all.type,
|
|
69
|
+
mod,
|
|
70
|
+
mode,
|
|
71
|
+
item: all,
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
href="#"
|
|
75
|
+
>
|
|
76
|
+
<CustomIcon name="LinkNewTab" width={14} height={14} color="#6C737F" />
|
|
77
|
+
</a>
|
|
78
|
+
) : (
|
|
79
|
+
<a
|
|
80
|
+
href={redirect({
|
|
81
|
+
id: all.datastakeId,
|
|
82
|
+
type: all.type,
|
|
83
|
+
mod,
|
|
84
|
+
mode,
|
|
85
|
+
item: all,
|
|
86
|
+
})}
|
|
87
|
+
target="_blank"
|
|
88
|
+
rel="noreferrer"
|
|
89
|
+
>
|
|
90
|
+
<CustomIcon name="LinkNewTab" width={14} height={14} color="#6C737F" />
|
|
91
|
+
</a>
|
|
92
|
+
);
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
];
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { capitalizeAll } from '../../../../../helpers/StringHelper.js';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export const decapitalize = string =>
|
|
6
|
+
string && string.charAt(0).toLowerCase() + string.slice(1);
|
|
7
|
+
|
|
8
|
+
const formatRedirectString = (stringItem) => {
|
|
9
|
+
let string;
|
|
10
|
+
if (stringItem.includes("nashiriki")) {
|
|
11
|
+
string = decapitalize(stringItem?.replaceAll("nashiriki", ""));
|
|
12
|
+
} else {
|
|
13
|
+
string = stringItem;
|
|
14
|
+
}
|
|
15
|
+
return string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const getLanguage = (lng = "") => {
|
|
19
|
+
if (lng.includes("en")) {
|
|
20
|
+
return "en";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (lng.includes("fr")) {
|
|
24
|
+
return "fr";
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const redirect = ({ id, item }) => {
|
|
29
|
+
const viewMode = "view";
|
|
30
|
+
let type = "testimonials";
|
|
31
|
+
|
|
32
|
+
if (item.category === "mineSite") {
|
|
33
|
+
type = "scl";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (item.stakeholderType === "operator") {
|
|
37
|
+
type = "operators";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (item.stakeholderType === "worker") {
|
|
41
|
+
type = "workers";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (item.form) {
|
|
45
|
+
type = `${formatRedirectString(item.form)}s`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let url = `/${viewMode}/${type}/${id}`;
|
|
49
|
+
|
|
50
|
+
return `/app${url}`;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const renderType = ({ item = {}, t = (s) => s }) => {
|
|
54
|
+
if (item.empty) {
|
|
55
|
+
return <div className="daf-default-cell" />;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (item.category === "mineSite") {
|
|
59
|
+
return t("Mine Site");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (item.stakeholderType === "operator") {
|
|
63
|
+
return t("Operator");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (item.stakeholderType === "worker") {
|
|
67
|
+
return t("Worker");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (item.form) {
|
|
71
|
+
return t(capitalizeAll(item.form));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return "--";
|
|
75
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import React, { useEffect, useMemo } from 'react';
|
|
2
|
+
import { useFilters } from '../../../../hooks/useFilters.js';
|
|
3
|
+
import { getColumns } from './columns.js';
|
|
4
|
+
import { redirect } from './config.js';
|
|
5
|
+
import LinkedSubjectsService from '../../../../services/LinkedSubjects.js';
|
|
6
|
+
import { formatClassname } from '../../../../../helpers/ClassesHelper.js';
|
|
7
|
+
import Table from '../../../../core/components/Table/index.jsx';
|
|
8
|
+
import Pagination from '../../../../core/components/Table/Pagination/index.jsx';
|
|
9
|
+
|
|
10
|
+
const emptyObject = {};
|
|
11
|
+
|
|
12
|
+
const LinkingTemplate = ({
|
|
13
|
+
conf,
|
|
14
|
+
namespace
|
|
15
|
+
}) => {
|
|
16
|
+
const view = useMemo(() => conf?.location?.pathname?.split(`/app/${conf.mod}/`)[1], [conf]);
|
|
17
|
+
|
|
18
|
+
const {
|
|
19
|
+
pagination,
|
|
20
|
+
onTableChange,
|
|
21
|
+
totalPages,
|
|
22
|
+
canGoNext,
|
|
23
|
+
canGoPrev,
|
|
24
|
+
setPagination,
|
|
25
|
+
goPrev,
|
|
26
|
+
goNext,
|
|
27
|
+
} = useFilters({
|
|
28
|
+
module: conf.mod,
|
|
29
|
+
view,
|
|
30
|
+
selectFiltersConfig: emptyObject,
|
|
31
|
+
filtersConfig: emptyObject,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const columns = useMemo(() => getColumns({
|
|
35
|
+
t: conf.t,
|
|
36
|
+
redirect,
|
|
37
|
+
mod: conf.mod,
|
|
38
|
+
language: conf.user?.language,
|
|
39
|
+
mode: conf.mode,
|
|
40
|
+
options: conf.options,
|
|
41
|
+
}), [conf]);
|
|
42
|
+
|
|
43
|
+
const id = conf.allData.id;
|
|
44
|
+
|
|
45
|
+
const dataSource = conf?.linkingTemplateContextData?.[id];
|
|
46
|
+
|
|
47
|
+
const changeData = async () => {
|
|
48
|
+
try {
|
|
49
|
+
const _data = await LinkedSubjectsService.getLinkedSubjects({ namespace, id, mod: conf.mod });
|
|
50
|
+
const data = (_data?.data || []).map((d, i) => ({ ...d, key: `${d.id}-${i}` }));
|
|
51
|
+
conf?.addData(id, data);
|
|
52
|
+
setPagination((prev) => ({
|
|
53
|
+
...prev,
|
|
54
|
+
current: 1,
|
|
55
|
+
total: data.length ? data.length : 1,
|
|
56
|
+
}));
|
|
57
|
+
} catch (err) {
|
|
58
|
+
console.log(err);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const _dataSource = useMemo(() => {
|
|
63
|
+
const startIndex = pagination.pageSize * (pagination.current - 1);
|
|
64
|
+
const endIndex = Math.min(startIndex + pagination.pageSize, dataSource?.length || 0);
|
|
65
|
+
return [...(dataSource || [])].slice(startIndex, endIndex);
|
|
66
|
+
}, [pagination, dataSource]);
|
|
67
|
+
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (!dataSource) {
|
|
70
|
+
changeData();
|
|
71
|
+
} else {
|
|
72
|
+
setPagination((prev) => ({
|
|
73
|
+
...prev,
|
|
74
|
+
current: 1,
|
|
75
|
+
total: dataSource.length ? dataSource.length : 1,
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
}, []);
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
return ( <div className={formatClassname(["content", "documents-layout"])} style={{}}>
|
|
82
|
+
<div className="view-header" style={{ flexDirection: "column", paddingTop: 0 }}>
|
|
83
|
+
<div className="daf-table-wrapper pagination-no-padding">
|
|
84
|
+
<Table
|
|
85
|
+
className="mt-0 p-0"
|
|
86
|
+
columns={columns}
|
|
87
|
+
hideOnLoading={false}
|
|
88
|
+
data={_dataSource}
|
|
89
|
+
doEmptyRows
|
|
90
|
+
loading={!dataSource}
|
|
91
|
+
rowKey="key"
|
|
92
|
+
pagination={pagination}
|
|
93
|
+
size="small"
|
|
94
|
+
/>
|
|
95
|
+
|
|
96
|
+
<Pagination
|
|
97
|
+
t={conf?.t}
|
|
98
|
+
isMobile={conf?.isMobile}
|
|
99
|
+
page={pagination.current}
|
|
100
|
+
totalPages={totalPages}
|
|
101
|
+
goPrev={goPrev}
|
|
102
|
+
goNext={goNext}
|
|
103
|
+
canGoNext={canGoNext}
|
|
104
|
+
canGoPrev={canGoPrev}
|
|
105
|
+
totalItems={pagination.total}
|
|
106
|
+
doTotalItems
|
|
107
|
+
onChangePagination={(val) => {
|
|
108
|
+
onTableChange({ ...pagination, current: 1, pageSize: val });
|
|
109
|
+
}}
|
|
110
|
+
perPage={pagination.pageSize}
|
|
111
|
+
arrowIcons
|
|
112
|
+
/>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
)
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export default LinkingTemplate;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* eslint-disable react/prop-types */
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import LinkingTemplate from './components/LinkingTemplate/index.jsx';
|
|
4
|
+
|
|
5
|
+
export function Template({
|
|
6
|
+
conf,
|
|
7
|
+
namespace,
|
|
8
|
+
}) {
|
|
9
|
+
switch (namespace) {
|
|
10
|
+
case 'locations':
|
|
11
|
+
case 'documents':
|
|
12
|
+
case 'stakeholders':
|
|
13
|
+
case 'events':
|
|
14
|
+
return <LinkingTemplate conf={conf} namespace={namespace} />
|
|
15
|
+
default:
|
|
16
|
+
return null;
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { useRef, useEffect } from "react";
|
|
2
|
+
import { hasKeyInObject } from "../../../../@daf/utils/object.js";
|
|
3
|
+
import { getNkey } from "../../../../@daf/core/components/ViewForm/helper.js";
|
|
4
|
+
|
|
5
|
+
export const useCallToGetData = ({
|
|
6
|
+
namespaceConfig,
|
|
7
|
+
namespace,
|
|
8
|
+
allData,
|
|
9
|
+
id,
|
|
10
|
+
isSupported,
|
|
11
|
+
namespaceGet,
|
|
12
|
+
source,
|
|
13
|
+
version,
|
|
14
|
+
user,
|
|
15
|
+
setLoading,
|
|
16
|
+
APP,
|
|
17
|
+
}) => {
|
|
18
|
+
const isFirstRender = useRef(true);
|
|
19
|
+
|
|
20
|
+
const callToGetData = (_doCall = false) => {
|
|
21
|
+
const dKey = namespaceConfig?.dataKey;
|
|
22
|
+
const nKey = `${APP}-${getNkey(namespace || "")}`;
|
|
23
|
+
const doCall = _doCall
|
|
24
|
+
? true
|
|
25
|
+
: hasKeyInObject(allData, dKey) && hasKeyInObject(allData[dKey], nKey)
|
|
26
|
+
? allData[dKey][nKey]?.data?.datastakeId !== id
|
|
27
|
+
: true;
|
|
28
|
+
if (doCall) {
|
|
29
|
+
if (isSupported) {
|
|
30
|
+
namespaceGet[namespace]();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
if (isFirstRender.current) {
|
|
37
|
+
isFirstRender.current = false;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
callToGetData(true);
|
|
41
|
+
}, [source, version]);
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
callToGetData(true);
|
|
45
|
+
}, [id, namespace, user.language]);
|
|
46
|
+
|
|
47
|
+
const onStorageUpdate = (e) => {
|
|
48
|
+
const { key, newValue } = e;
|
|
49
|
+
if (key === `${id}-loading` && newValue) {
|
|
50
|
+
setLoading(newValue);
|
|
51
|
+
}
|
|
52
|
+
if (key === `${id}-updated` && newValue) {
|
|
53
|
+
setLoading(true);
|
|
54
|
+
callToGetData();
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
window.addEventListener("storage", onStorageUpdate);
|
|
60
|
+
return () => {
|
|
61
|
+
window.removeEventListener("storage", onStorageUpdate);
|
|
62
|
+
};
|
|
63
|
+
}, []);
|
|
64
|
+
|
|
65
|
+
// useEffect(() => {
|
|
66
|
+
// setLoading(true);
|
|
67
|
+
// }, [namespace]);
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
callToGetData,
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
import { hasKeyInObject } from "../../../../@daf/utils/object.js";
|
|
3
|
+
|
|
4
|
+
export const usePrepareForm = ({
|
|
5
|
+
namespaceConfig,
|
|
6
|
+
allData,
|
|
7
|
+
id,
|
|
8
|
+
namespace,
|
|
9
|
+
t,
|
|
10
|
+
mode,
|
|
11
|
+
APP,
|
|
12
|
+
viewConfig,
|
|
13
|
+
}) => {
|
|
14
|
+
const [form, setForm] = useState({});
|
|
15
|
+
const [data, setData] = useState({});
|
|
16
|
+
const [groups, setGroups] = useState({});
|
|
17
|
+
const [linkingForms, setLinkingForms] = useState({});
|
|
18
|
+
const [loading, setLoading] = useState(true);
|
|
19
|
+
const [notFound, setNotFound] = useState(false);
|
|
20
|
+
|
|
21
|
+
const prepareForm = (currentView) => {
|
|
22
|
+
const dKey = namespaceConfig?.dataKey;
|
|
23
|
+
const nKey = `${APP}-${currentView}`;
|
|
24
|
+
|
|
25
|
+
if (hasKeyInObject(allData, dKey) && hasKeyInObject(allData[dKey], nKey)) {
|
|
26
|
+
const {
|
|
27
|
+
form = {},
|
|
28
|
+
data = {},
|
|
29
|
+
config = {},
|
|
30
|
+
linkingForms = {},
|
|
31
|
+
} = JSON.parse(JSON.stringify(allData[dKey][nKey] || {}));
|
|
32
|
+
|
|
33
|
+
if (data.datastakeId === id || id === "user") {
|
|
34
|
+
if (viewConfig.linkingSubjects.includes(namespace)) {
|
|
35
|
+
setForm({
|
|
36
|
+
...form,
|
|
37
|
+
linking: {
|
|
38
|
+
position: 100,
|
|
39
|
+
excludeFromEdit: true,
|
|
40
|
+
label: t("Linked Subjects"),
|
|
41
|
+
template: "linkingSubjects",
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
} else {
|
|
45
|
+
setForm(form);
|
|
46
|
+
}
|
|
47
|
+
setData(data);
|
|
48
|
+
setGroups(config.groups || {});
|
|
49
|
+
setLinkingForms(linkingForms);
|
|
50
|
+
setLoading(false);
|
|
51
|
+
setNotFound(false);
|
|
52
|
+
} else if (!data.id) {
|
|
53
|
+
if (mode === "proxy") {
|
|
54
|
+
window.location.reload();
|
|
55
|
+
} else {
|
|
56
|
+
setLoading(false);
|
|
57
|
+
setNotFound(true);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const getCertainData = allData?.[namespaceConfig?.dataKey];
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if(namespace && namespaceConfig) {
|
|
67
|
+
prepareForm(namespaceConfig?.view);
|
|
68
|
+
}
|
|
69
|
+
}, [getCertainData, namespaceConfig]);
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
form,
|
|
73
|
+
setForm,
|
|
74
|
+
data,
|
|
75
|
+
setData,
|
|
76
|
+
groups,
|
|
77
|
+
setGroups,
|
|
78
|
+
linkingForms,
|
|
79
|
+
setLinkingForms,
|
|
80
|
+
loading,
|
|
81
|
+
setLoading,
|
|
82
|
+
notFound,
|
|
83
|
+
setNotFound,
|
|
84
|
+
prepareForm,
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useState, useCallback } from "react";
|
|
2
|
+
|
|
3
|
+
export const submitSubjectData = async (namespace, data, serviceMap) => {
|
|
4
|
+
const service = serviceMap[namespace];
|
|
5
|
+
if (!service) {
|
|
6
|
+
throw new Error(`No service found for namespace: ${namespace}`);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const response = await service.submitStep(
|
|
10
|
+
data,
|
|
11
|
+
data.datastakeId || data.id
|
|
12
|
+
);
|
|
13
|
+
return response.data;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const useSubmitSubject = ({namespace, data, serviceMap}) => {
|
|
17
|
+
const [isDisabled, setIsDisabled] = useState(false);
|
|
18
|
+
const [loading, setLoading] = useState(false);
|
|
19
|
+
const [isPublished, setIsPublished] = useState(false);
|
|
20
|
+
|
|
21
|
+
const submitSubject = useCallback(async () => {
|
|
22
|
+
try {
|
|
23
|
+
setLoading(true);
|
|
24
|
+
const response = await submitSubjectData(namespace, data, serviceMap);
|
|
25
|
+
setIsDisabled(response.published);
|
|
26
|
+
setIsPublished(response.published);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.error("Submit error:", error);
|
|
29
|
+
} finally {
|
|
30
|
+
setLoading(false);
|
|
31
|
+
}
|
|
32
|
+
}, [namespace, data]);
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
submitSubject,
|
|
36
|
+
isDisabled,
|
|
37
|
+
submitLoading: loading,
|
|
38
|
+
isPublished,
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
export const useViewActions = ({
|
|
4
|
+
namespace,
|
|
5
|
+
data,
|
|
6
|
+
isSupported,
|
|
7
|
+
canEdit,
|
|
8
|
+
versionUrl,
|
|
9
|
+
sourceUrl,
|
|
10
|
+
getEditLink,
|
|
11
|
+
submitSubject,
|
|
12
|
+
isDisabled,
|
|
13
|
+
setOpenRecordsModal,
|
|
14
|
+
goBackFromSource,
|
|
15
|
+
push,
|
|
16
|
+
getRedirectLink,
|
|
17
|
+
t,
|
|
18
|
+
viewConfig,
|
|
19
|
+
buttonActions,
|
|
20
|
+
}) => {
|
|
21
|
+
const [pageActions, setPageActions] = useState([]);
|
|
22
|
+
const [extraPageActions, setExtraPageActions] = useState([]);
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const actions = [];
|
|
26
|
+
const extraActions = [];
|
|
27
|
+
|
|
28
|
+
if (!isSupported) {
|
|
29
|
+
setPageActions([]);
|
|
30
|
+
setExtraPageActions([]);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (canEdit) {
|
|
35
|
+
if (viewConfig.namespacesWithoutActionButtons.includes(namespace)) {
|
|
36
|
+
if (viewConfig.editOnlyButton.includes(namespace)) {
|
|
37
|
+
if (versionUrl && sourceUrl) {
|
|
38
|
+
actions.push(buttonActions.createBackButton(t, goBackFromSource));
|
|
39
|
+
} else {
|
|
40
|
+
actions.push(buttonActions.createEditButton(t, getEditLink));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
if (versionUrl && sourceUrl) {
|
|
45
|
+
actions.push(buttonActions.createBackButton(t, goBackFromSource));
|
|
46
|
+
} else {
|
|
47
|
+
actions.push(buttonActions.createSubmitButton(t, submitSubject, isDisabled, data));
|
|
48
|
+
actions.push(buttonActions.createEditButton(t, getEditLink));
|
|
49
|
+
// actions.push(createRecordsButton(t, setOpenRecordsModal));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (viewConfig.summaryNamespaces.includes(namespace)) {
|
|
55
|
+
extraActions.push(
|
|
56
|
+
buttonActions.createSummaryButton(t, namespace, data, push, getRedirectLink)
|
|
57
|
+
);
|
|
58
|
+
extraActions.push(
|
|
59
|
+
buttonActions.createRecordsButton(t, setOpenRecordsModal)
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
setPageActions(actions);
|
|
64
|
+
setExtraPageActions(extraActions);
|
|
65
|
+
}, [
|
|
66
|
+
namespace,
|
|
67
|
+
data,
|
|
68
|
+
isSupported,
|
|
69
|
+
canEdit,
|
|
70
|
+
versionUrl,
|
|
71
|
+
sourceUrl,
|
|
72
|
+
isDisabled,
|
|
73
|
+
t,
|
|
74
|
+
getEditLink,
|
|
75
|
+
submitSubject,
|
|
76
|
+
goBackFromSource,
|
|
77
|
+
setOpenRecordsModal,
|
|
78
|
+
push,
|
|
79
|
+
getRedirectLink,
|
|
80
|
+
]);
|
|
81
|
+
|
|
82
|
+
return { pageActions, extraPageActions };
|
|
83
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { useMemo, useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
export const useViewPermissions = ({
|
|
4
|
+
data,
|
|
5
|
+
id,
|
|
6
|
+
namespaceOverrides = {
|
|
7
|
+
supportedNamespaces: {},
|
|
8
|
+
canEdit: {},
|
|
9
|
+
},
|
|
10
|
+
namespace,
|
|
11
|
+
user,
|
|
12
|
+
push,
|
|
13
|
+
getRedirectLink,
|
|
14
|
+
namespaceConfig,
|
|
15
|
+
APP,
|
|
16
|
+
viewConfig,
|
|
17
|
+
}) => {
|
|
18
|
+
const baseNamespaceKeys = Object.keys(namespaceConfig || {});
|
|
19
|
+
|
|
20
|
+
const baseSupportedNamespaces = baseNamespaceKeys?.reduce((acc, key) => {
|
|
21
|
+
acc[key] = () => true;
|
|
22
|
+
return acc;
|
|
23
|
+
}, {});
|
|
24
|
+
|
|
25
|
+
const isSupportedNamespaces = useMemo(
|
|
26
|
+
() => ({
|
|
27
|
+
...baseSupportedNamespaces,
|
|
28
|
+
...namespaceOverrides?.supportedNamespaces,
|
|
29
|
+
}),
|
|
30
|
+
[data, id],
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const isSupported = typeof isSupportedNamespaces[namespace] === "function"
|
|
34
|
+
? isSupportedNamespaces[namespace]() &&
|
|
35
|
+
viewConfig?.supportedNamespaces[APP] &&
|
|
36
|
+
viewConfig?.supportedNamespaces[APP]?.includes(namespace)
|
|
37
|
+
: viewConfig?.supportedNamespaces[APP] && viewConfig?.supportedNamespaces[APP].includes(namespace);
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
const isUserData = () => {
|
|
41
|
+
return data && data.authorId && user?.company?.id === data.authorId;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const canEdit = useMemo(() => {
|
|
45
|
+
const baseCanEditAction = baseNamespaceKeys.reduce((acc, key) => {
|
|
46
|
+
acc[key] = () => isUserData();
|
|
47
|
+
return acc;
|
|
48
|
+
}, {});
|
|
49
|
+
|
|
50
|
+
const canEditAction = {
|
|
51
|
+
...baseCanEditAction,
|
|
52
|
+
...namespaceOverrides.canEdit,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return canEditAction[namespace] ? canEditAction[namespace]() : false;
|
|
56
|
+
}, [namespace, data, user]);
|
|
57
|
+
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (data) {
|
|
60
|
+
if (typeof isSupportedNamespaces[namespace] === "function") {
|
|
61
|
+
if (!isSupportedNamespaces[namespace]()) {
|
|
62
|
+
push(getRedirectLink(`/app`));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}, [data, namespace]);
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
isSupportedNamespaces,
|
|
70
|
+
canEdit,
|
|
71
|
+
isSupported,
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
}
|