@solidstarters/solid-core-ui 1.1.54 → 1.1.56
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/common/SolidFormStepper.d.ts.map +1 -1
- package/dist/components/common/SolidFormStepper.js +0 -4
- package/dist/components/common/SolidFormStepper.js.map +1 -1
- package/dist/components/core/common/SolidGlobalSearchElement.d.ts.map +1 -1
- package/dist/components/core/common/SolidGlobalSearchElement.js +7 -2
- package/dist/components/core/common/SolidGlobalSearchElement.js.map +1 -1
- package/dist/components/core/form/SolidFormUserViewLayout.d.ts +2 -0
- package/dist/components/core/form/SolidFormUserViewLayout.d.ts.map +1 -0
- package/dist/components/core/form/SolidFormUserViewLayout.js +112 -0
- package/dist/components/core/form/SolidFormUserViewLayout.js.map +1 -0
- package/dist/components/core/form/SolidFormView.d.ts.map +1 -1
- package/dist/components/core/form/SolidFormView.js +29 -22
- package/dist/components/core/form/SolidFormView.js.map +1 -1
- package/dist/components/core/form/fields/SolidMediaMultipleField.d.ts.map +1 -1
- package/dist/components/core/form/fields/SolidMediaMultipleField.js +1 -1
- package/dist/components/core/form/fields/SolidMediaMultipleField.js.map +1 -1
- package/dist/components/core/form/fields/SolidMediaSingleField.d.ts.map +1 -1
- package/dist/components/core/form/fields/SolidMediaSingleField.js +1 -1
- package/dist/components/core/form/fields/SolidMediaSingleField.js.map +1 -1
- package/dist/components/core/form/fields/SolidSelectionDynamicField.d.ts.map +1 -1
- package/dist/components/core/form/fields/SolidSelectionDynamicField.js +12 -1
- package/dist/components/core/form/fields/SolidSelectionDynamicField.js.map +1 -1
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.d.ts.map +1 -1
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js +4 -0
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js.map +1 -1
- package/dist/components/core/form/fields/relations/SolidRelationOneToManyField.d.ts.map +1 -1
- package/dist/components/core/form/fields/relations/SolidRelationOneToManyField.js +9 -7
- package/dist/components/core/form/fields/relations/SolidRelationOneToManyField.js.map +1 -1
- package/dist/components/core/kanban/KanbanBoard.d.ts.map +1 -1
- package/dist/components/core/kanban/KanbanBoard.js +1 -0
- package/dist/components/core/kanban/KanbanBoard.js.map +1 -1
- package/dist/components/core/kanban/KanbanUserViewLayout.d.ts +2 -0
- package/dist/components/core/kanban/KanbanUserViewLayout.d.ts.map +1 -0
- package/dist/components/core/kanban/KanbanUserViewLayout.js +112 -0
- package/dist/components/core/kanban/KanbanUserViewLayout.js.map +1 -0
- package/dist/components/core/kanban/SolidKanbanView.d.ts.map +1 -1
- package/dist/components/core/kanban/SolidKanbanView.js +41 -35
- package/dist/components/core/kanban/SolidKanbanView.js.map +1 -1
- package/dist/components/core/kanban/SolidKanbanViewConfigure.d.ts +1 -1
- package/dist/components/core/kanban/SolidKanbanViewConfigure.d.ts.map +1 -1
- package/dist/components/core/kanban/SolidKanbanViewConfigure.js +2 -2
- package/dist/components/core/kanban/SolidKanbanViewConfigure.js.map +1 -1
- package/dist/components/core/list/SolidListColumnSelector.d.ts +2 -0
- package/dist/components/core/list/SolidListColumnSelector.d.ts.map +1 -0
- package/dist/components/core/list/SolidListColumnSelector.js +182 -0
- package/dist/components/core/list/SolidListColumnSelector.js.map +1 -0
- package/dist/components/core/list/SolidListView.d.ts.map +1 -1
- package/dist/components/core/list/SolidListView.js +48 -45
- package/dist/components/core/list/SolidListView.js.map +1 -1
- package/dist/components/core/list/SolidListViewConfigure.d.ts +1 -1
- package/dist/components/core/list/SolidListViewConfigure.d.ts.map +1 -1
- package/dist/components/core/list/SolidListViewConfigure.js +7 -49
- package/dist/components/core/list/SolidListViewConfigure.js.map +1 -1
- package/dist/redux/api/solidEntityApi.d.ts +1 -0
- package/dist/redux/api/solidEntityApi.d.ts.map +1 -1
- package/dist/redux/api/solidEntityApi.js +7 -0
- package/dist/redux/api/solidEntityApi.js.map +1 -1
- package/dist/resources/globals.css +1 -0
- package/package.json +1 -1
- package/src/components/common/SolidFormStepper.tsx +0 -4
- package/src/components/core/common/SolidGlobalSearchElement.tsx +14 -3
- package/src/components/core/form/SolidFormUserViewLayout.tsx +87 -0
- package/src/components/core/form/SolidFormView.tsx +30 -5
- package/src/components/core/form/fields/SolidMediaMultipleField.tsx +16 -14
- package/src/components/core/form/fields/SolidMediaSingleField.tsx +16 -14
- package/src/components/core/form/fields/SolidSelectionDynamicField.tsx +12 -4
- package/src/components/core/form/fields/relations/SolidRelationManyToOneField.tsx +5 -2
- package/src/components/core/form/fields/relations/SolidRelationOneToManyField.tsx +4 -2
- package/src/components/core/kanban/KanbanBoard.tsx +1 -0
- package/src/components/core/kanban/KanbanUserViewLayout.tsx +87 -0
- package/src/components/core/kanban/SolidKanbanView.tsx +18 -3
- package/src/components/core/kanban/SolidKanbanViewConfigure.tsx +3 -3
- package/src/components/core/list/SolidListColumnSelector.tsx +170 -0
- package/src/components/core/list/SolidListView.tsx +16 -12
- package/src/components/core/list/SolidListViewConfigure.tsx +2 -77
- package/src/redux/api/solidEntityApi.tsx +7 -0
- package/src/resources/globals.css +1 -0
|
@@ -34,10 +34,8 @@ export const SolidFormStepper = (props: Props) => {
|
|
|
34
34
|
|
|
35
35
|
setSolidWorkflowFieldValue(() => {
|
|
36
36
|
if (initialEntityData?.[solidWorkflowField] !== undefined) {
|
|
37
|
-
console.log("checkloginitial", initialEntityData[solidWorkflowField]);
|
|
38
37
|
return initialEntityData[solidWorkflowField];
|
|
39
38
|
} else if (defaultWorkflowFieldValue !== undefined) {
|
|
40
|
-
console.log("checklogdefault", defaultWorkflowFieldValue);
|
|
41
39
|
return defaultWorkflowFieldValue;
|
|
42
40
|
} else {
|
|
43
41
|
return activeStep;
|
|
@@ -98,7 +96,6 @@ export const SolidFormStepper = (props: Props) => {
|
|
|
98
96
|
|
|
99
97
|
const activeIndex = solidFormViewWorkflowData.findIndex((step: any) => step.value === solidWorkflowFieldValue);
|
|
100
98
|
const visibleSteps = solidFormViewWorkflowData.length > 5 ? solidFormViewWorkflowData.slice(0, 5) : solidFormViewWorkflowData;
|
|
101
|
-
console.log("activeIndex:", activeIndex, "solidWorkflowFieldValue:", solidWorkflowFieldValue);
|
|
102
99
|
|
|
103
100
|
return (
|
|
104
101
|
<>
|
|
@@ -112,7 +109,6 @@ export const SolidFormStepper = (props: Props) => {
|
|
|
112
109
|
const isLastVisible = index === visibleSteps.length - 1;
|
|
113
110
|
const isNextAfterActive = index === activeIndex + 1;
|
|
114
111
|
const isTwoStepsOnly = visibleSteps.length === 2;
|
|
115
|
-
console.log("isActive", isActive);
|
|
116
112
|
|
|
117
113
|
return (
|
|
118
114
|
<Button
|
|
@@ -383,6 +383,13 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, handleApplyCusto
|
|
|
383
383
|
return acc;
|
|
384
384
|
}, {} as Record<string, string[]>);
|
|
385
385
|
|
|
386
|
+
const handleRemoveChipGroup = (columnName: string) => {
|
|
387
|
+
const updatedChips = searchChips.filter(chip => chip.columnName !== columnName);
|
|
388
|
+
setSearchChips(updatedChips);
|
|
389
|
+
setHasSearched(true);
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
|
|
386
393
|
const CustomChip = () => (
|
|
387
394
|
<li>
|
|
388
395
|
<div className="custom-filter-chip-type">
|
|
@@ -397,7 +404,9 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, handleApplyCusto
|
|
|
397
404
|
</div>
|
|
398
405
|
|
|
399
406
|
{/* button to clear filter */}
|
|
400
|
-
<a onClick={clearCustomFilter}
|
|
407
|
+
<a onClick={clearCustomFilter}
|
|
408
|
+
style={{ cursor: "pointer" }}
|
|
409
|
+
>
|
|
401
410
|
<i className="pi pi-times ml-1">
|
|
402
411
|
</i></a>
|
|
403
412
|
</div>
|
|
@@ -421,8 +430,10 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, handleApplyCusto
|
|
|
421
430
|
</React.Fragment>
|
|
422
431
|
))}
|
|
423
432
|
{/* button to clear filter */}
|
|
424
|
-
<i className="pi pi-times ml-1"
|
|
425
|
-
|
|
433
|
+
<i className="pi pi-times ml-1"
|
|
434
|
+
style={{ cursor: "pointer" }}
|
|
435
|
+
onClick={() => handleRemoveChipGroup(column)}
|
|
436
|
+
> </i>
|
|
426
437
|
</div>
|
|
427
438
|
</li>
|
|
428
439
|
))}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useFormik } from "formik";
|
|
3
|
+
import { Button } from "primereact/button";
|
|
4
|
+
import { useSelector } from "react-redux";
|
|
5
|
+
import React, { useRef } from "react";
|
|
6
|
+
import { createSolidEntityApi } from "@/redux/api/solidEntityApi";
|
|
7
|
+
import { javascript } from "@codemirror/lang-javascript";
|
|
8
|
+
import { oneDark } from "@codemirror/theme-one-dark";
|
|
9
|
+
import CodeMirror, { EditorView } from "@uiw/react-codemirror";
|
|
10
|
+
import { Toast } from "primereact/toast";
|
|
11
|
+
|
|
12
|
+
export const SolidFormUserViewLayout = ({ solidFormViewMetaData, setLayoutDialogVisible }: any) => {
|
|
13
|
+
const toast = useRef<Toast>(null);
|
|
14
|
+
const { user } = useSelector((state: any) => state.auth);
|
|
15
|
+
const entityApi = createSolidEntityApi("userViewMetadata");
|
|
16
|
+
const { useUpsertSolidEntityMutation } = entityApi;
|
|
17
|
+
const [upsertUserView] = useUpsertSolidEntityMutation();
|
|
18
|
+
|
|
19
|
+
if (!solidFormViewMetaData?.data?.solidView) return null;
|
|
20
|
+
|
|
21
|
+
const solidView = solidFormViewMetaData.data.solidView;
|
|
22
|
+
|
|
23
|
+
const showToast = (severity: "success" | "error", summary: string, detail: string) => {
|
|
24
|
+
toast.current?.show({
|
|
25
|
+
severity,
|
|
26
|
+
summary,
|
|
27
|
+
detail,
|
|
28
|
+
life: 3000,
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const formik = useFormik({
|
|
33
|
+
initialValues: {
|
|
34
|
+
layoutString: JSON.stringify(solidView.layout, null, 2),
|
|
35
|
+
},
|
|
36
|
+
onSubmit: async (values) => {
|
|
37
|
+
const parsedLayout = JSON.parse(values.layoutString);
|
|
38
|
+
console.log("updatedLayout", parsedLayout);
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
if (solidView.id) {
|
|
42
|
+
const response = await upsertUserView({
|
|
43
|
+
userId: user?.user?.id,
|
|
44
|
+
viewMetadataId: solidView.id,
|
|
45
|
+
layout: JSON.stringify(parsedLayout)
|
|
46
|
+
}).unwrap();
|
|
47
|
+
console.log("Response", response);
|
|
48
|
+
if (response.statusCode === 200) {
|
|
49
|
+
showToast("success", "Layout", "Form Layout Updated successfully!");
|
|
50
|
+
setLayoutDialogVisible(false);
|
|
51
|
+
window.location.reload();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error("Update failed:", error);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<>
|
|
62
|
+
<Toast ref={toast} />
|
|
63
|
+
<form onSubmit={formik.handleSubmit}>
|
|
64
|
+
<CodeMirror
|
|
65
|
+
value={formik.values.layoutString}
|
|
66
|
+
height="500px"
|
|
67
|
+
theme={oneDark}
|
|
68
|
+
style={{ fontSize: '10px' }}
|
|
69
|
+
extensions={[javascript(), EditorView.lineWrapping]}
|
|
70
|
+
onChange={(value) => {
|
|
71
|
+
formik.setFieldValue("layoutString", value);
|
|
72
|
+
}}
|
|
73
|
+
/>
|
|
74
|
+
<div className="pt-3 flex gap-2">
|
|
75
|
+
<Button type="submit" label="Apply" size="small" />
|
|
76
|
+
<Button
|
|
77
|
+
type="button"
|
|
78
|
+
outlined
|
|
79
|
+
label="Cancel"
|
|
80
|
+
size="small"
|
|
81
|
+
onClick={() => setLayoutDialogVisible(false)}
|
|
82
|
+
/>
|
|
83
|
+
</div>
|
|
84
|
+
</form>
|
|
85
|
+
</>
|
|
86
|
+
);
|
|
87
|
+
};
|
|
@@ -43,6 +43,8 @@ import { SolidEmailField } from "./fields/SolidEmailField";
|
|
|
43
43
|
import { Panel } from "primereact/panel";
|
|
44
44
|
import { SolidFormStepper } from "@/components/common/SolidFormStepper";
|
|
45
45
|
import { SolidFormHeader } from "@/components/common/SolidFormHeader";
|
|
46
|
+
import { SolidFormUserViewLayout } from "./SolidFormUserViewLayout";
|
|
47
|
+
import { useSelector } from "react-redux";
|
|
46
48
|
|
|
47
49
|
export type SolidFormViewProps = {
|
|
48
50
|
moduleName: string;
|
|
@@ -342,7 +344,7 @@ const SolidPage = ({ attrs, children, key }: any) => (
|
|
|
342
344
|
// };
|
|
343
345
|
|
|
344
346
|
const SolidFormView = (params: SolidFormViewProps) => {
|
|
345
|
-
|
|
347
|
+
const { user } = useSelector((state: any) => state.auth);
|
|
346
348
|
const pathname = usePathname();
|
|
347
349
|
const router = useRouter();
|
|
348
350
|
const toast = useRef<Toast>(null);
|
|
@@ -352,6 +354,7 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
352
354
|
const [redirectToList, setRedirectToList] = useState(false);
|
|
353
355
|
|
|
354
356
|
const [isDeleteDialogVisible, setDeleteDialogVisible] = useState(false);
|
|
357
|
+
const [isLayoutDialogVisible, setLayoutDialogVisible] = useState(false);
|
|
355
358
|
|
|
356
359
|
const [actionsAllowed, setActionsAllowed] = useState<string[]>([]);
|
|
357
360
|
const [viewMode, setViewMode] = useState<"view" | "edit">("view");
|
|
@@ -437,7 +440,7 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
437
440
|
|
|
438
441
|
// - - - - - - - - - - - -- - - - - - - - - - - - METADATA here
|
|
439
442
|
// Get the form view layout & metadata first.
|
|
440
|
-
const formViewMetaDataQs = qs.stringify({ ...params, viewType: 'form' }, {
|
|
443
|
+
const formViewMetaDataQs = qs.stringify({ ...params, viewType: 'form', userId: user?.user?.id }, {
|
|
441
444
|
encodeValuesOnly: true,
|
|
442
445
|
});
|
|
443
446
|
const [formViewMetaData, setFormViewMetaData] = useState({});
|
|
@@ -919,7 +922,7 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
919
922
|
// const fieldMetadata = solidFieldsMetadata[attrs.name];
|
|
920
923
|
const fieldMetadata = solidFormViewMetaData.data.solidFieldsMetadata[attrs.name];
|
|
921
924
|
// Read only permission if there is no update permission on model and router doesnt contains new
|
|
922
|
-
const readOnlyPermission = !actionsAllowed.includes(`${updatePermission(params.modelName)}`) && params.id !== "new"
|
|
925
|
+
const readOnlyPermission = !actionsAllowed.includes(`${updatePermission(params.modelName)}`) && params.id !== "new";
|
|
923
926
|
return <SolidField
|
|
924
927
|
key={key}
|
|
925
928
|
field={element}
|
|
@@ -1042,6 +1045,7 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
1042
1045
|
</svg>}
|
|
1043
1046
|
/> */}
|
|
1044
1047
|
{params.embeded !== true &&
|
|
1048
|
+
params.id !== "new" &&
|
|
1045
1049
|
actionsAllowed.includes(`${deletePermission(params.modelName)}`) &&
|
|
1046
1050
|
!formViewLayout.attrs.readonly &&
|
|
1047
1051
|
<Button
|
|
@@ -1056,6 +1060,17 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
1056
1060
|
onClick={() => setDeleteDialogVisible(true)}
|
|
1057
1061
|
/>
|
|
1058
1062
|
}
|
|
1063
|
+
<Button
|
|
1064
|
+
text
|
|
1065
|
+
type="button"
|
|
1066
|
+
className="w-8rem text-left gap-2 purple-200"
|
|
1067
|
+
label="Layout"
|
|
1068
|
+
size="small"
|
|
1069
|
+
iconPos="left"
|
|
1070
|
+
severity="contrast"
|
|
1071
|
+
icon={'pi pi-objects-column'}
|
|
1072
|
+
onClick={() => setLayoutDialogVisible(true)}
|
|
1073
|
+
/>
|
|
1059
1074
|
</div>
|
|
1060
1075
|
</OverlayPanel>
|
|
1061
1076
|
</div>
|
|
@@ -1137,7 +1152,7 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
1137
1152
|
{params.embeded !== true &&
|
|
1138
1153
|
<SolidCancelButton />
|
|
1139
1154
|
}
|
|
1140
|
-
|
|
1155
|
+
{formActionDropdown()}
|
|
1141
1156
|
</div>
|
|
1142
1157
|
</>
|
|
1143
1158
|
) : (
|
|
@@ -1266,9 +1281,19 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
1266
1281
|
>
|
|
1267
1282
|
<p>Are you sure you want to delete?</p>
|
|
1268
1283
|
</Dialog>
|
|
1284
|
+
<Dialog
|
|
1285
|
+
visible={isLayoutDialogVisible}
|
|
1286
|
+
header="Change Form Layout"
|
|
1287
|
+
modal
|
|
1288
|
+
onHide={() => setLayoutDialogVisible(false)}
|
|
1289
|
+
contentStyle={{
|
|
1290
|
+
width: 800
|
|
1291
|
+
}}
|
|
1292
|
+
>
|
|
1293
|
+
<SolidFormUserViewLayout solidFormViewMetaData={solidFormViewMetaData} setLayoutDialogVisible={setLayoutDialogVisible} />
|
|
1294
|
+
</Dialog>
|
|
1269
1295
|
</div>
|
|
1270
1296
|
);
|
|
1271
|
-
|
|
1272
1297
|
}
|
|
1273
1298
|
};
|
|
1274
1299
|
|
|
@@ -240,21 +240,23 @@ export class SolidMediaMultipleField implements ISolidField {
|
|
|
240
240
|
{/* {fieldDescription && <span className="form_field_help">({fieldDescription}) </span>} */}
|
|
241
241
|
</label>
|
|
242
242
|
}
|
|
243
|
-
<div
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
{isFormFieldValid(formik, fieldLayoutInfo.attrs.name) && (
|
|
254
|
-
<div className="absolute mt-1">
|
|
255
|
-
<Message severity="error" text={formik?.errors[fieldLayoutInfo.attrs.name]?.toString()} />
|
|
243
|
+
<div className="relative">
|
|
244
|
+
<div
|
|
245
|
+
{...getRootProps()}
|
|
246
|
+
className="solid-dropzone-wrapper"
|
|
247
|
+
>
|
|
248
|
+
<input {...getInputProps()} />
|
|
249
|
+
<DropzonePlaceholder
|
|
250
|
+
mediaTypes={fieldMetadata.mediaTypes}
|
|
251
|
+
mediaMaxSizeKb={fieldMetadata.mediaMaxSizeKb}
|
|
252
|
+
/>
|
|
256
253
|
</div>
|
|
257
|
-
|
|
254
|
+
{isFormFieldValid(formik, fieldLayoutInfo.attrs.name) && (
|
|
255
|
+
<div className="absolute mt-1">
|
|
256
|
+
<Message severity="error" text={formik?.errors[fieldLayoutInfo.attrs.name]?.toString()} />
|
|
257
|
+
</div>
|
|
258
|
+
)}
|
|
259
|
+
</div>
|
|
258
260
|
{
|
|
259
261
|
fileSizeError &&
|
|
260
262
|
<Message severity="error" text={fileSizeError?.toString()} />
|
|
@@ -235,21 +235,23 @@ export class SolidMediaSingleField implements ISolidField {
|
|
|
235
235
|
{/* {fieldDescription && <span className="form_field_help">({fieldDescription}) </span>} */}
|
|
236
236
|
</label>
|
|
237
237
|
}
|
|
238
|
-
<div
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
{isFormFieldValid(formik, fieldLayoutInfo.attrs.name) && (
|
|
249
|
-
<div className="absolute mt-1">
|
|
250
|
-
<Message severity="error" text={formik?.errors[fieldLayoutInfo.attrs.name]?.toString()} />
|
|
238
|
+
<div className="relative">
|
|
239
|
+
<div
|
|
240
|
+
{...getRootProps()}
|
|
241
|
+
className="solid-dropzone-wrapper"
|
|
242
|
+
>
|
|
243
|
+
<input {...getInputProps()} />
|
|
244
|
+
<DropzonePlaceholder
|
|
245
|
+
mediaTypes={fieldMetadata.mediaTypes}
|
|
246
|
+
mediaMaxSizeKb={fieldMetadata.mediaMaxSizeKb}
|
|
247
|
+
/>
|
|
251
248
|
</div>
|
|
252
|
-
|
|
249
|
+
{isFormFieldValid(formik, fieldLayoutInfo.attrs.name) && (
|
|
250
|
+
<div className="absolute mt-1">
|
|
251
|
+
<Message severity="error" text={formik?.errors[fieldLayoutInfo.attrs.name]?.toString()} />
|
|
252
|
+
</div>
|
|
253
|
+
)}
|
|
254
|
+
</div>
|
|
253
255
|
{
|
|
254
256
|
fileSizeError &&
|
|
255
257
|
<Message severity="error" text={fileSizeError?.toString()} />
|
|
@@ -64,6 +64,7 @@ export class SolidSelectionDynamicField implements ISolidField {
|
|
|
64
64
|
|
|
65
65
|
const formDisabled = solidFormViewMetaData.data.solidView?.layout?.attrs?.disabled;
|
|
66
66
|
const formReadonly = solidFormViewMetaData.data.solidView?.layout?.attrs?.readonly;
|
|
67
|
+
const whereClause = fieldLayoutInfo.attrs.whereClause;
|
|
67
68
|
|
|
68
69
|
// selection dynamic specific code.
|
|
69
70
|
const [triggerGetSelectionDynamicValues] = useLazyGetSelectionDynamicValuesQuery();
|
|
@@ -77,11 +78,18 @@ export class SolidSelectionDynamicField implements ISolidField {
|
|
|
77
78
|
query: event.query,
|
|
78
79
|
fieldId: fieldMetadata.id
|
|
79
80
|
};
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
if (whereClause) {
|
|
82
|
+
queryData.query = whereClause;
|
|
83
|
+
}
|
|
84
|
+
let sdQs = qs.stringify(queryData, {
|
|
82
85
|
encodeValuesOnly: true,
|
|
86
|
+
encoder: (str, defaultEncoder, charset, type) => {
|
|
87
|
+
if (type === 'key' || type === 'value') {
|
|
88
|
+
if (str === queryData.query) return str;
|
|
89
|
+
}
|
|
90
|
+
return defaultEncoder(str);
|
|
91
|
+
}
|
|
83
92
|
});
|
|
84
|
-
|
|
85
93
|
// TODO: do error handling here, possible errors like modelname is incorrect etc...
|
|
86
94
|
const sdResponse = await triggerGetSelectionDynamicValues(sdQs);
|
|
87
95
|
|
|
@@ -98,7 +106,7 @@ export class SolidSelectionDynamicField implements ISolidField {
|
|
|
98
106
|
let DynamicWidget = getExtensionComponent("SolidFormFieldViewModeWidget");
|
|
99
107
|
const widgetProps = {
|
|
100
108
|
label: fieldLabel,
|
|
101
|
-
value: formik.values[fieldLayoutInfo.attrs.name],
|
|
109
|
+
value: formik.values[fieldLayoutInfo.attrs.name] && formik.values[fieldLayoutInfo.attrs.name].value,
|
|
102
110
|
}
|
|
103
111
|
return (
|
|
104
112
|
<>
|
|
@@ -78,6 +78,7 @@ export class SolidRelationManyToOneField implements ISolidField {
|
|
|
78
78
|
|
|
79
79
|
const formDisabled = solidFormViewMetaData.data.solidView?.layout?.attrs?.disabled;
|
|
80
80
|
const formReadonly = solidFormViewMetaData.data.solidView?.layout?.attrs?.readonly;
|
|
81
|
+
const whereClause = fieldLayoutInfo.attrs.whereClause;
|
|
81
82
|
|
|
82
83
|
const [autoCompleteItems, setAutoCompleteItems] = useState([]);
|
|
83
84
|
const autoCompleteSearch = async (event: AutoCompleteCompleteEvent) => {
|
|
@@ -93,10 +94,12 @@ export class SolidRelationManyToOneField implements ISolidField {
|
|
|
93
94
|
}
|
|
94
95
|
};
|
|
95
96
|
|
|
96
|
-
|
|
97
|
+
let autocompleteQs = qs.stringify(queryData, {
|
|
97
98
|
encodeValuesOnly: true,
|
|
98
99
|
});
|
|
99
|
-
|
|
100
|
+
if (whereClause) {
|
|
101
|
+
autocompleteQs = `${autocompleteQs}&${whereClause}`;
|
|
102
|
+
}
|
|
100
103
|
// TODO: do error handling here, possible errors like modelname is incorrect etc...
|
|
101
104
|
const autocompleteResponse = await triggerGetSolidEntities(autocompleteQs);
|
|
102
105
|
|
|
@@ -93,6 +93,7 @@ export class SolidRelationOneToManyField implements ISolidField {
|
|
|
93
93
|
inlineCreate: readOnlyPermission === false ? true : false,
|
|
94
94
|
customLayout: fieldLayoutInfo?.attrs?.inlineListLayout,
|
|
95
95
|
embeded: true,
|
|
96
|
+
id: this.fieldContext.data ? this?.fieldContext?.data?.id : 'new',
|
|
96
97
|
customFilter: {
|
|
97
98
|
[customFilter]: {
|
|
98
99
|
id: {
|
|
@@ -113,6 +114,7 @@ export class SolidRelationOneToManyField implements ISolidField {
|
|
|
113
114
|
inlineCreate: readOnlyPermission === false ? true : false,
|
|
114
115
|
customLayout: fieldLayoutInfo?.attrs?.inlineListLayout,
|
|
115
116
|
embeded: true,
|
|
117
|
+
id: this.fieldContext.data ? this?.fieldContext?.data?.id : 'new',
|
|
116
118
|
customFilter: {
|
|
117
119
|
[customFilter]: {
|
|
118
120
|
id: {
|
|
@@ -128,11 +130,11 @@ export class SolidRelationOneToManyField implements ISolidField {
|
|
|
128
130
|
embeded: true,
|
|
129
131
|
isCustomCreate: false,
|
|
130
132
|
customLayout: fieldLayoutInfo?.attrs?.inlineCreateLayout,
|
|
131
|
-
modelName: camelCase(this.fieldContext.fieldMetadata.relationCoModelSingularName)
|
|
133
|
+
modelName: camelCase(this.fieldContext.fieldMetadata.relationCoModelSingularName),
|
|
132
134
|
}
|
|
133
135
|
setformViewParams(formviewparams)
|
|
134
136
|
|
|
135
|
-
}, [])
|
|
137
|
+
}, [readOnlyPermission])
|
|
136
138
|
|
|
137
139
|
const fieldDisabled = fieldLayoutInfo.attrs?.disabled;
|
|
138
140
|
const fieldReadonly = fieldLayoutInfo.attrs?.readonly;
|
|
@@ -5,6 +5,7 @@ import React, { useState, useEffect } from "react";
|
|
|
5
5
|
import { DragDropContext, DropResult } from "@hello-pangea/dnd";
|
|
6
6
|
import axios from "axios";
|
|
7
7
|
import KanbanColumn from "./KanbanColumn";
|
|
8
|
+
import { Button } from "primereact/button";
|
|
8
9
|
|
|
9
10
|
// Define types for groupData and Grouped Data
|
|
10
11
|
interface Post {
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useFormik } from "formik";
|
|
3
|
+
import { Button } from "primereact/button";
|
|
4
|
+
import { useSelector } from "react-redux";
|
|
5
|
+
import React, { useRef } from "react";
|
|
6
|
+
import { createSolidEntityApi } from "@/redux/api/solidEntityApi";
|
|
7
|
+
import { javascript } from "@codemirror/lang-javascript";
|
|
8
|
+
import { oneDark } from "@codemirror/theme-one-dark";
|
|
9
|
+
import CodeMirror, { EditorView } from "@uiw/react-codemirror";
|
|
10
|
+
import { Toast } from "primereact/toast";
|
|
11
|
+
|
|
12
|
+
export const KanbanUserViewLayout = ({ solidKanbanViewMetaData, setLayoutDialogVisible }: any) => {
|
|
13
|
+
const toast = useRef<Toast>(null);
|
|
14
|
+
const { user } = useSelector((state: any) => state.auth);
|
|
15
|
+
const entityApi = createSolidEntityApi("userViewMetadata");
|
|
16
|
+
const { useUpsertSolidEntityMutation } = entityApi;
|
|
17
|
+
const [upsertUserView] = useUpsertSolidEntityMutation();
|
|
18
|
+
|
|
19
|
+
if (!solidKanbanViewMetaData?.data?.solidView) return null;
|
|
20
|
+
|
|
21
|
+
const solidView = solidKanbanViewMetaData.data.solidView;
|
|
22
|
+
|
|
23
|
+
const showToast = (severity: "success" | "error", summary: string, detail: string) => {
|
|
24
|
+
toast.current?.show({
|
|
25
|
+
severity,
|
|
26
|
+
summary,
|
|
27
|
+
detail,
|
|
28
|
+
life: 3000,
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const formik = useFormik({
|
|
33
|
+
initialValues: {
|
|
34
|
+
layoutString: JSON.stringify(solidView.layout, null, 2),
|
|
35
|
+
},
|
|
36
|
+
onSubmit: async (values) => {
|
|
37
|
+
const parsedLayout = JSON.parse(values.layoutString);
|
|
38
|
+
console.log("updatedLayout", parsedLayout);
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
if (solidView.id) {
|
|
42
|
+
const response = await upsertUserView({
|
|
43
|
+
userId: user?.user?.id,
|
|
44
|
+
viewMetadataId: solidView.id,
|
|
45
|
+
layout: JSON.stringify(parsedLayout),
|
|
46
|
+
}).unwrap();
|
|
47
|
+
console.log("Response", response);
|
|
48
|
+
if (response.statusCode === 200) {
|
|
49
|
+
showToast("success", "Layout", "Form Layout Updated successfully!");
|
|
50
|
+
setLayoutDialogVisible(false);
|
|
51
|
+
window.location.reload();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error("Update failed:", error);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<>
|
|
62
|
+
<Toast ref={toast} />
|
|
63
|
+
<form onSubmit={formik.handleSubmit}>
|
|
64
|
+
<CodeMirror
|
|
65
|
+
value={formik.values.layoutString}
|
|
66
|
+
height="500px"
|
|
67
|
+
theme={oneDark}
|
|
68
|
+
style={{ fontSize: '10px' }}
|
|
69
|
+
extensions={[javascript(), EditorView.lineWrapping]}
|
|
70
|
+
onChange={(value) => {
|
|
71
|
+
formik.setFieldValue("layoutString", value);
|
|
72
|
+
}}
|
|
73
|
+
/>
|
|
74
|
+
<div className="pt-3 flex gap-2">
|
|
75
|
+
<Button type="submit" label="Apply" size="small" />
|
|
76
|
+
<Button
|
|
77
|
+
type="button"
|
|
78
|
+
outlined
|
|
79
|
+
label="Cancel"
|
|
80
|
+
size="small"
|
|
81
|
+
onClick={() => setLayoutDialogVisible(false)}
|
|
82
|
+
/>
|
|
83
|
+
</div>
|
|
84
|
+
</form>
|
|
85
|
+
</>
|
|
86
|
+
);
|
|
87
|
+
};
|
|
@@ -28,6 +28,8 @@ import "yet-another-react-lightbox/styles.css";
|
|
|
28
28
|
import "yet-another-react-lightbox/plugins/counter.css";
|
|
29
29
|
import { useRouter, useSearchParams } from "next/navigation";
|
|
30
30
|
import { SolidKanbanViewConfigure } from "./SolidKanbanViewConfigure";
|
|
31
|
+
import { KanbanUserViewLayout } from "./KanbanUserViewLayout";
|
|
32
|
+
import { useSelector } from "react-redux";
|
|
31
33
|
|
|
32
34
|
|
|
33
35
|
|
|
@@ -39,6 +41,7 @@ type SolidKanbanViewParams = {
|
|
|
39
41
|
|
|
40
42
|
|
|
41
43
|
export const SolidKanbanView = (params: SolidKanbanViewParams) => {
|
|
44
|
+
const { user } = useSelector((state: any) => state.auth);
|
|
42
45
|
const solidGlobalSearchElementRef = useRef();
|
|
43
46
|
const searchParams = useSearchParams().toString(); // Converts the query params to a string
|
|
44
47
|
const router = useRouter();
|
|
@@ -62,6 +65,7 @@ export const SolidKanbanView = (params: SolidKanbanViewParams) => {
|
|
|
62
65
|
const [openLightbox, setOpenLightbox] = useState(false);
|
|
63
66
|
const [lightboxUrls, setLightboxUrls] = useState({});
|
|
64
67
|
const [filterQueryString, setFilterQueryString] = useState<any>();
|
|
68
|
+
const [isLayoutDialogVisible, setLayoutDialogVisible] = useState(false);
|
|
65
69
|
|
|
66
70
|
|
|
67
71
|
|
|
@@ -117,7 +121,7 @@ export const SolidKanbanView = (params: SolidKanbanViewParams) => {
|
|
|
117
121
|
} = entityApi;
|
|
118
122
|
|
|
119
123
|
// Get the kanban view layout & metadata first.
|
|
120
|
-
const kanbanViewMetaDataQs = qs.stringify({ ...params, viewType: 'kanban' }, {
|
|
124
|
+
const kanbanViewMetaDataQs = qs.stringify({ ...params, viewType: 'kanban', userId: user?.user?.id }, {
|
|
121
125
|
encodeValuesOnly: true,
|
|
122
126
|
});
|
|
123
127
|
const [kanbanViewMetaData, setKanbanViewMetaData] = useState<any>({});
|
|
@@ -706,14 +710,14 @@ export const SolidKanbanView = (params: SolidKanbanViewParams) => {
|
|
|
706
710
|
solidKanbanViewMetaData={solidKanbanViewMetaData}
|
|
707
711
|
actionsAllowed={actionsAllowed}
|
|
708
712
|
viewModes={viewModes}
|
|
709
|
-
|
|
713
|
+
setLayoutDialogVisible={setLayoutDialogVisible}
|
|
710
714
|
/>
|
|
711
715
|
{/* <SolidConfigureLayoutElement></SolidConfigureLayoutElement> */}
|
|
712
716
|
</div>
|
|
713
717
|
</div>
|
|
714
718
|
<style>{`.p-datatable .p-datatable-loading-overlay {background-color: rgba(0, 0, 0, 0.0);}`}</style>
|
|
715
719
|
{solidKanbanViewMetaData && kanbanViewData &&
|
|
716
|
-
<KanbanBoard groupedView={groupedView} kanbanViewData={kanbanViewData} solidKanbanViewMetaData={solidKanbanViewMetaData?.data} setKanbanViewData={setKanbanViewData} handleLoadMore={handleLoadMore} onDragEnd={onDragEnd} handleSwimLinPagination={handleSwimLinPagination} setLightboxUrls={setLightboxUrls} setOpenLightbox={setOpenLightbox}
|
|
720
|
+
<KanbanBoard groupedView={groupedView} kanbanViewData={kanbanViewData} solidKanbanViewMetaData={solidKanbanViewMetaData?.data} setKanbanViewData={setKanbanViewData} handleLoadMore={handleLoadMore} onDragEnd={onDragEnd} handleSwimLinPagination={handleSwimLinPagination} setLightboxUrls={setLightboxUrls} setOpenLightbox={setOpenLightbox} editButtonUrl={editButtonUrl}></KanbanBoard>
|
|
717
721
|
}
|
|
718
722
|
|
|
719
723
|
<Dialog
|
|
@@ -738,6 +742,17 @@ export const SolidKanbanView = (params: SolidKanbanViewParams) => {
|
|
|
738
742
|
slides={lightboxUrls}
|
|
739
743
|
/>
|
|
740
744
|
}
|
|
745
|
+
<Dialog
|
|
746
|
+
visible={isLayoutDialogVisible}
|
|
747
|
+
header="Change Kanban Layout"
|
|
748
|
+
modal
|
|
749
|
+
onHide={() => setLayoutDialogVisible(false)}
|
|
750
|
+
contentStyle={{
|
|
751
|
+
width: 800
|
|
752
|
+
}}
|
|
753
|
+
>
|
|
754
|
+
<KanbanUserViewLayout solidKanbanViewMetaData={solidKanbanViewMetaData} setLayoutDialogVisible={setLayoutDialogVisible} />
|
|
755
|
+
</Dialog>
|
|
741
756
|
</div>
|
|
742
757
|
);
|
|
743
758
|
};
|
|
@@ -7,7 +7,7 @@ import { OverlayPanel } from 'primereact/overlaypanel';
|
|
|
7
7
|
import { RadioButton } from 'primereact/radiobutton';
|
|
8
8
|
import React, { useEffect, useRef, useState } from 'react'
|
|
9
9
|
|
|
10
|
-
export const SolidKanbanViewConfigure = ({ solidKanbanViewMetaData, actionsAllowed, viewModes }: any) => {
|
|
10
|
+
export const SolidKanbanViewConfigure = ({ solidKanbanViewMetaData, actionsAllowed, setLayoutDialogVisible, viewModes }: any) => {
|
|
11
11
|
const op = useRef(null);
|
|
12
12
|
const customizeLayout = useRef<OverlayPanel | null>(null);
|
|
13
13
|
const pathname = usePathname();
|
|
@@ -68,7 +68,7 @@ export const SolidKanbanViewConfigure = ({ solidKanbanViewMetaData, actionsAllow
|
|
|
68
68
|
<div className="flex flex-column">
|
|
69
69
|
<Button text icon='pi pi-download' label="Import" size="small" severity="secondary" className="text-left gap-2 text-base" />
|
|
70
70
|
<Button text icon='pi pi-upload' label="Export" size="small" severity="secondary" className="text-left gap-2 text-base" />
|
|
71
|
-
|
|
71
|
+
<Button
|
|
72
72
|
text
|
|
73
73
|
type="button"
|
|
74
74
|
className="w-8rem text-left gap-2 purple-200"
|
|
@@ -78,7 +78,7 @@ export const SolidKanbanViewConfigure = ({ solidKanbanViewMetaData, actionsAllow
|
|
|
78
78
|
severity="contrast"
|
|
79
79
|
icon={'pi pi-objects-column'}
|
|
80
80
|
onClick={() => setLayoutDialogVisible(true)}
|
|
81
|
-
/>
|
|
81
|
+
/>
|
|
82
82
|
</div>
|
|
83
83
|
</div>
|
|
84
84
|
<Divider className="m-0" />
|