datastake-daf 0.6.753 → 0.6.755

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datastake-daf",
3
- "version": "0.6.753",
3
+ "version": "0.6.755",
4
4
  "dependencies": {
5
5
  "@ant-design/icons": "^5.2.5",
6
6
  "@antv/g2": "^5.1.1",
@@ -165,46 +165,61 @@ export default function DynamicForm({
165
165
  // setOriginalData({});
166
166
  // setValues({});
167
167
  // MainForm.resetFields();
168
+ } else if (isCreate) {
169
+ // Reset form when data is empty in create mode (e.g., when switching contexts)
170
+ setOriginalData({});
171
+ setValues({});
172
+ MainForm.resetFields();
168
173
  }
169
- }, [data]);
174
+ }, [data, isCreate]);
170
175
 
171
176
  // Initialize default values for hidden and disabled fields
172
177
  useEffect(() => {
173
178
  if (Object.keys(form).length > 0) {
174
- const updatedValues = { ...values };
175
- let hasChanges = false;
176
- const isEditMode = data && (data.id || data._id);
177
-
178
- // Process all form fields to set default values for hidden and disabled fields
179
- Object.keys(form).forEach(formKey => {
180
- Object.keys(form[formKey]).forEach(fieldKey => {
181
- const field = form[formKey][fieldKey];
182
- const fieldId = field.dataId || fieldKey;
183
-
184
- // Check if field is disabled
185
- const isDisabled = (field?.meta?.disableEdit && typeof field?.meta?.disableEdit === 'object')
186
- ? isModal
187
- ? field.meta.disableEdit.create || field.meta.disableEdit.modal || (field?.meta?.disableEdit?.edit && isEditMode)
188
- : field.meta.disableEdit.create || field.meta.disableEdit.drawer || (field?.meta?.disableEdit?.edit && isEditMode)
189
- : field?.meta?.disableEdit;
190
-
191
- // Set default value for hidden fields or disabled fields with default values
192
- if (field?.meta?.defaultValue !== undefined && !propHasValue(updatedValues[fieldId])) {
193
- if (field?.meta?.hidden === true || isDisabled) {
194
- updatedValues[fieldId] = field.meta.defaultValue;
195
- hasChanges = true;
179
+ setValues(prevValues => {
180
+ // Use data prop as base, or current values if data is empty
181
+ const baseValues = Object.keys(data).length > 0 ? data : prevValues;
182
+ const updatedValues = { ...baseValues };
183
+ let hasChanges = false;
184
+ const isEditMode = data && (data.id || data._id);
185
+
186
+ // Process all form fields to set default values for hidden and disabled fields
187
+ Object.keys(form).forEach(formKey => {
188
+ Object.keys(form[formKey]).forEach(fieldKey => {
189
+ const field = form[formKey][fieldKey];
190
+ const fieldId = field.dataId || fieldKey;
191
+
192
+ // Check if field is disabled
193
+ const isDisabled = (field?.meta?.disableEdit && typeof field?.meta?.disableEdit === 'object')
194
+ ? isModal
195
+ ? field.meta.disableEdit.create || field.meta.disableEdit.modal || (field?.meta?.disableEdit?.edit && isEditMode)
196
+ : field.meta.disableEdit.create || field.meta.disableEdit.drawer || (field?.meta?.disableEdit?.edit && isEditMode)
197
+ : field?.meta?.disableEdit;
198
+
199
+ // Set default value for hidden fields or disabled fields with default values
200
+ if (field?.meta?.defaultValue !== undefined) {
201
+ // In create mode, always update disabled/hidden fields with default values when form config changes
202
+ // This ensures context switching (Operation -> Restoration) updates the field correctly
203
+ const shouldUpdate = !propHasValue(updatedValues[fieldId]) ||
204
+ (isCreate && !isEditMode && (field?.meta?.hidden === true || isDisabled));
205
+
206
+ if (shouldUpdate && (field?.meta?.hidden === true || isDisabled)) {
207
+ updatedValues[fieldId] = field.meta.defaultValue;
208
+ hasChanges = true;
209
+ }
196
210
  }
197
- }
211
+ });
198
212
  });
213
+
214
+ if (hasChanges) {
215
+ // Also set the values in the Ant Design form
216
+ MainForm.setFieldsValue(updatedValues);
217
+ return updatedValues;
218
+ }
219
+ return prevValues;
199
220
  });
200
-
201
- if (hasChanges) {
202
- setValues(updatedValues);
203
- // Also set the values in the Ant Design form
204
- MainForm.setFieldsValue(updatedValues);
205
- }
206
221
  }
207
- }, [form, data, isModal]);
222
+ }, [form, data, isModal, isCreate]);
208
223
 
209
224
  const setSelectedForm = (id) => {
210
225
  setForms(Forms.map(form => {
@@ -0,0 +1,216 @@
1
+ import React from 'react';
2
+ import { Modal, Tag, Typography, message ,Tooltip} from "antd";
3
+
4
+ import { renderDateFormatted } from '../../../../../helpers/Forms.js';
5
+ import MoreMenu from '../../../../core/components/Table/MoreMenu/index.jsx';
6
+ const getLinkValue = (value, linkingObject) => {
7
+ if(linkingObject && linkingObject?.[value]) {
8
+ return linkingObject?.[value]?.name;
9
+ }
10
+ return null;
11
+ }
12
+
13
+ export const getColumns = ({t, goTo, user, removeUser = () => {},
14
+ resendInvite = () => {},
15
+ setUserToEdit = () => {},
16
+ userRoles = [],
17
+ company = {},
18
+ canCreate = false,
19
+ app}) => [
20
+ // {
21
+ // dataIndex: 'datastakeId',
22
+ // title: t('ID'),
23
+ // ellipsis: true,
24
+ // show: true,
25
+ // render: (v, all) => {
26
+ // if (all.empty) {
27
+ // return <div className="daf-default-cell" />
28
+ // }
29
+
30
+ // return <Tooltip title={v}>{v}</Tooltip>;
31
+ // },
32
+ // },
33
+ {
34
+ dataIndex: 'firstName',
35
+ title: t('Name'),
36
+ ellipsis: true,
37
+ show: true,
38
+ render: (v, all) => {
39
+ if (all.empty) {
40
+ return <div className="daf-default-cell" />
41
+ }
42
+
43
+ return <Tooltip title={v}>{v}</Tooltip>;
44
+ },
45
+ },
46
+ {
47
+ dataIndex: 'lastName',
48
+ title: t('Last Name'),
49
+ ellipsis: true,
50
+ show: true,
51
+ render: (v, all) => {
52
+ if (all.empty) {
53
+ return <div className="daf-default-cell" />
54
+ }
55
+
56
+ return <Tooltip title={v}>{v}</Tooltip>;
57
+ },
58
+ },
59
+ {
60
+ dataIndex: 'email',
61
+ title: t('Email'),
62
+ ellipsis: true,
63
+ show: true,
64
+ render: (v, all) => {
65
+ if (all.empty) {
66
+ return <div className="daf-default-cell" />
67
+ }
68
+
69
+ return <Tooltip title={v}>{v}</Tooltip>;
70
+ },
71
+
72
+ },
73
+ {
74
+ title: t("Status"),
75
+ dataIndex: "status",
76
+ key: "status",
77
+ width: 150,
78
+ ellipsis: false,
79
+ show: true,
80
+ render: (status, users) => {
81
+ if (users.empty) {
82
+ return null;
83
+ }
84
+
85
+ if (status === "inactive") {
86
+ return (
87
+ <Tag color="red" style={{ width: 100, textAlign: "center" }}>
88
+ {t("Blocked")}
89
+ </Tag>
90
+ );
91
+ }
92
+
93
+ if (status === "active") {
94
+ return (
95
+ <Tag color="green" style={{ width: 100, textAlign: "center" }}>
96
+ {t("Active")}
97
+ </Tag>
98
+ );
99
+ }
100
+
101
+ return (
102
+ <Tag color="orange" style={{ width: 100, textAlign: "center" }}>
103
+ {t("Pending")}
104
+ </Tag>
105
+ );
106
+ },
107
+ },
108
+ {
109
+ title: t("Last Login"),
110
+ dataIndex: "lastLogin",
111
+ key: "lastLogin",
112
+ width: 125,
113
+ render: (date, all) => {
114
+ if (all.empty) {
115
+ return <div className="daf-default-cell" />;
116
+ }
117
+
118
+ const _date = date ? renderDateFormatted(date, "DD MMM YYYY", user?.language || 'en') : "-";
119
+ return <Tooltip title={_date}>{_date}</Tooltip>;
120
+ },
121
+ ellipsis: true,
122
+ },
123
+ {
124
+ title: t("User Role"),
125
+ dataIndex: "roleName",
126
+ key: "role",
127
+ show: true,
128
+ render: (val, all) => {
129
+ if (all.empty) {
130
+ return <div className="daf-default-cell" />;
131
+ }
132
+
133
+ // Display role name if available, fallback to role ID
134
+ const displayValue = val || all.role;
135
+ return <Tooltip title={displayValue}>{displayValue}</Tooltip>;
136
+ },
137
+ },
138
+ {
139
+ title: t(""),
140
+ key: "actions",
141
+ width: 60,
142
+ show: removeUser || setUserToEdit,
143
+ render: (row, all) => {
144
+ if (all.empty) {
145
+ return <div className="daf-default-cell" />;
146
+ }
147
+
148
+ const _v = userRoles?.find((r) => r.value === all.role);
149
+
150
+ const items = [
151
+ removeUser
152
+ ? {
153
+ key: "removeUser",
154
+ onClick: () => {
155
+ Modal.confirm({
156
+ title: t(
157
+ "Are you sure you want to remove this user from your organisation?",
158
+ ),
159
+ onOk: () => removeUser(all.id),
160
+ cancelText: t("No"),
161
+ okText: "Yes",
162
+ closable: true,
163
+ });
164
+ },
165
+ label: t("Remove User"),
166
+ }
167
+ : null,
168
+ setUserToEdit ? {
169
+ key: "editPermission",
170
+ onClick: () => setUserToEdit(all),
171
+ disabled: all.isAdmin || _v?.isForAppAdmin,
172
+ label: t("Edit Permissions"),
173
+ }
174
+ : null,
175
+ all.invitationToken && canCreate
176
+ ? {
177
+ key: "copyLink",
178
+ onClick: () => {
179
+ if (location.pathname.includes(`/${APP}`)) {
180
+ navigator.clipboard.writeText(
181
+ `${window.location.host}/${app}/r/${company.inviteToken}/${all.invitationToken}`,
182
+ );
183
+ } else {
184
+ navigator.clipboard.writeText(
185
+ `${window.location.host}/r/${company.inviteToken}/${all.invitationToken}`,
186
+ );
187
+ }
188
+ message.info({ content: t("Invitation link copied") });
189
+ },
190
+ label: t("Copy Invitation Link"),
191
+ }
192
+ : null,
193
+ all.invitationToken && canCreate
194
+ ? {
195
+ key: "resendInvite",
196
+ onClick: () => {
197
+ Modal.confirm({
198
+ title: t(
199
+ "Are you sure you want to invite this user again? This user will receive a new notification",
200
+ ),
201
+ onOk: () => resendInvite(all.id),
202
+ cancelText: t("No"),
203
+ okText: "Yes",
204
+ closable: true,
205
+ });
206
+ },
207
+ label: t("Resend Invite"),
208
+ }
209
+ : null,
210
+ ];
211
+
212
+ return <MoreMenu items={items} />;
213
+ },
214
+ client: false,
215
+ },
216
+ ].filter((column) => column.show !== false);
@@ -0,0 +1,174 @@
1
+ export const checkboxConfig = {
2
+ name: 'Name',
3
+ datastakeId: 'ID'
4
+ }
5
+
6
+ export const getFiltersConfig = ({t}) => {
7
+ return {
8
+ email: {
9
+ type: 'text',
10
+ label: 'Email',
11
+ placeholder: (t) => `${t('Filter by')} ${t('Email').toLowerCase()}`,
12
+ style: { flex: 1 },
13
+ labelStyle: { flex: 1 },
14
+ getLabel: (option) => option.label,
15
+ getValue: (option) => option.value,
16
+ },
17
+
18
+
19
+ status: {
20
+ type: "select",
21
+ label: "Status",
22
+ placeholder: (t) => `${t("Filter by")} ${t("Status").toLowerCase()}`,
23
+ style: { flex: 1 },
24
+ labelStyle: { fley: 1 },
25
+ getLabel: (option) => option.label,
26
+ getValue: (option) => option.value,
27
+ },
28
+ timeframe: {
29
+ type: "timeframe",
30
+ label: "Timeframe",
31
+ placeholder: (t) => `${t("Filter by")} ${t("Timeframe").toLowerCase()}`,
32
+ style: { flex: 1 },
33
+ labelStyle: { flex: 1 },
34
+ },
35
+ userRole: {
36
+ type: "select",
37
+ label: "User Role",
38
+ placeholder: (t) => `${t("Filter by")} ${t("User Role").toLowerCase()}`,
39
+ style: { flex: 1 },
40
+ labelStyle: { flex: 1 },
41
+ },
42
+ }
43
+ }
44
+
45
+ export const filtersConfig = {
46
+ name: '',
47
+ datastakeId: '',
48
+ };
49
+
50
+ export const getFilterOptions = (options, t) => {
51
+ const {
52
+ emailOptions = [],
53
+ statusOptions = [],
54
+ timeframeOptions = [],
55
+ userRoleOptions = [],
56
+ } = options || {};
57
+ console.log({options})
58
+
59
+ const _default = {
60
+ timeframe: timeframeOptions,
61
+ email: emailOptions,
62
+ status: statusOptions,
63
+ userRole: userRoleOptions,
64
+ status: [
65
+ {
66
+ value: "active",
67
+ label: "Active",
68
+ },
69
+ {
70
+ value: "pending",
71
+ label: "Pending",
72
+ },
73
+ ],
74
+ }
75
+
76
+ return _default;
77
+ }
78
+
79
+ export const getUserForm = ({ t, userRoles = [], APP }) => {
80
+ return {
81
+ user: {
82
+ position: 0,
83
+ firstName: {
84
+ group: "user",
85
+ section: "user",
86
+ moduleScope: {
87
+ cadd: ["scoping", "new", "linking-extra"],
88
+ pme: ["scoping", "new", "linking-extra"],
89
+ },
90
+ label: t("First Name"),
91
+ comment: false,
92
+ type: "text",
93
+ rules: [
94
+ {
95
+ required: true,
96
+ message: "This field is required",
97
+ },
98
+ ],
99
+ mergeStrategy: "simple",
100
+ position: 1,
101
+ },
102
+ lastName: {
103
+ group: "user",
104
+ section: "user",
105
+ moduleScope: {
106
+ cadd: ["scoping", "new", "linking-extra"],
107
+ pme: ["scoping", "new", "linking-extra"],
108
+ },
109
+ label: t("Last Name"),
110
+ comment: false,
111
+ type: "text",
112
+ rules: [
113
+ {
114
+ required: true,
115
+ message: "This field is required",
116
+ },
117
+ ],
118
+ mergeStrategy: "simple",
119
+ position: 2,
120
+ },
121
+ email: {
122
+ group: "user",
123
+ section: "user",
124
+ moduleScope: {
125
+ cadd: ["scoping", "new", "linking-extra"],
126
+ pme: ["scoping", "new", "linking-extra"],
127
+ },
128
+ label: t("Email"),
129
+ comment: false,
130
+ type: "text",
131
+ rules: [
132
+ {
133
+ required: true,
134
+ message: "This field is required",
135
+ },
136
+ {
137
+ type: "email",
138
+ message: "errors::field must be email",
139
+ },
140
+ ],
141
+ mergeStrategy: "simple",
142
+ position: 3,
143
+ },
144
+ role: {
145
+ group: "user",
146
+ section: "user",
147
+ moduleScope: {
148
+ cadd: ["scoping", "new", "linking", "linking-extra", "admin"],
149
+ pme: ["scoping", "new", "linking", "linking-extra", "admin"],
150
+ },
151
+ label: t("User Role"),
152
+ placeholder: t("User Role"),
153
+ comment: false,
154
+ type: "select",
155
+ options: userRoles
156
+ .filter((r) => r.canBeAssignedToSubUsers && r.app === APP)
157
+ .map((v) => ({
158
+ label: t(v.label),
159
+ value: v.value,
160
+ })),
161
+ optionsName: "userRoles",
162
+ // tooltip: <UserRolePopover t={t} />,
163
+ sortOptions: true,
164
+ rules: [
165
+ {
166
+ required: true,
167
+ message: "This field is required",
168
+ },
169
+ ],
170
+ position: 4,
171
+ },
172
+ },
173
+ };
174
+ };
@@ -0,0 +1,63 @@
1
+ import React, { useMemo } from 'react'
2
+ import { getUserForm } from './config.js';
3
+ import DynamicForm from '../../../../core/components/DynamicForm/index.jsx';
4
+
5
+ const UsersCreate = ({
6
+ onSubmitted = () => {},
7
+ onCancel = () => {},
8
+ user = {},
9
+ APP,
10
+ query,
11
+ goTo = () => {},
12
+ t = () => {},
13
+ ajaxForms = {},
14
+ changeAjaxForms = () => {},
15
+ ajaxOptions = {},
16
+ changeAjaxOptions = () => {},
17
+ getAppHeader = () => {},
18
+ getApiBaseUrl = () => {},
19
+ userToEdit = null,
20
+ userRoles = [],
21
+ }) => {
22
+ const disabledInputs = useMemo(() => !userToEdit ? [] : ['firstName', 'lastName', 'email'], [userToEdit]);
23
+ const data = useMemo(() => ({ ...(userToEdit || {}), userRole: userToEdit?.role }), [userToEdit]);
24
+ const form = useMemo(() => getUserForm({ t, userRoles, APP }), [t, userRoles, APP]);
25
+
26
+ return (
27
+ <div className="daf-create-form">
28
+ <DynamicForm
29
+ form={form}
30
+ data={data}
31
+ showSaveAndNext={false}
32
+ module={APP}
33
+ onCancel={onCancel}
34
+ isCreate
35
+ t={t}
36
+ user={user}
37
+ ajaxForms={ajaxForms}
38
+ ajaxOptions={ajaxOptions}
39
+ getAppHeader={getAppHeader}
40
+ getApiBaseUrl={getApiBaseUrl}
41
+ changeAjaxOptions={changeAjaxOptions}
42
+ app={APP}
43
+ query={query}
44
+ goTo={goTo}
45
+ changeAjaxForms={changeAjaxForms}
46
+ disabledInputs={disabledInputs}
47
+ submit={(payload) => {
48
+ onSubmitted({
49
+ ...payload,
50
+ apps: {
51
+ [APP]: {
52
+ ...((userToEdit?.apps || {})[APP] || {}),
53
+ role: payload.role,
54
+ },
55
+ },
56
+ });
57
+ }}
58
+ />
59
+ </div>
60
+ )
61
+ }
62
+
63
+ export default UsersCreate