@solidstarters/solid-core-ui 1.1.7 → 1.1.9

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 (72) hide show
  1. package/dist/components/auth/SolidForgotPassword.js +2 -2
  2. package/dist/components/auth/SolidForgotPassword.js.map +1 -1
  3. package/dist/components/auth/SolidLogin.js +4 -4
  4. package/dist/components/auth/SolidLogin.js.map +1 -1
  5. package/dist/components/core/common/LoadDynamicJsxComponent.d.ts.map +1 -1
  6. package/dist/components/core/common/LoadDynamicJsxComponent.js +42 -61
  7. package/dist/components/core/common/LoadDynamicJsxComponent.js.map +1 -1
  8. package/dist/components/core/common/SolidGlobalSearchElement.d.ts.map +1 -1
  9. package/dist/components/core/common/SolidGlobalSearchElement.js +6 -5
  10. package/dist/components/core/common/SolidGlobalSearchElement.js.map +1 -1
  11. package/dist/components/core/extension/solid-core/modelMetadata/list/GenerateModelCodeRowAction.d.ts +2 -1
  12. package/dist/components/core/extension/solid-core/modelMetadata/list/GenerateModelCodeRowAction.d.ts.map +1 -1
  13. package/dist/components/core/extension/solid-core/modelMetadata/list/GenerateModelCodeRowAction.js +28 -7
  14. package/dist/components/core/extension/solid-core/modelMetadata/list/GenerateModelCodeRowAction.js.map +1 -1
  15. package/dist/components/core/extension/solid-core/moduleMetadata/list/GenerateModuleCodeRowAction.d.ts +2 -1
  16. package/dist/components/core/extension/solid-core/moduleMetadata/list/GenerateModuleCodeRowAction.d.ts.map +1 -1
  17. package/dist/components/core/extension/solid-core/moduleMetadata/list/GenerateModuleCodeRowAction.js +10 -8
  18. package/dist/components/core/extension/solid-core/moduleMetadata/list/GenerateModuleCodeRowAction.js.map +1 -1
  19. package/dist/components/core/filter/fields/SolidIntField.js +2 -2
  20. package/dist/components/core/filter/fields/SolidIntField.js.map +1 -1
  21. package/dist/components/core/list/SolidListView.d.ts.map +1 -1
  22. package/dist/components/core/list/SolidListView.js +99 -21
  23. package/dist/components/core/list/SolidListView.js.map +1 -1
  24. package/dist/components/core/model/CreateModel.d.ts.map +1 -1
  25. package/dist/components/core/model/CreateModel.js +1 -1
  26. package/dist/components/core/model/CreateModel.js.map +1 -1
  27. package/dist/components/core/model/FieldMetaData.d.ts +1 -1
  28. package/dist/components/core/model/FieldMetaData.d.ts.map +1 -1
  29. package/dist/components/core/model/FieldMetaData.js +5 -4
  30. package/dist/components/core/model/FieldMetaData.js.map +1 -1
  31. package/dist/components/core/model/FieldMetaDataForm.d.ts +1 -1
  32. package/dist/components/core/model/FieldMetaDataForm.d.ts.map +1 -1
  33. package/dist/components/core/model/FieldMetaDataForm.js +44 -43
  34. package/dist/components/core/model/FieldMetaDataForm.js.map +1 -1
  35. package/dist/components/core/model/ModelMetaData.d.ts.map +1 -1
  36. package/dist/components/core/model/ModelMetaData.js +10 -3
  37. package/dist/components/core/model/ModelMetaData.js.map +1 -1
  38. package/dist/components/layout/user-profile-menu.d.ts.map +1 -1
  39. package/dist/components/layout/user-profile-menu.js +3 -1
  40. package/dist/components/layout/user-profile-menu.js.map +1 -1
  41. package/dist/index.d.ts +2 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +2 -0
  44. package/dist/index.js.map +1 -1
  45. package/dist/redux/api/solidEntityApi.d.ts +2 -0
  46. package/dist/redux/api/solidEntityApi.d.ts.map +1 -1
  47. package/dist/redux/api/solidEntityApi.js +10 -0
  48. package/dist/redux/api/solidEntityApi.js.map +1 -1
  49. package/dist/redux/api/solidSettingsApi.js +1 -1
  50. package/dist/redux/api/solidSettingsApi.js.map +1 -1
  51. package/dist/redux/api/testApi.d.ts +5 -0
  52. package/dist/redux/api/testApi.d.ts.map +1 -0
  53. package/dist/redux/api/testApi.js +19 -0
  54. package/dist/redux/api/testApi.js.map +1 -0
  55. package/package.json +1 -1
  56. package/src/components/auth/SolidForgotPassword.tsx +2 -2
  57. package/src/components/auth/SolidLogin.tsx +5 -5
  58. package/src/components/core/common/LoadDynamicJsxComponent.tsx +49 -24
  59. package/src/components/core/common/SolidGlobalSearchElement.tsx +6 -2
  60. package/src/components/core/extension/solid-core/modelMetadata/list/GenerateModelCodeRowAction.tsx +18 -6
  61. package/src/components/core/extension/solid-core/moduleMetadata/list/GenerateModuleCodeRowAction.tsx +5 -4
  62. package/src/components/core/filter/fields/SolidIntField.tsx +2 -2
  63. package/src/components/core/list/SolidListView.tsx +118 -8
  64. package/src/components/core/model/CreateModel.tsx +1 -0
  65. package/src/components/core/model/FieldMetaData.tsx +22 -3
  66. package/src/components/core/model/FieldMetaDataForm.tsx +24 -19
  67. package/src/components/core/model/ModelMetaData.tsx +10 -3
  68. package/src/components/layout/user-profile-menu.tsx +6 -1
  69. package/src/index.ts +2 -0
  70. package/src/redux/api/solidEntityApi.tsx +11 -0
  71. package/src/redux/api/solidSettingsApi.tsx +1 -1
  72. package/src/redux/api/testApi.ts +21 -0
@@ -1,22 +1,34 @@
1
1
  'use client';
2
2
  import { useGenerateCodeForModelMutation } from "@/redux/api/modelApi";
3
+ import { useSeederMutation } from "@/redux/api/testApi";
3
4
  import { Button } from "primereact/button";
5
+ import { useEffect } from "react";
4
6
 
5
7
 
6
- export const GenerateModelCodeRowAction = ({ context }: any) => {
7
-
8
+ const GenerateModelCodeRowAction = ({ context }: any) => {
8
9
  const [
9
10
  generateCode,
10
11
  { isLoading: isGenerateCodeUpdating, isSuccess: isGenerateCodeSuceess, isError: isGenerateCodeError, error: generateCodeError, data: generateCodeData },
11
12
  ] = useGenerateCodeForModelMutation();
12
13
 
14
+ const [triggerSeeder, {data}] = useSeederMutation();
15
+
13
16
 
14
17
  const generateCodeHandler = async () => {
15
- const response = await generateCode({ id: context.rowData.id })
16
- context.closeCustomRowActionPopup();
18
+ const response = await generateCode({ id: context?.rowData?.id });
19
+ context.closeListViewRowActionPopup();
17
20
  console.log("response", response);
18
21
  }
19
22
 
23
+ useEffect(() => {
24
+ const seeder = async () => {
25
+ if(isGenerateCodeSuceess) {
26
+ await triggerSeeder("ModuleMetadataSeederService");
27
+ }
28
+ }
29
+ seeder();
30
+ }, [isGenerateCodeSuceess])
31
+
20
32
  return (
21
33
  <div>
22
34
  <p className="">Click Ok to proceed with model code generation, please note that if the file already exists and <br></br>you have made custom changes to this file we will create a .bkp file as a backup of the existing file.</p>
@@ -29,10 +41,10 @@ export const GenerateModelCodeRowAction = ({ context }: any) => {
29
41
  </ul>
30
42
  <div className="flex gap-5 justify-content-center">
31
43
  <Button label="Ok" icon="pi pi-check" className='small-button' severity="danger" autoFocus onClick={generateCodeHandler} />
32
- <Button label="Cancel" icon="pi pi-times" className='small-button' onClick={() => context.closeCustomRowActionPopup()} />
44
+ <Button label="Cancel" icon="pi pi-times" className='small-button' onClick={() => context.closeListViewRowActionPopup()} />
33
45
  </div>
34
46
  </div >
35
47
  )
36
48
  }
37
49
 
38
-
50
+ export default GenerateModelCodeRowAction;
@@ -3,15 +3,15 @@ import { useGenerateCodeFormoduleMutation } from "@/redux/api/moduleApi";
3
3
  import { Button } from "primereact/button";
4
4
 
5
5
 
6
- export const GenerateModuleCodeRowAction = ({ context, closeCustomRowActionPopup }: any) => {
6
+ const GenerateModuleCodeRowAction = ({ context }: any) => {
7
7
  const [
8
8
  generateCode,
9
9
  { isLoading: isGenerateCodeUpdating, isSuccess: isGenerateCodeSuceess, isError: isGenerateCodeError, error: generateCodeError, data: generateCodeData },
10
10
  ] = useGenerateCodeFormoduleMutation();
11
11
 
12
12
  const generateCodeHandler = async () => {
13
- const response = await generateCode({ id: context.rowData.id })
14
- closeCustomRowActionPopup()
13
+ const response = await generateCode({ id: context?.rowData?.id })
14
+ context.closeListViewRowActionPopup();
15
15
 
16
16
  }
17
17
 
@@ -20,9 +20,10 @@ export const GenerateModuleCodeRowAction = ({ context, closeCustomRowActionPopup
20
20
  <p className="text-center">Click Ok to proceed with module code generation, please note that if the file already exists and <br></br>you have made custom changes to this file we will create a .bkp file as a backup of the existing file.</p>
21
21
  <div className="flex gap-5 justify-content-center">
22
22
  <Button label="Ok" icon="pi pi-check" className='small-button' severity="danger" autoFocus onClick={generateCodeHandler} />
23
- <Button label="Cancel" icon="pi pi-times" className='small-button' onClick={closeCustomRowActionPopup} />
23
+ <Button label="Cancel" icon="pi pi-times" className='small-button' onClick={() => context.closeListViewRowActionPopup()} />
24
24
  </div>
25
25
  </div >
26
26
  )
27
27
  }
28
28
 
29
+ export default GenerateModuleCodeRowAction;
@@ -6,8 +6,8 @@ import { InputTypes, SolidVarInputsFilterElement } from '../SolidVarInputsFilter
6
6
  const SolidIntField = ({ fieldMetadata, onChange, index, rule }: SolidFilterFieldsParams) => {
7
7
  // const filterable = column.attrs.filterable;
8
8
  const filterMatchModeOptions = [
9
- { label: 'Equals', value: "$eqi" },
10
- { label: 'Not Equals', value: "$nei" },
9
+ { label: 'Equals', value: "$eq" },
10
+ { label: 'Not Equals', value: "$ne" },
11
11
  { label: 'Less Than', value: "$lt" },
12
12
  { label: 'Less Than Or Equal', value: "$lte" },
13
13
  { label: 'Greater Than', value: "$gt" },
@@ -30,6 +30,7 @@ import { SolidLayoutViews } from '../common/SolidLayoutViews'
30
30
  import { SolidConfigureLayoutElement } from '../common/SolidConfigureLayoutElement'
31
31
  import { FilterIcon } from '../../modelsComponents/filterIcon';
32
32
  import { OverlayPanel } from "primereact/overlaypanel";
33
+ import { Toast } from "primereact/toast";
33
34
  const getRandomInt = (min: number, max: number) => {
34
35
  return Math.floor(Math.random() * (max - min + 1)) + min;
35
36
  }
@@ -94,7 +95,10 @@ export const SolidListView = (params: SolidListViewParams) => {
94
95
  useLazyGetSolidEntitiesQuery,
95
96
  useLazyGetSolidEntityByIdQuery,
96
97
  usePrefetch,
97
- useUpdateSolidEntityMutation
98
+ useUpdateSolidEntityMutation,
99
+ useRecoverSolidEntityByIdQuery,
100
+ useLazyRecoverSolidEntityByIdQuery,
101
+ useRecoverSolidEntityMutation
98
102
  } = entityApi;
99
103
 
100
104
  // Get the list view layout & metadata first.
@@ -110,7 +114,6 @@ export const SolidListView = (params: SolidListViewParams) => {
110
114
  refetch
111
115
  } = useGetSolidViewLayoutQuery(listViewMetaDataQs);
112
116
 
113
-
114
117
  const initialFilterMethod = () => {
115
118
 
116
119
  const solidView = solidListViewMetaData.data.solidView;
@@ -179,24 +182,30 @@ export const SolidListView = (params: SolidListViewParams) => {
179
182
  const [sortField, setSortField] = useState("");
180
183
  const [sortOrder, setSortOrder] = useState(0);
181
184
  const [selectedRecords, setSelectedRecords] = useState<any[]>([]);
185
+ const [selectedRecoverRecords, setSelectedRecoverRecords] = useState<any[]>([]);
182
186
  const [loading, setLoading] = useState<boolean>(true);
183
187
  const [isDialogVisible, setDialogVisible] = useState(false);
188
+ const [isRecoverDialogVisible, setRecoverDialogVisible] = useState(false);
184
189
  const [createButtonUrl, setCreateButtonUrl] = useState<string>();
185
190
  const [editButtonUrl, setEditButtonUrl] = useState<string>();
191
+ const [showArchived, setShowArchived] = useState(false);
186
192
 
187
193
  // Custom Row Action
188
194
  const [listViewRowActionPopupState, setListViewRowActionPopupState] = useState(false);
189
195
  const [listViewRowActionData, setListRowActionData] = useState<any>();
190
196
 
197
+ const toast = useRef<Toast>(null);
198
+
191
199
  // Get the list view data.
192
200
  const [triggerGetSolidEntities, { data: solidEntityListViewData, isLoading, error }] = useLazyGetSolidEntitiesQuery();
193
201
 
202
+ const [triggerRecoverSolidEntitiesById, { data: recoverByIdData, isLoading: recoverByIdIsLoading, error: recoverByIdError, isError: recoverByIdIsError, isSuccess: recoverByIdIsSuccess }] = useLazyRecoverSolidEntityByIdQuery();
194
203
 
204
+ const [triggerRecoverSolidEntities, { data: recoverByData, isLoading: recoverByIsLoading, error: recoverError, isError: recoverIsError, isSuccess: recoverByIsSuccess }] = useRecoverSolidEntityMutation();
195
205
 
196
206
  // After data is fetched populate the list view state so as to be able to render the data.
197
207
  useEffect(() => {
198
208
  if (solidEntityListViewData) {
199
-
200
209
  setListViewData(solidEntityListViewData?.records);
201
210
  setTotalRecords(solidEntityListViewData?.meta.totalRecords);
202
211
  setLoading(false);
@@ -231,6 +240,27 @@ export const SolidListView = (params: SolidListViewParams) => {
231
240
  },
232
241
  ] = useDeleteMultipleSolidEntitiesMutation();
233
242
 
243
+ // Fetch Soft Deleted data
244
+ useEffect(() => {
245
+ const queryData = {
246
+ offset: 0,
247
+ limit: 25,
248
+ populate: toPopulate,
249
+ sort: [`id:desc`],
250
+ };
251
+ if (showArchived) {
252
+ queryData.showSoftDeleted = 'true';
253
+ }
254
+ const queryString = qs.stringify(queryData, {
255
+ encodeValuesOnly: true
256
+ });
257
+
258
+ triggerGetSolidEntities(queryString);
259
+ setSelectedRecords([]);
260
+ setSelectedRecoverRecords([]);
261
+ }, [showArchived, recoverByIdIsSuccess, recoverByIsSuccess]);
262
+
263
+
234
264
  // Fetch data after toPopulate has been populated...
235
265
  useEffect(() => {
236
266
  if (toPopulate) {
@@ -250,6 +280,8 @@ export const SolidListView = (params: SolidListViewParams) => {
250
280
 
251
281
  triggerGetSolidEntities(queryString);
252
282
  setSelectedRecords([]);
283
+ setSelectedRecoverRecords([]);
284
+ setShowArchived(false);
253
285
  }
254
286
  }, [isDeleteSolidEntitiesSucess, isDeleteSolidSingleEntitySuccess, toPopulate]);
255
287
 
@@ -279,7 +311,11 @@ export const SolidListView = (params: SolidListViewParams) => {
279
311
  // handle change in the records which are currently selected...
280
312
  const onSelectionChange = (event: any) => {
281
313
  const value = event.value;
282
- setSelectedRecords(value);
314
+ const activeRecords = value.filter((record: any) => record.deletedAt === null);
315
+ const deletedRecords = value.filter((record: any) => record.deletedAt !== null);
316
+
317
+ setSelectedRecords(activeRecords);
318
+ setSelectedRecoverRecords(deletedRecords);
283
319
  };
284
320
 
285
321
  const identifySolidOperatorAndValue = (primeReactMatchMode: FilterMatchMode, value: any): { operator: string, value: string | string[] | any[] } => {
@@ -475,6 +511,51 @@ export const SolidListView = (params: SolidListViewParams) => {
475
511
  );
476
512
  };
477
513
 
514
+ // Recover functions
515
+ const recoverById = (id) => {
516
+ triggerRecoverSolidEntitiesById(id);
517
+ }
518
+
519
+ const recoverAll = () => {
520
+ let recoverList: any = [];
521
+ selectedRecoverRecords.forEach((element: any) => {
522
+ recoverList.push(element.id);
523
+ });
524
+ triggerRecoverSolidEntities(recoverList);
525
+ setRecoverDialogVisible(false);
526
+ }
527
+
528
+ useEffect(() => {
529
+ if (recoverIsError || recoverByIdIsError) {
530
+ showError(recoverByIdIsError ? recoverByIdError : recoverError);
531
+ }
532
+ }, [recoverIsError, recoverByIdIsError])
533
+
534
+ const showError = async (error) => {
535
+ const errorMessages = error?.data?.message;
536
+ if (errorMessages.length > 0) {
537
+ toast?.current?.show({
538
+ severity: "error",
539
+ summary: "Can you send me the report?",
540
+ // sticky: true,
541
+ life: 3000,
542
+ //@ts-ignore
543
+ content: (props) => (
544
+ <div
545
+ className="flex flex-column align-items-left"
546
+ style={{ flex: "1" }}
547
+ >
548
+ {errorMessages.map((m, index) => (
549
+ <div className="flex align-items-center gap-2" key={index}>
550
+ <span className="font-bold text-900">{String(m)}</span>
551
+ </div>
552
+ ))}
553
+ </div>
554
+ ),
555
+ });
556
+ }
557
+ };
558
+
478
559
  // handle bulk deletion
479
560
  const deleteBulk = () => {
480
561
  let deleteList: any = [];
@@ -490,6 +571,7 @@ export const SolidListView = (params: SolidListViewParams) => {
490
571
  const onDeleteClose = () => {
491
572
  setDialogVisible(false);
492
573
  setSelectedRecords([]);
574
+ setSelectedRecoverRecords([]);
493
575
  }
494
576
 
495
577
  // Render columns dynamically based on metadata
@@ -542,6 +624,7 @@ export const SolidListView = (params: SolidListViewParams) => {
542
624
  return (
543
625
  <>
544
626
  <div className="page-header">
627
+ <Toast ref={toast} />
545
628
  <div className="flex gap-3 align-items-center">
546
629
 
547
630
 
@@ -566,7 +649,7 @@ export const SolidListView = (params: SolidListViewParams) => {
566
649
  }
567
650
 
568
651
  {solidListViewMetaData?.data?.solidView?.layout?.attrs?.enableGlobalSearch === true && params.embeded === false &&
569
- <SolidGlobalSearchElement ref={solidGlobalSearchElementRef} viewData={solidListViewMetaData} handleApplyCustomFilter={handleApplyCustomFilter} ></SolidGlobalSearchElement>
652
+ <SolidGlobalSearchElement ref={solidGlobalSearchElementRef} viewData={solidListViewMetaData} handleApplyCustomFilter={handleApplyCustomFilter} setShowArchived={setShowArchived} showArchived={showArchived}></SolidGlobalSearchElement>
570
653
  }
571
654
  </div>
572
655
  <div className="flex align-items-center gap-3">
@@ -580,6 +663,9 @@ export const SolidListView = (params: SolidListViewParams) => {
580
663
  onClick={() => params.handlePopUpOpen(true)}
581
664
  ></Button>
582
665
  }
666
+ {showArchived && <Button type="button" icon="pi pi-refresh" label="Recover" size='small' severity="warning"
667
+ onClick={() => setRecoverDialogVisible(true)}
668
+ ></Button>}
583
669
  <SolidLayoutViews
584
670
  sizeOptions={sizeOptions}
585
671
  setSize={setSize}
@@ -596,10 +682,13 @@ export const SolidListView = (params: SolidListViewParams) => {
596
682
  } */}
597
683
  </div>
598
684
  </div>
599
- <style>{`.p-datatable .p-datatable-loading-overlay {background-color: rgba(0, 0, 0, 0.0);}`}</style>
685
+ <style>{`.p-datatable .p-datatable-loading-overlay {background-color: rgba(0, 0, 0, 0.0);} .greyed-out-row { background-color: #f5f5f5 !important; color: #a0a0a0 !important; opacity: 0.6;}`}</style>
600
686
  <div className="solid-datatable-wrapper">
601
687
  <DataTable
602
688
  value={listViewData}
689
+ rowClassName={(rowData) => {
690
+ return rowData.deletedAt ? "greyed-out-row" : "";
691
+ }}
603
692
  showGridlines={false}
604
693
  lazy
605
694
  scrollable
@@ -620,7 +709,7 @@ export const SolidListView = (params: SolidListViewParams) => {
620
709
  sortOrder={sortOrder === 1 || sortOrder === -1 ? sortOrder : 0}
621
710
  loading={loading || isLoading}
622
711
  loadingIcon="pi pi-spinner"
623
- selection={selectedRecords}
712
+ selection={[...selectedRecords, ...selectedRecoverRecords]}
624
713
  onSelectionChange={onSelectionChange}
625
714
  selectionMode="multiple"
626
715
  removableSort
@@ -635,7 +724,14 @@ export const SolidListView = (params: SolidListViewParams) => {
635
724
 
636
725
  {renderColumnsDynamically(listViewMetaData)}
637
726
  {actionsAllowed.includes(`${updatePermission(params.modelName)}`) && solidListViewMetaData?.data?.solidView?.layout?.attrs?.edit !== false &&
638
- <Column body={detailsBodyTemplate} ></Column>
727
+ <Column body={(rowData) => (
728
+ rowData.deletedAt ? (
729
+ <a onClick={() => recoverById(rowData.id)} className="retrieve-button">
730
+ <i className="pi pi-refresh" style={{ fontSize: "1rem" }}/>
731
+ </a>
732
+ ) :
733
+ detailsBodyTemplate(rowData)
734
+ )}></Column>
639
735
  }
640
736
  {solidListViewMetaData?.data?.solidView?.layout?.attrs?.rowButtons &&
641
737
  solidListViewMetaData?.data?.solidView?.layout?.attrs?.rowButtons.map((rowAction: any) => {
@@ -678,6 +774,20 @@ export const SolidListView = (params: SolidListViewParams) => {
678
774
  <p>Are you sure you want to delete the selected records?</p>
679
775
  </Dialog>
680
776
 
777
+ <Dialog
778
+ visible={isRecoverDialogVisible}
779
+ header="Confirm Recover"
780
+ modal
781
+ footer={() => (
782
+ <div className="flex justify-content-center">
783
+ <Button label="Yes" icon="pi pi-check" className='small-button' severity="danger" autoFocus onClick={recoverAll} />
784
+ <Button label="No" icon="pi pi-times" className='small-button' onClick={() => setRecoverDialogVisible(false)} />
785
+ </div>
786
+ )}
787
+ onHide={() => setRecoverDialogVisible(false)}
788
+ >
789
+ <p>Are you sure you want to recover all records?</p>
790
+ </Dialog>
681
791
 
682
792
  {listViewRowActionData &&
683
793
  <Dialog
@@ -342,6 +342,7 @@ const CreateModel = ({ data, params }: any) => {
342
342
  deleteModelFunction={deleteModelFunction}
343
343
  nextTab={nextTab}
344
344
  formikFieldsMetadataRef={formikFieldsMetadataRef}
345
+ params={params}
345
346
  ></FieldMetaData>
346
347
  </TabPanel>
347
348
  </TabView>
@@ -11,7 +11,7 @@ import { useRef, useState } from "react";
11
11
  import FieldMetaDataForm from "./FieldMetaDataForm";
12
12
 
13
13
 
14
- const FieldMetaData = ({ modelMetaData, fieldMetaData, setFieldMetaData, deleteModelFunction, nextTab, formikFieldsMetadataRef }: any) => {
14
+ const FieldMetaData = ({ modelMetaData, fieldMetaData, setFieldMetaData, deleteModelFunction, nextTab, formikFieldsMetadataRef, params }: any) => {
15
15
  const pathname = usePathname();
16
16
  const msgs = useRef<Messages>(null);
17
17
 
@@ -29,6 +29,7 @@ const FieldMetaData = ({ modelMetaData, fieldMetaData, setFieldMetaData, deleteM
29
29
  });
30
30
  const toast = useRef<Toast>(null);
31
31
  const [visiblePopup, setVisiblePopup] = useState(false);
32
+ const [isRequiredPopUp, setIsRequiredPopUp] = useState(false);
32
33
  const [currentPopup, setCurrentPopup] = useState();
33
34
  const [selectedFieldMetaData, setSelectedFieldMetaData] = useState(null);
34
35
  const onRowSelect = (event: any) => {
@@ -130,9 +131,27 @@ const FieldMetaData = ({ modelMetaData, fieldMetaData, setFieldMetaData, deleteM
130
131
  }}
131
132
  showHeader={false}
132
133
  >
133
- <FieldMetaDataForm modelMetaData={modelMetaData} fieldMetaData={selectedFieldMetaData} allFields={fieldMetaData} setFieldMetaData={setFieldMetaData} deleteModelFunction={deleteModelFunction} setVisiblePopup={setVisiblePopup} formikFieldsMetadataRef={formikFieldsMetadataRef} ></FieldMetaDataForm>
134
+ <FieldMetaDataForm modelMetaData={modelMetaData} fieldMetaData={selectedFieldMetaData} allFields={fieldMetaData} setFieldMetaData={setFieldMetaData} deleteModelFunction={deleteModelFunction} setVisiblePopup={setVisiblePopup} formikFieldsMetadataRef={formikFieldsMetadataRef} params={params} setIsRequiredPopUp={setIsRequiredPopUp}></FieldMetaDataForm>
135
+ </Dialog>
136
+ <Dialog
137
+ visible={isRequiredPopUp}
138
+ header={(
139
+ <div className="flex align-items-center">
140
+ <i className="pi pi-exclamation-triangle text-yellow-500 text-xl mr-2"></i>
141
+ <span>Warning</span>
142
+ </div>
143
+ )}
144
+ headerClassName="text-center"
145
+ modal
146
+ footer={() => (
147
+ <div className="flex justify-content-center">
148
+ <Button label="Ok" className='small-button' onClick={() => setIsRequiredPopUp(false)} />
149
+ </div>
150
+ )}
151
+ onHide={() => setIsRequiredPopUp(false)}
152
+ >
153
+ <p>If there is data against this model this operation might not work and manual intervention will be required</p>
134
154
  </Dialog>
135
-
136
155
  </div >
137
156
  }
138
157
  </>
@@ -323,12 +323,12 @@ const createValidationSchema = (currentFields: any, selectedType: any, allFields
323
323
  "Max must be greater than Min",
324
324
  function (value) {
325
325
  const { min } = this.parent; // Access sibling field 'min'
326
- if (min != null && value == null) {
327
- // Trigger error if Min is filled but Max is empty
328
- return this.createError({
329
- message: "Max is required if Min is specified",
330
- });
331
- }
326
+ // if (min != null && value == null) {
327
+ // // Trigger error if Min is filled but Max is empty
328
+ // return this.createError({
329
+ // message: "Max is required if Min is specified",
330
+ // });
331
+ // }
332
332
  return value == null || value > min; // Validate only if Max exists
333
333
  }
334
334
  );
@@ -345,12 +345,12 @@ const createValidationSchema = (currentFields: any, selectedType: any, allFields
345
345
  "Max must be greater than Min",
346
346
  function (value) {
347
347
  const { min } = this.parent; // Access sibling field 'min'
348
- if (min != null && value == null) {
349
- // Trigger error if Min is filled but Max is empty
350
- return this.createError({
351
- message: "Max is required if Min is specified",
352
- });
353
- }
348
+ // if (min != null && value == null) {
349
+ // // Trigger error if Min is filled but Max is empty
350
+ // return this.createError({
351
+ // message: "Max is required if Min is specified",
352
+ // });
353
+ // }
354
354
  return value == null || value > min; // Validate only if Max exists
355
355
  }
356
356
  );
@@ -506,7 +506,7 @@ const createValidationSchema = (currentFields: any, selectedType: any, allFields
506
506
  return Yup.object(schema);
507
507
  };
508
508
 
509
- const FieldMetaDataForm = ({ modelMetaData, fieldMetaData, setFieldMetaData, allFields, deleteModelFunction, setVisiblePopup }: any) => {
509
+ const FieldMetaDataForm = ({ modelMetaData, fieldMetaData, setFieldMetaData, allFields, deleteModelFunction, setVisiblePopup, params, setIsRequiredPopUp }: any) => {
510
510
 
511
511
  const booleanOptions = ["false", "true"];
512
512
  const [isBackPopupVisible, setIsBackPopupVisible] = useState(false);
@@ -923,6 +923,9 @@ const FieldMetaDataForm = ({ modelMetaData, fieldMetaData, setFieldMetaData, all
923
923
  return updatedItems
924
924
  }
925
925
  else {
926
+ if (params?.id !== 'new' && formtatedFieldPayload?.required && !formtatedFieldPayload?.defaultValue) {
927
+ setIsRequiredPopUp(true);
928
+ }
926
929
  return [...prevItems, formtatedFieldPayload]
927
930
  }
928
931
  });
@@ -1114,7 +1117,7 @@ const FieldMetaDataForm = ({ modelMetaData, fieldMetaData, setFieldMetaData, all
1114
1117
  <div className="p-d-flex p-jc-center creat-field-for form-dem">
1115
1118
  <div className="p-fluid" style={{ position: 'relative' }}>
1116
1119
  <div className="mb-3">
1117
- <div className="form-wrapper-title">Add a new {capitalize(selectedType.value)} Field</div>
1120
+ <div className="form-wrapper-title">{fieldMetaData ? `Edit ${capitalize(selectedType.value)} Field` : `Add a new ${capitalize(selectedType.value)} Field`}</div>
1118
1121
  </div>
1119
1122
 
1120
1123
 
@@ -1416,7 +1419,7 @@ const FieldMetaDataForm = ({ modelMetaData, fieldMetaData, setFieldMetaData, all
1416
1419
  <Calendar
1417
1420
  id="defaultValue"
1418
1421
  name="defaultValue"
1419
- value={formik.values.defaultValue ? new Date(formik.values.defaultValue) : new Date()}
1422
+ value={formik.values.defaultValue ? new Date(formik.values.defaultValue) : null}
1420
1423
  onChange={(e) => formik.setFieldValue("defaultValue", e.value)} // Use setFieldValue for proper handling
1421
1424
  showTime={formik.values.type === "datetime"} // Show time picker for datetime
1422
1425
  timeOnly={formik.values.type === "time"} // Time-only for time
@@ -2622,9 +2625,10 @@ const FieldMetaDataForm = ({ modelMetaData, fieldMetaData, setFieldMetaData, all
2622
2625
  )}
2623
2626
  </div>
2624
2627
  )}
2625
- {currentFields.includes("isSystem") && (
2626
- <div className="field col-6 flex-flex-column gap-2 mt-3">
2627
- <div className="flex align-items-center gap-2">
2628
+ {/* {currentFields.includes("isSystem") && (
2629
+ <div className="md:col-6 sm:col-12">
2630
+ <div className="field">
2631
+ <div className="flex align-items-center">
2628
2632
  <Checkbox
2629
2633
  name="isSystem"
2630
2634
  onChange={(e) => {
@@ -2643,7 +2647,8 @@ const FieldMetaDataForm = ({ modelMetaData, fieldMetaData, setFieldMetaData, all
2643
2647
  />
2644
2648
  )}
2645
2649
  </div>
2646
- )}
2650
+ </div>
2651
+ )} */}
2647
2652
  {currentFields.includes("isUserKey") && (
2648
2653
  <div className="field col-6 flex-flex-column gap-2 mt-3">
2649
2654
  <div className="flex align-items-center gap-2">
@@ -4,6 +4,7 @@ import { getSingularAndPlural } from "@/helpers/helpers";
4
4
  import { useGetFieldDefaultMetaDataQuery } from "@/redux/api/fieldApi";
5
5
  import { useLazyGetmodulesQuery } from "@/redux/api/moduleApi";
6
6
  import { useFormik } from "formik";
7
+ import { snakeCase } from "lodash";
7
8
  import { usePathname, useRouter } from "next/navigation";
8
9
  import { Checkbox } from "primereact/checkbox";
9
10
  import { Divider } from "primereact/divider";
@@ -107,6 +108,7 @@ const ModelMetaData = React.forwardRef(({ modelMetaData, setModelMetaData, allMo
107
108
  enableReinitialize: true,
108
109
  innerRef: formikModelMetadataRef,
109
110
  onSubmit: async (values) => {
111
+ const tableName = generateTableName(values.module.displayName, values.singularName);
110
112
  try {
111
113
  const modelData = {
112
114
  ...modelMetaData,
@@ -116,7 +118,7 @@ const ModelMetaData = React.forwardRef(({ modelMetaData, setModelMetaData, allMo
116
118
  description: values.description,
117
119
  dataSource: values.dataSource,
118
120
  dataSourceType: values.dataSourceType,
119
- tableName: showTableName === true ? values?.tableName : null,
121
+ tableName: showTableName === true ? values?.tableName : tableName,
120
122
  moduleId: values.moduleId,
121
123
  module: values.module,
122
124
  isSystem: values.isSystem ? values.isSystem === true : '',
@@ -124,7 +126,6 @@ const ModelMetaData = React.forwardRef(({ modelMetaData, setModelMetaData, allMo
124
126
  enableAuditTracking: values.enableAuditTracking === true ? true : '',
125
127
  internationalisation: values.internationalisation === true ? true : '',
126
128
  };
127
-
128
129
  setModelMetaData(modelData);
129
130
  nextTab()
130
131
 
@@ -134,6 +135,12 @@ const ModelMetaData = React.forwardRef(({ modelMetaData, setModelMetaData, allMo
134
135
  },
135
136
  });
136
137
 
138
+ function generateTableName(moduleSlug: string, modelName: string): string {
139
+ const snakeCaseModelName = snakeCase(modelName);
140
+ const sankeCaseModuleName = snakeCase(moduleSlug);
141
+ return `${sankeCaseModuleName}_${snakeCaseModelName}`;
142
+ }
143
+
137
144
  const showError = async () => {
138
145
  const errors = await formik.validateForm(); // Trigger validation and get the updated errors
139
146
  const errorMessages = Object.values(errors);
@@ -588,7 +595,7 @@ const ModelMetaData = React.forwardRef(({ modelMetaData, setModelMetaData, allMo
588
595
  }
589
596
  }
590
597
 
591
- }} checked={showTableName}></Checkbox>
598
+ }} checked={showTableName} disabled={params.id !== 'new'}></Checkbox>
592
599
  <label htmlFor="ingredient1" className="form-field-label">
593
600
  Set table name
594
601
  </label>
@@ -10,8 +10,11 @@ import { LayoutConfig } from "@/types";
10
10
  import { toggleTheme } from "@/redux/features/themeSlice";
11
11
  import { InputSwitch } from "primereact/inputswitch";
12
12
  import { Button } from "primereact/button";
13
+ import { useRouter } from "next/navigation";
13
14
 
14
15
  const UserProfileMenu = () => {
16
+ const router = useRouter();
17
+
15
18
  // const { user } = useAppSelector((state) => state.auth);
16
19
  const { changeTheme } = useContext(PrimeReactContext);
17
20
  const { layoutConfig, setLayoutConfig } = useContext(LayoutContext);
@@ -76,7 +79,9 @@ const UserProfileMenu = () => {
76
79
  </div>
77
80
  <InputSwitch checked={checked} onChange={handleThemeToggle} />
78
81
  </div>
79
-
82
+ <div className="p-2">
83
+ <Button icon="pi pi-cog" label="General Settings" size="small" text severity="secondary" className="w-full text-left gap-2" onClick={()=>router.push("/admin/settings") }/>
84
+ </div>
80
85
  <div className="user-profile-body p-3">
81
86
  <Button
82
87
  text
package/src/index.ts CHANGED
@@ -432,6 +432,7 @@ export { mediaStorageProviderApi, useCreateMediaStorageProivderMutation, useDele
432
432
  // export * from '@/redux/api/modelApi';
433
433
  export { modelsApi, useCreatemodelMutation, useDeleteMultipleModelsMutation, useDeletemodelMutation, useGenerateCodeForModelMutation, useGetModelsQuery, useGetmodelByIdQuery, useLazyGetModelsQuery, useLazyGetmodelByIdQuery, useUpdatemodelMutation } from '@/redux/api/modelApi';
434
434
  export { modulesApi, useCreatemoduleMutation, useDeleteMultiplemodulesMutation, useDeletemoduleMutation, useGenerateCodeFormoduleMutation, useGetDefaultDataSourceQuery, useGetmoduleByIdQuery, useGetmodulesQuery, useLazyGetDefaultDataSourceQuery, useLazyGetmoduleByIdQuery, useLazyGetmodulesQuery, useRefreshPermissionsMutation, useUpdatemoduleMutation } from '@/redux/api/moduleApi';
435
+ export { testApi, useSeederMutation } from '@/redux/api/testApi';
435
436
  // export * from '@/redux/api/orderAttributeApi';
436
437
  // export * from '@/redux/api/permissionApi';
437
438
  // export * from '@/redux/api/pincodeApi';
@@ -592,6 +593,7 @@ export { default as popupReducer } from '@/redux/features/popupSlice';
592
593
  export { default as themeReducer } from '@/redux/features/themeSlice';
593
594
  export { default as userReducer } from '@/redux/features/userSlice';
594
595
 
596
+ export {default as GenerateModelCodeRowAction } from '@/components/core/extension/solid-core/modelMetadata/list/GenerateModelCodeRowAction'
595
597
 
596
598
  // types
597
599
  export type { LayoutConfig } from '@/types';
@@ -69,6 +69,17 @@ export const createSolidEntityApi = (entityName: string) => {
69
69
  method: 'DELETE',
70
70
  }),
71
71
  }),
72
+ recoverSolidEntityById: builder.query({
73
+ query: (id) => `/${kebabEntityName}/recover/${id}`,
74
+ }),
75
+ recoverSolidEntity: builder.mutation({
76
+ query: (data) => ({
77
+ url: `/${kebabEntityName}/bulk-recover/`,
78
+ method: 'POST',
79
+ body: data
80
+ })
81
+
82
+ }),
72
83
  }),
73
84
  });
74
85
  };
@@ -19,7 +19,7 @@ export const solidSettingsApi = createApi({
19
19
  }),
20
20
  getAuthSettings: builder.query({
21
21
  query: () => {
22
- return `/setting/getSettings`
22
+ return `/setting/wrapped`
23
23
  },
24
24
  }),
25
25
  getSolidSettingsById: builder.query({
@@ -0,0 +1,21 @@
1
+ import { createApi } from '@reduxjs/toolkit/query/react';
2
+ import { baseQueryWithAuth } from './fetchBaseQuery';
3
+
4
+ export const testApi = createApi({
5
+ reducerPath: 'testApi',
6
+ baseQuery: baseQueryWithAuth,
7
+ endpoints: (builder) => ({
8
+ seeder: builder.mutation({
9
+ query: (name) => ({
10
+ url: '/test/seed',
11
+ method: 'POST',
12
+ body: {
13
+ "seeder": name
14
+ }
15
+ }),
16
+ }),
17
+ })
18
+
19
+ });
20
+
21
+ export const {useSeederMutation} = testApi