@solidstarters/solid-core-ui 1.1.55 → 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.
Files changed (69) hide show
  1. package/dist/components/common/SolidFormStepper.d.ts.map +1 -1
  2. package/dist/components/common/SolidFormStepper.js +0 -4
  3. package/dist/components/common/SolidFormStepper.js.map +1 -1
  4. package/dist/components/core/form/SolidFormUserViewLayout.d.ts +2 -0
  5. package/dist/components/core/form/SolidFormUserViewLayout.d.ts.map +1 -0
  6. package/dist/components/core/form/SolidFormUserViewLayout.js +112 -0
  7. package/dist/components/core/form/SolidFormUserViewLayout.js.map +1 -0
  8. package/dist/components/core/form/SolidFormView.d.ts.map +1 -1
  9. package/dist/components/core/form/SolidFormView.js +29 -22
  10. package/dist/components/core/form/SolidFormView.js.map +1 -1
  11. package/dist/components/core/form/fields/SolidMediaMultipleField.d.ts.map +1 -1
  12. package/dist/components/core/form/fields/SolidMediaMultipleField.js +1 -1
  13. package/dist/components/core/form/fields/SolidMediaMultipleField.js.map +1 -1
  14. package/dist/components/core/form/fields/SolidMediaSingleField.d.ts.map +1 -1
  15. package/dist/components/core/form/fields/SolidMediaSingleField.js +1 -1
  16. package/dist/components/core/form/fields/SolidMediaSingleField.js.map +1 -1
  17. package/dist/components/core/form/fields/SolidSelectionDynamicField.d.ts.map +1 -1
  18. package/dist/components/core/form/fields/SolidSelectionDynamicField.js +12 -1
  19. package/dist/components/core/form/fields/SolidSelectionDynamicField.js.map +1 -1
  20. package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.d.ts.map +1 -1
  21. package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js +4 -0
  22. package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js.map +1 -1
  23. package/dist/components/core/form/fields/relations/SolidRelationOneToManyField.d.ts.map +1 -1
  24. package/dist/components/core/form/fields/relations/SolidRelationOneToManyField.js +9 -7
  25. package/dist/components/core/form/fields/relations/SolidRelationOneToManyField.js.map +1 -1
  26. package/dist/components/core/kanban/KanbanUserViewLayout.d.ts +2 -0
  27. package/dist/components/core/kanban/KanbanUserViewLayout.d.ts.map +1 -0
  28. package/dist/components/core/kanban/KanbanUserViewLayout.js +112 -0
  29. package/dist/components/core/kanban/KanbanUserViewLayout.js.map +1 -0
  30. package/dist/components/core/kanban/SolidKanbanView.d.ts.map +1 -1
  31. package/dist/components/core/kanban/SolidKanbanView.js +41 -35
  32. package/dist/components/core/kanban/SolidKanbanView.js.map +1 -1
  33. package/dist/components/core/kanban/SolidKanbanViewConfigure.d.ts +1 -1
  34. package/dist/components/core/kanban/SolidKanbanViewConfigure.d.ts.map +1 -1
  35. package/dist/components/core/kanban/SolidKanbanViewConfigure.js +2 -2
  36. package/dist/components/core/kanban/SolidKanbanViewConfigure.js.map +1 -1
  37. package/dist/components/core/list/SolidListColumnSelector.d.ts +2 -0
  38. package/dist/components/core/list/SolidListColumnSelector.d.ts.map +1 -0
  39. package/dist/components/core/list/SolidListColumnSelector.js +182 -0
  40. package/dist/components/core/list/SolidListColumnSelector.js.map +1 -0
  41. package/dist/components/core/list/SolidListView.d.ts.map +1 -1
  42. package/dist/components/core/list/SolidListView.js +48 -45
  43. package/dist/components/core/list/SolidListView.js.map +1 -1
  44. package/dist/components/core/list/SolidListViewConfigure.d.ts +1 -1
  45. package/dist/components/core/list/SolidListViewConfigure.d.ts.map +1 -1
  46. package/dist/components/core/list/SolidListViewConfigure.js +7 -49
  47. package/dist/components/core/list/SolidListViewConfigure.js.map +1 -1
  48. package/dist/redux/api/solidEntityApi.d.ts +1 -0
  49. package/dist/redux/api/solidEntityApi.d.ts.map +1 -1
  50. package/dist/redux/api/solidEntityApi.js +7 -0
  51. package/dist/redux/api/solidEntityApi.js.map +1 -1
  52. package/dist/resources/globals.css +1 -0
  53. package/package.json +1 -1
  54. package/src/components/common/SolidFormStepper.tsx +0 -4
  55. package/src/components/core/form/SolidFormUserViewLayout.tsx +87 -0
  56. package/src/components/core/form/SolidFormView.tsx +30 -5
  57. package/src/components/core/form/fields/SolidMediaMultipleField.tsx +16 -14
  58. package/src/components/core/form/fields/SolidMediaSingleField.tsx +16 -14
  59. package/src/components/core/form/fields/SolidSelectionDynamicField.tsx +12 -4
  60. package/src/components/core/form/fields/relations/SolidRelationManyToOneField.tsx +5 -2
  61. package/src/components/core/form/fields/relations/SolidRelationOneToManyField.tsx +4 -2
  62. package/src/components/core/kanban/KanbanUserViewLayout.tsx +87 -0
  63. package/src/components/core/kanban/SolidKanbanView.tsx +18 -3
  64. package/src/components/core/kanban/SolidKanbanViewConfigure.tsx +3 -3
  65. package/src/components/core/list/SolidListColumnSelector.tsx +170 -0
  66. package/src/components/core/list/SolidListView.tsx +16 -12
  67. package/src/components/core/list/SolidListViewConfigure.tsx +2 -77
  68. package/src/redux/api/solidEntityApi.tsx +7 -0
  69. package/src/resources/globals.css +1 -0
@@ -240,21 +240,23 @@ export class SolidMediaMultipleField implements ISolidField {
240
240
  {/* &nbsp; {fieldDescription && <span className="form_field_help">({fieldDescription}) </span>} */}
241
241
  </label>
242
242
  }
243
- <div
244
- {...getRootProps()}
245
- className="solid-dropzone-wrapper"
246
- >
247
- <input {...getInputProps()} />
248
- <DropzonePlaceholder
249
- mediaTypes={fieldMetadata.mediaTypes}
250
- mediaMaxSizeKb={fieldMetadata.mediaMaxSizeKb}
251
- />
252
- </div>
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
  {/* &nbsp; {fieldDescription && <span className="form_field_help">({fieldDescription}) </span>} */}
236
236
  </label>
237
237
  }
238
- <div
239
- {...getRootProps()}
240
- className="solid-dropzone-wrapper"
241
- >
242
- <input {...getInputProps()} />
243
- <DropzonePlaceholder
244
- mediaTypes={fieldMetadata.mediaTypes}
245
- mediaMaxSizeKb={fieldMetadata.mediaMaxSizeKb}
246
- />
247
- </div>
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
- const sdQs = qs.stringify(queryData, {
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
- const autocompleteQs = qs.stringify(queryData, {
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;
@@ -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
- // setLayoutDialogVisible={setLayoutDialogVisible}
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} editButtonUrl={editButtonUrl}></KanbanBoard>
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
- {/* <Button
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" />
@@ -0,0 +1,170 @@
1
+ "use client"
2
+ import { useFormik } from 'formik';
3
+ import { Button } from 'primereact/button';
4
+ import { Checkbox, CheckboxChangeEvent } from 'primereact/checkbox';
5
+ import React, { useEffect, useRef, useState } from 'react'
6
+ import qs from "qs";
7
+ import { useSelector } from 'react-redux';
8
+ import { createSolidEntityApi } from '@/redux/api/solidEntityApi';
9
+ import { Toast } from "primereact/toast";
10
+
11
+ interface FieldMetadata {
12
+ displayName: string;
13
+ }
14
+
15
+ interface FilterColumns {
16
+ name: string;
17
+ key: string;
18
+ }
19
+
20
+ export const SolidListColumnSelector = ({ listViewMetaData }: any) => {
21
+ const toast = useRef<Toast>(null);
22
+
23
+ const { user } = useSelector((state: any) => state.auth);
24
+ const entityApi = createSolidEntityApi('userViewMetadata');
25
+ const {
26
+ useUpsertSolidEntityMutation
27
+ } = entityApi;
28
+
29
+ const [upsertUserView, { isLoading, error: viewCreateError, isSuccess, data: data }] = useUpsertSolidEntityMutation();
30
+ const showToast = (severity: "success" | "error", summary: string, detail: string) => {
31
+ toast.current?.show({
32
+ severity,
33
+ summary,
34
+ detail,
35
+ life: 3000,
36
+ });
37
+ };
38
+
39
+ if (!listViewMetaData) {
40
+ return;
41
+ }
42
+ if (!listViewMetaData.data) {
43
+ return;
44
+ }
45
+
46
+ const solidView = listViewMetaData?.data?.solidView;
47
+
48
+ // This is a key value map of field name vs field metadata.
49
+ const solidFieldsMetadata = listViewMetaData?.data?.solidFieldsMetadata as Record<string, FieldMetadata>;
50
+
51
+
52
+ if (!solidView || !solidFieldsMetadata) {
53
+ return;
54
+ }
55
+
56
+ const checkedFieldNames = new Set(solidView.layout.children.map((col: { attrs: { name: string } }) => col.attrs.name));
57
+
58
+ const solidListColumns: FilterColumns[] = Object.entries(solidFieldsMetadata).map(([key, field]) => ({
59
+ name: field.displayName,
60
+ key,
61
+ }));
62
+
63
+ const formik = useFormik({
64
+ initialValues: {
65
+ selectedColumns: solidListColumns.filter(col => checkedFieldNames.has(col.key)),
66
+ },
67
+ onSubmit: async (values) => {
68
+ const selectedKeys = values.selectedColumns.map(col => col.key);
69
+
70
+ // Step 1: Extract current children
71
+ const currentChildren = solidView.layout.children;
72
+
73
+ // Step 2: Create a map of all available metadata
74
+ const allFieldMeta = solidFieldsMetadata;
75
+
76
+ // Step 3: Filter children to include only selected keys
77
+ const newChildren = selectedKeys.map((key) => {
78
+ const existingChild = currentChildren.find((child: any) => child.attrs.name === key);
79
+ if (existingChild) {
80
+ return existingChild; // keep original config
81
+ } else {
82
+ // construct a new one if it wasn't in the original
83
+ return {
84
+ type: 'field',
85
+ attrs: {
86
+ name: key,
87
+ label: allFieldMeta[key]?.displayName || key,
88
+ sortable: true,
89
+ filterable: true,
90
+ }
91
+ };
92
+ }
93
+ });
94
+
95
+ // Now build updated solidView
96
+ const updatedView = {
97
+ layout: {
98
+ ...solidView.layout,
99
+ children: newChildren
100
+ }
101
+ };
102
+
103
+ try {
104
+ if (listViewMetaData?.data?.solidView?.id) {
105
+ // Update existing user view
106
+ const response = await upsertUserView({
107
+ userId: user?.user?.id,
108
+ viewMetadataId: listViewMetaData?.data?.solidView?.id,
109
+ layout: JSON.stringify(updatedView.layout),
110
+ }).unwrap();
111
+ if (response.statusCode === 200) {
112
+ showToast("success", "Layout", "Form Layout Updated successfully!");
113
+ window.location.reload();
114
+ }
115
+ console.log("Successfully updated:", response);
116
+ } else {
117
+ // Create new user view
118
+ console.log("Error:");
119
+ }
120
+ } catch (error) {
121
+ console.error("Error updating user view:", error);
122
+ }
123
+
124
+ console.log("Updated solidView", updatedView);
125
+
126
+ },
127
+ });
128
+
129
+ return (
130
+ <>
131
+ <Toast ref={toast} />
132
+ <form onSubmit={formik.handleSubmit} className="flex flex-column gap-1 p-1">
133
+ <div className="flex flex-column gap-3 px-3 cogwheel-column-filter" style={{ maxHeight: 400, overflowY: 'auto' }}>
134
+ {solidListColumns.map((column) => {
135
+ return (
136
+ <div key={column.key} className="flex align-items-center gap-1">
137
+ <Checkbox
138
+ inputId={column.key}
139
+ name="selectedColumns"
140
+ value={column}
141
+ onChange={(e) => {
142
+ const isChecked = formik.values.selectedColumns.some(item => item.key === column.key);
143
+ formik.setFieldValue(
144
+ "selectedColumns",
145
+ isChecked
146
+ ? formik.values.selectedColumns.filter(item => item.key !== column.key)
147
+ : [...formik.values.selectedColumns, column]
148
+ );
149
+ }}
150
+ checked={formik.values.selectedColumns.some(item => item.key === column.key)}
151
+ className="text-base"
152
+ />
153
+ <label htmlFor={column.key} className="ml-2 text-base">
154
+ {column.name}
155
+ </label>
156
+ </div>
157
+ );
158
+ })}
159
+ </div>
160
+ <div className="p-3 flex gap-2">
161
+ <Button type='submit' label="Apply" size="small" />
162
+ <Button type='button' outlined label="Cancel" size="small"
163
+ // @ts-ignore
164
+ onClick={(e) => op.current.hide(e)}
165
+ />
166
+ </div>
167
+ </form>
168
+ </>
169
+ )
170
+ }
@@ -43,6 +43,7 @@ import Download from "yet-another-react-lightbox/plugins/download";
43
43
  import "yet-another-react-lightbox/styles.css";
44
44
  import "yet-another-react-lightbox/plugins/counter.css";
45
45
  import { SolidListViewConfigure } from "./SolidListViewConfigure";
46
+ import { useSelector } from "react-redux";
46
47
 
47
48
 
48
49
  const getRandomInt = (min: number, max: number) => {
@@ -91,6 +92,7 @@ type SolidListViewParams = {
91
92
  export const SolidListView = (params: SolidListViewParams) => {
92
93
 
93
94
  const solidGlobalSearchElementRef = useRef();
95
+ const { user } = useSelector((state: any) => state.auth);
94
96
 
95
97
 
96
98
  const router = useRouter()
@@ -148,7 +150,7 @@ export const SolidListView = (params: SolidListViewParams) => {
148
150
  } = entityApi;
149
151
 
150
152
  // Get the list view layout & metadata first.
151
- const listViewMetaDataQs = qs.stringify({ modelName: params.modelName, moduleName: params.moduleName, viewType: 'list' }, {
153
+ const listViewMetaDataQs = qs.stringify({ modelName: params.modelName, moduleName: params.moduleName, viewType: 'list', userId: user?.user?.id }, {
152
154
  encodeValuesOnly: true,
153
155
  });
154
156
  const [listViewMetaData, setListViewMetaData] = useState({});
@@ -722,23 +724,25 @@ export const SolidListView = (params: SolidListViewParams) => {
722
724
  {actionsAllowed.includes(`${createPermission(params.modelName)}`) && solidListViewMetaData?.data?.solidView?.layout?.attrs?.create !== false && params.embeded !== true &&
723
725
  <SolidCreateButton url={createButtonUrl} />
724
726
  }
725
- {actionsAllowed.includes(`${createPermission(params.modelName)}`) && solidListViewMetaData?.data?.solidView?.layout?.attrs?.create !== false && params.embeded == true && params.inlineCreate == true &&
727
+ {actionsAllowed.includes(`${createPermission(params.modelName)}`) && solidListViewMetaData?.data?.solidView?.layout?.attrs?.create !== false && params.embeded == true && params.inlineCreate == true && params.id !== 'new' &&
726
728
  // < SolidCreateButton url={createButtonUrl} />
727
729
  <Button type="button" icon="pi pi-plus" label="Add" size='small'
728
730
  onClick={() => params.handlePopUpOpen("new")}
729
731
  ></Button>
730
732
  }
731
733
  {/* Button For Manual Refresh */}
732
- <Button
733
- type="button"
734
- size="small"
735
- icon="pi pi-refresh"
736
- severity="secondary"
737
- outlined
738
- onClick={() => {
739
- setQueryString(first, rows, sortField, sortOrder, filters, showArchived);
740
- }}
741
- />
734
+ {params.embeded !== true &&
735
+ <Button
736
+ type="button"
737
+ size="small"
738
+ icon="pi pi-refresh"
739
+ severity="secondary"
740
+ outlined
741
+ onClick={() => {
742
+ setQueryString(first, rows, sortField, sortOrder, filters, showArchived);
743
+ }}
744
+ />
745
+ }
742
746
  {showArchived && <Button type="button" icon="pi pi-refresh" label="Recover" size='small' severity="secondary"
743
747
  onClick={() => setRecoverDialogVisible(true)}
744
748
  ></Button>}