@solidstarters/solid-core-ui 1.1.22 → 1.1.24
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/SolidBreadcrumb.d.ts +2 -10
- package/dist/components/common/SolidBreadcrumb.d.ts.map +1 -1
- package/dist/components/common/SolidBreadcrumb.js +28 -8
- package/dist/components/common/SolidBreadcrumb.js.map +1 -1
- package/dist/components/core/common/SolidGlobalSearchElement.d.ts.map +1 -1
- package/dist/components/core/common/SolidGlobalSearchElement.js +1 -0
- package/dist/components/core/common/SolidGlobalSearchElement.js.map +1 -1
- package/dist/components/core/common/SolidViewLayoutManager.d.ts +13 -0
- package/dist/components/core/common/SolidViewLayoutManager.d.ts.map +1 -0
- package/dist/components/core/common/SolidViewLayoutManager.js +90 -0
- package/dist/components/core/common/SolidViewLayoutManager.js.map +1 -0
- package/dist/components/core/extension/solid-core/modelMetadata/list/GenerateModelCodeRowAction.d.ts.map +1 -1
- package/dist/components/core/extension/solid-core/modelMetadata/list/GenerateModelCodeRowAction.js +6 -4
- package/dist/components/core/extension/solid-core/modelMetadata/list/GenerateModelCodeRowAction.js.map +1 -1
- package/dist/components/core/extension/solid-core/moduleMetadata/list/GenerateModuleCodeRowAction.d.ts.map +1 -1
- package/dist/components/core/extension/solid-core/moduleMetadata/list/GenerateModuleCodeRowAction.js +5 -3
- package/dist/components/core/extension/solid-core/moduleMetadata/list/GenerateModuleCodeRowAction.js.map +1 -1
- package/dist/components/core/form/SolidFormLayouts.d.ts.map +1 -1
- package/dist/components/core/form/SolidFormLayouts.js +6 -2
- package/dist/components/core/form/SolidFormLayouts.js.map +1 -1
- package/dist/components/core/form/SolidFormView.d.ts.map +1 -1
- package/dist/components/core/form/SolidFormView.js +134 -48
- package/dist/components/core/form/SolidFormView.js.map +1 -1
- package/dist/components/core/form/fields/ISolidField.d.ts +2 -1
- package/dist/components/core/form/fields/ISolidField.d.ts.map +1 -1
- package/dist/components/core/form/fields/SolidSelectionStaticField.d.ts.map +1 -1
- package/dist/components/core/form/fields/SolidSelectionStaticField.js +4 -2
- package/dist/components/core/form/fields/SolidSelectionStaticField.js.map +1 -1
- package/dist/components/core/form/fields/SolidShortTextField.d.ts.map +1 -1
- package/dist/components/core/form/fields/SolidShortTextField.js +19 -13
- package/dist/components/core/form/fields/SolidShortTextField.js.map +1 -1
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js +2 -2
- package/dist/components/core/form/fields/relations/SolidRelationManyToOneField.js.map +1 -1
- package/dist/components/core/form/widgets/CustomHtml.d.ts +3 -0
- package/dist/components/core/form/widgets/CustomHtml.d.ts.map +1 -0
- package/dist/components/core/form/widgets/CustomHtml.js +15 -0
- package/dist/components/core/form/widgets/CustomHtml.js.map +1 -0
- package/dist/components/core/list/SolidListView.js +1 -1
- package/dist/components/core/model/CreateModel.d.ts.map +1 -1
- package/dist/components/core/model/CreateModel.js +3 -7
- package/dist/components/core/model/CreateModel.js.map +1 -1
- package/dist/components/core/model/FieldMetaData.d.ts +1 -1
- package/dist/components/core/model/FieldMetaData.d.ts.map +1 -1
- package/dist/components/core/model/FieldMetaData.js +7 -3
- package/dist/components/core/model/FieldMetaData.js.map +1 -1
- package/dist/components/core/model/FieldMetaDataForm.d.ts +1 -1
- package/dist/components/core/model/FieldMetaDataForm.d.ts.map +1 -1
- package/dist/components/core/model/FieldMetaDataForm.js +23 -15
- package/dist/components/core/model/FieldMetaDataForm.js.map +1 -1
- package/dist/components/core/model/ModelMetaData.js +5 -5
- package/dist/components/core/model/ModelMetaData.js.map +1 -1
- package/dist/components/core/module/CreateModule.d.ts.map +1 -1
- package/dist/components/core/module/CreateModule.js +1 -5
- package/dist/components/core/module/CreateModule.js.map +1 -1
- package/dist/components/core/users/CreateUser.d.ts.map +1 -1
- package/dist/components/core/users/CreateUser.js +1 -5
- package/dist/components/core/users/CreateUser.js.map +1 -1
- package/dist/components/layout/AppSidebar.d.ts.map +1 -1
- package/dist/components/layout/AppSidebar.js +2 -14
- package/dist/components/layout/AppSidebar.js.map +1 -1
- package/dist/helpers/registry.d.ts.map +1 -1
- package/dist/helpers/registry.js +9 -3
- package/dist/helpers/registry.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- package/src/components/common/SolidBreadcrumb.tsx +38 -14
- package/src/components/core/common/SolidGlobalSearchElement.tsx +2 -0
- package/src/components/core/common/SolidViewLayoutManager.ts +85 -0
- package/src/components/core/extension/solid-core/modelMetadata/list/GenerateModelCodeRowAction.tsx +11 -1
- package/src/components/core/extension/solid-core/moduleMetadata/list/GenerateModuleCodeRowAction.tsx +16 -7
- package/src/components/core/form/SolidFormLayouts.tsx +6 -3
- package/src/components/core/form/SolidFormView.tsx +184 -65
- package/src/components/core/form/fields/ISolidField.tsx +2 -1
- package/src/components/core/form/fields/SolidSelectionStaticField.tsx +3 -1
- package/src/components/core/form/fields/SolidShortTextField.tsx +49 -23
- package/src/components/core/form/fields/relations/SolidRelationManyToOneField.tsx +6 -6
- package/src/components/core/form/widgets/CustomHtml.tsx +19 -0
- package/src/components/core/list/SolidListView.tsx +1 -1
- package/src/components/core/model/CreateModel.tsx +4 -8
- package/src/components/core/model/FieldMetaData.tsx +7 -3
- package/src/components/core/model/FieldMetaDataForm.tsx +343 -339
- package/src/components/core/model/ModelMetaData.tsx +5 -5
- package/src/components/core/module/CreateModule.tsx +1 -6
- package/src/components/core/users/CreateUser.tsx +1 -6
- package/src/components/layout/AppSidebar.tsx +2 -20
- package/src/helpers/registry.ts +16 -4
- package/src/index.ts +16 -1
- package/src/types/index.d.ts +24 -2
- package/src/types/solid-core.d.ts +12 -3
|
@@ -37,6 +37,7 @@ import { OverlayPanel } from "primereact/overlaypanel";
|
|
|
37
37
|
import { SolidBreadcrumb } from "@/components/common/SolidBreadcrumb";
|
|
38
38
|
import { SolidUiEvent } from "@/types";
|
|
39
39
|
import { getExtensionComponent, getExtensionFunction } from "@/helpers/registry";
|
|
40
|
+
import { SolidFormWidgetProps } from "@/types/solid-core";
|
|
40
41
|
|
|
41
42
|
export type SolidFormViewProps = {
|
|
42
43
|
moduleName: string;
|
|
@@ -89,7 +90,7 @@ const fieldFactory = (type: string, fieldContext: SolidFieldProps): ISolidField
|
|
|
89
90
|
if (type === 'longText') {
|
|
90
91
|
return new SolidLongTextField(fieldContext);
|
|
91
92
|
}
|
|
92
|
-
if (type === 'int') {
|
|
93
|
+
if (type === 'int' || type === 'bigint' ) {
|
|
93
94
|
return new SolidIntegerField(fieldContext);
|
|
94
95
|
}
|
|
95
96
|
if (type === 'decimal' || type === 'float') {
|
|
@@ -132,7 +133,7 @@ const fieldFactory = (type: string, fieldContext: SolidFieldProps): ISolidField
|
|
|
132
133
|
}
|
|
133
134
|
|
|
134
135
|
// solidFieldsMetadata={solidFieldsMetadata} solidView={solidView}
|
|
135
|
-
const SolidField = ({ formik, field, fieldMetadata, initialEntityData, solidFormViewMetaData, modelName, readOnly,
|
|
136
|
+
const SolidField = ({ formik, field, fieldMetadata, initialEntityData, solidFormViewMetaData, modelName, readOnly, onChange, onBlur }: any) => {
|
|
136
137
|
const fieldContext: SolidFieldProps = {
|
|
137
138
|
// field metadata - coming from the field-metadata table.
|
|
138
139
|
fieldMetadata: fieldMetadata,
|
|
@@ -144,7 +145,8 @@ const SolidField = ({ formik, field, fieldMetadata, initialEntityData, solidForm
|
|
|
144
145
|
solidFormViewMetaData: solidFormViewMetaData,
|
|
145
146
|
modelName: modelName,
|
|
146
147
|
readOnly: readOnly,
|
|
147
|
-
|
|
148
|
+
onChange: onChange,
|
|
149
|
+
onBlur: onBlur
|
|
148
150
|
}
|
|
149
151
|
const solidField = fieldFactory(fieldMetadata?.type, fieldContext);
|
|
150
152
|
|
|
@@ -225,6 +227,7 @@ const SolidSheet = ({ children }: any) => (
|
|
|
225
227
|
{children}
|
|
226
228
|
</div>
|
|
227
229
|
);
|
|
230
|
+
|
|
228
231
|
const SolidNotebook = ({ children }: any) => {
|
|
229
232
|
|
|
230
233
|
return (
|
|
@@ -236,6 +239,26 @@ const SolidNotebook = ({ children }: any) => {
|
|
|
236
239
|
)
|
|
237
240
|
};
|
|
238
241
|
|
|
242
|
+
const SolidDynamicWidget = ({ widgetName, formik, field, solidFormViewMetaData }: any) => {
|
|
243
|
+
const solidView = solidFormViewMetaData.data.solidView;
|
|
244
|
+
const solidFieldsMetadata = solidFormViewMetaData.data.solidFieldsMetadata;
|
|
245
|
+
|
|
246
|
+
let DynamicWidget = getExtensionComponent(widgetName);
|
|
247
|
+
|
|
248
|
+
const widgetProps: SolidFormWidgetProps = {
|
|
249
|
+
formData: formik.values,
|
|
250
|
+
field: field,
|
|
251
|
+
fieldsMetadata: solidFieldsMetadata,
|
|
252
|
+
viewMetadata: solidView
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return (
|
|
256
|
+
<div className="solid-tab-view w-full">
|
|
257
|
+
{DynamicWidget && <DynamicWidget {...widgetProps} />}
|
|
258
|
+
</div>
|
|
259
|
+
)
|
|
260
|
+
};
|
|
261
|
+
|
|
239
262
|
|
|
240
263
|
const SolidPage = ({ attrs, children, key }: any) => (
|
|
241
264
|
<TabPanel key={key} header={attrs.label} >
|
|
@@ -472,9 +495,7 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
472
495
|
field: layoutFieldsObj[key],
|
|
473
496
|
data: initialEntityData,
|
|
474
497
|
solidFormViewMetaData: solidFormViewMetaData,
|
|
475
|
-
modelName: params.modelName
|
|
476
|
-
// TODO: do we need to pass the change handler?
|
|
477
|
-
changeHandler: null
|
|
498
|
+
modelName: params.modelName
|
|
478
499
|
}
|
|
479
500
|
|
|
480
501
|
let solidField = fieldFactory(fieldMetadata?.type, fieldContext);
|
|
@@ -598,9 +619,7 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
598
619
|
field: formLayoutField,
|
|
599
620
|
data: initialEntityData,
|
|
600
621
|
solidFormViewMetaData: solidFormViewMetaData,
|
|
601
|
-
modelName: params.modelName
|
|
602
|
-
// TODO: do we need to pass the change handler?
|
|
603
|
-
changeHandler: null,
|
|
622
|
+
modelName: params.modelName
|
|
604
623
|
}
|
|
605
624
|
let solidField = fieldFactory(fieldMetadata?.type, fieldContext);
|
|
606
625
|
if (!fieldMetadata?.type) {
|
|
@@ -625,14 +644,20 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
625
644
|
onSubmit: onFormikSubmit,
|
|
626
645
|
});
|
|
627
646
|
|
|
628
|
-
const
|
|
647
|
+
const formFieldOnXXX = async (event: ChangeEvent<HTMLInputElement>, eventType: string) => {
|
|
648
|
+
|
|
649
|
+
// Invoke the formik change
|
|
650
|
+
if (eventType === 'onFieldChange') {
|
|
651
|
+
formik.handleChange(event);
|
|
652
|
+
}
|
|
653
|
+
|
|
629
654
|
// get details from the form event
|
|
630
655
|
const { name: fieldName, value, type, checked } = event.target;
|
|
631
|
-
console.log(
|
|
656
|
+
// console.log(`${eventType}: formFieldOnXXX ${fieldName} invoked for change with value:`, value);
|
|
632
657
|
|
|
633
658
|
// TODO: check if there is a change handler registered with this form view, load it and fire it.
|
|
634
|
-
const changeHandler = solidView.layout
|
|
635
|
-
console.log(`changeHandler for this form is ${changeHandler}`);
|
|
659
|
+
const changeHandler = solidView.layout[eventType];
|
|
660
|
+
// console.log(`changeHandler for this form is ${changeHandler}`);
|
|
636
661
|
|
|
637
662
|
if (changeHandler) {
|
|
638
663
|
// Get hold of the dynamic module...
|
|
@@ -645,69 +670,170 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
645
670
|
fieldsMetadata: solidFieldsMetadata,
|
|
646
671
|
formData: formik.values,
|
|
647
672
|
modifiedField: fieldName,
|
|
648
|
-
|
|
673
|
+
modifiedFieldValue: value,
|
|
674
|
+
// @ts-ignore
|
|
675
|
+
// TODO: HP & OR: This will be fixed once we figure out how to get types exported from solid-core-ui
|
|
676
|
+
type: eventType,
|
|
649
677
|
viewMetadata: solidView
|
|
650
678
|
}
|
|
679
|
+
|
|
680
|
+
// Invoke the dynamic change handler:
|
|
681
|
+
// TODO: encapsulate in try/catch, catch the exception render in the UI as an error & stop form rendering.
|
|
651
682
|
const updatedFormInfo = dynamicChangeHandler(event);
|
|
652
|
-
console.log(
|
|
683
|
+
// console.log(`${eventType}: formFieldOnXXX response received: `, updatedFormInfo);
|
|
684
|
+
|
|
685
|
+
// If dataChanged is true, update Formik values
|
|
686
|
+
if (updatedFormInfo?.dataChanged && updatedFormInfo.newFormData) {
|
|
687
|
+
// This does one field at a time.
|
|
688
|
+
// TODO: does the below fire change events again?
|
|
689
|
+
Object.entries(updatedFormInfo.newFormData).forEach(([key, newValue]) => {
|
|
690
|
+
formik.setFieldValue(key, newValue);
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
// This does all at once.
|
|
694
|
+
// formik.setValues({
|
|
695
|
+
// ...formik.values,
|
|
696
|
+
// ...updatedFormInfo.newFormData
|
|
697
|
+
// });
|
|
698
|
+
}
|
|
653
699
|
|
|
700
|
+
// if layout has changed then we need to re-render.
|
|
701
|
+
if (updatedFormInfo?.layoutChanged && updatedFormInfo.newLayout) {
|
|
702
|
+
// setFormViewMetaData({ ...formViewMetaData, layout: updatedFormInfo.newLayout });
|
|
703
|
+
// console.log(`Existing form view metadata is: `, formViewMetaData);
|
|
704
|
+
|
|
705
|
+
// TODO: this will trigger a useEffect dependent on formViewMetadata that invokes setFormViewLayout,
|
|
706
|
+
// TODO: which means that this will not work if custom layout has been injected as a prop.
|
|
707
|
+
setFormViewLayout(updatedFormInfo.newLayout);
|
|
708
|
+
setFormViewMetaData((prevMetaData: any) => {
|
|
709
|
+
const updatedFormViewMetadata = {
|
|
710
|
+
...prevMetaData,
|
|
711
|
+
data: {
|
|
712
|
+
...prevMetaData.data,
|
|
713
|
+
solidView: {
|
|
714
|
+
...prevMetaData.data.solidView,
|
|
715
|
+
layout: updatedFormInfo.newLayout,
|
|
716
|
+
},
|
|
717
|
+
},
|
|
718
|
+
};
|
|
719
|
+
// console.log(`Updated form view metadata is: `, updatedFormViewMetadata);
|
|
720
|
+
return updatedFormViewMetadata;
|
|
721
|
+
});
|
|
722
|
+
}
|
|
654
723
|
}
|
|
655
724
|
else {
|
|
725
|
+
// TODO: Show an error popup and stop form rendering ideallly...
|
|
656
726
|
console.log(`Unable to load dynamic module:`, changeHandler);
|
|
657
727
|
}
|
|
658
|
-
|
|
659
728
|
}
|
|
660
|
-
|
|
661
|
-
// Invoke the formik change
|
|
662
|
-
formik.handleChange(event);
|
|
663
729
|
}
|
|
664
730
|
|
|
665
731
|
// Now render the form dynamically...
|
|
666
732
|
const renderFormElementDynamically: any = (element: any, solidFormViewMetaData: any) => {
|
|
667
|
-
|
|
733
|
+
let { type, attrs, body, children } = element;
|
|
668
734
|
|
|
669
735
|
// const key = attrs?.name ?? generateRandomKey();
|
|
670
736
|
const key = attrs?.name;
|
|
737
|
+
let visible = attrs?.visible;
|
|
738
|
+
if (visible === undefined || visible === null) {
|
|
739
|
+
visible = true;
|
|
740
|
+
}
|
|
741
|
+
// console.log(`Resolved visibility of form element ${key} to ${visible}`);
|
|
742
|
+
// console.log(`Form element ${key}: `, attrs);
|
|
671
743
|
|
|
672
744
|
switch (type) {
|
|
673
745
|
case "form":
|
|
746
|
+
if (!children)
|
|
747
|
+
children = [];
|
|
674
748
|
return <div key={key}>{children.map((element: any) => renderFormElementDynamically(element, solidFormViewMetaData))}</div>;
|
|
749
|
+
case "div":
|
|
750
|
+
if (!children)
|
|
751
|
+
children = [];
|
|
752
|
+
return <div key={key} {...attrs}>{children.map((element: any) => renderFormElementDynamically(element, solidFormViewMetaData))}</div>
|
|
753
|
+
case "span":
|
|
754
|
+
return <span key={key} {...attrs}>{body}</span>
|
|
755
|
+
case "p":
|
|
756
|
+
return <p key={key} {...attrs}>{body}</p>
|
|
757
|
+
case "h1":
|
|
758
|
+
return <h1 key={key} {...attrs}>{body}</h1>
|
|
759
|
+
case "h2":
|
|
760
|
+
return <h2 key={key} {...attrs}>{body}</h2>
|
|
761
|
+
case "ul":
|
|
762
|
+
if (!children)
|
|
763
|
+
children = [];
|
|
764
|
+
return <ul key={key} {...attrs}>{children.map((element: any) => renderFormElementDynamically(element, solidFormViewMetaData))}</ul>
|
|
765
|
+
case "li":
|
|
766
|
+
return <li key={key} {...attrs}>{body}</li>
|
|
675
767
|
case "sheet":
|
|
676
768
|
return <SolidSheet key={key}>{children.map((element: any) => renderFormElementDynamically(element, solidFormViewMetaData))}</SolidSheet>;
|
|
677
769
|
case "group":
|
|
678
|
-
|
|
770
|
+
if (visible === true) {
|
|
771
|
+
return <SolidGroup key={key} attrs={attrs}>{children.map((element: any) => renderFormElementDynamically(element, solidFormViewMetaData))}</SolidGroup>;
|
|
772
|
+
}
|
|
679
773
|
case "row":
|
|
680
|
-
|
|
774
|
+
if (visible === true) {
|
|
775
|
+
return <SolidRow key={key} attrs={attrs}>{children.map((element: any) => renderFormElementDynamically(element, solidFormViewMetaData))}</SolidRow>;
|
|
776
|
+
}
|
|
681
777
|
case "column":
|
|
682
|
-
|
|
778
|
+
if (visible === true) {
|
|
779
|
+
return <SolidColumn key={key} attrs={attrs}>{children.map((element: any) => renderFormElementDynamically(element, solidFormViewMetaData))}</SolidColumn>;
|
|
780
|
+
}
|
|
683
781
|
case "field": {
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
782
|
+
if (visible === true) {
|
|
783
|
+
|
|
784
|
+
// const fieldMetadata = solidFieldsMetadata[attrs.name];
|
|
785
|
+
const fieldMetadata = solidFormViewMetaData.data.solidFieldsMetadata[attrs.name];
|
|
786
|
+
// Read only permission if there is no update permission on model and router doesnt contains new
|
|
787
|
+
const readOnlyPermission = !actionsAllowed.includes(`${updatePermission(params.modelName)}`) && params.id !== "new"
|
|
788
|
+
return <SolidField
|
|
789
|
+
key={key}
|
|
790
|
+
field={element}
|
|
791
|
+
formik={formik}
|
|
792
|
+
fieldMetadata={fieldMetadata}
|
|
793
|
+
initialEntityData={solidFormViewData ? solidFormViewData.data : null}
|
|
794
|
+
solidFormViewMetaData={solidFormViewMetaData}
|
|
795
|
+
modelName={params.modelName}
|
|
796
|
+
readOnly={readOnlyPermission}
|
|
797
|
+
onChange={formFieldOnXXX}
|
|
798
|
+
onBlur={formFieldOnXXX}
|
|
799
|
+
/>;
|
|
800
|
+
}
|
|
699
801
|
}
|
|
700
802
|
case "notebook":
|
|
701
|
-
|
|
803
|
+
if (visible === true) {
|
|
804
|
+
return <SolidNotebook key={key}>{children.map((element: any) => renderFormElementDynamically(element, solidFormViewMetaData))}</SolidNotebook>;
|
|
805
|
+
}
|
|
702
806
|
case "page":
|
|
703
|
-
|
|
704
|
-
|
|
807
|
+
// console.log(`Resolved visibility of form element ${key} to ${visible}`);
|
|
808
|
+
if (visible === true) {
|
|
809
|
+
const pageChildren = children.map((element: any) => renderFormElementDynamically(element, solidFormViewMetaData));
|
|
810
|
+
return SolidPage({ children: pageChildren, attrs: attrs, key: key });
|
|
811
|
+
}
|
|
812
|
+
case "custom":
|
|
813
|
+
if (visible === true) {
|
|
814
|
+
const widgetName = attrs?.widget;
|
|
815
|
+
const fieldMetadata = solidFormViewMetaData.data.solidFieldsMetadata[attrs.name];
|
|
816
|
+
|
|
817
|
+
if (widgetName) {
|
|
818
|
+
// widgetName, formik, field, fieldMetadata, solidFormViewMetaData
|
|
819
|
+
return <SolidDynamicWidget
|
|
820
|
+
key={key}
|
|
821
|
+
widgetName={widgetName}
|
|
822
|
+
field={element}
|
|
823
|
+
formik={formik}
|
|
824
|
+
fieldMetadata={fieldMetadata}
|
|
825
|
+
solidFormViewMetaData={solidFormViewMetaData}
|
|
826
|
+
/>
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
705
830
|
default:
|
|
706
831
|
return null;
|
|
707
832
|
}
|
|
708
833
|
};
|
|
709
834
|
|
|
710
835
|
const renderFormDynamically = (solidFormViewMetaData: any) => {
|
|
836
|
+
// console.log(`renderFormDynamically invoked....`);
|
|
711
837
|
if (!solidFormViewMetaData) {
|
|
712
838
|
return;
|
|
713
839
|
}
|
|
@@ -794,35 +920,16 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
794
920
|
onClick={() => setDeleteDialogVisible(true)}
|
|
795
921
|
/>
|
|
796
922
|
}
|
|
797
|
-
{params.embeded == true &&
|
|
798
|
-
actionsAllowed.includes(`${deletePermission(params.modelName)}`) &&
|
|
799
|
-
!formViewLayout.attrs.readonly &&
|
|
800
|
-
<Button
|
|
801
|
-
text
|
|
802
|
-
type="button"
|
|
803
|
-
className="w-8rem text-left gap-2"
|
|
804
|
-
label="Delete"
|
|
805
|
-
size="small"
|
|
806
|
-
iconPos="left"
|
|
807
|
-
severity="danger"
|
|
808
|
-
icon={'pi pi-trash'}
|
|
809
|
-
onClick={() => setDeleteDialogVisible(true)}
|
|
810
|
-
/>
|
|
811
|
-
}
|
|
812
923
|
</div>
|
|
813
924
|
</OverlayPanel>
|
|
814
925
|
</div>
|
|
815
926
|
)
|
|
816
927
|
}
|
|
817
928
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
];
|
|
822
|
-
|
|
823
|
-
// see if we have an injected dynamic component.s
|
|
929
|
+
// TODO: This was simply to demonstrate how we can use dynamic components, we will remove this and use it in a more sensible way in the layout.
|
|
930
|
+
// TODO: to demonstrated this you can simply add the below to the layout of the book form view.
|
|
931
|
+
// TODO: "header": "BookFormViewDynamicComponent",
|
|
824
932
|
const dynamicHeader = solidView.layout?.header;
|
|
825
|
-
// const dynamicHeader = "BookFormViewDynamicComponent";
|
|
826
933
|
let DynamicHeaderComponent = null;
|
|
827
934
|
if (dynamicHeader) {
|
|
828
935
|
DynamicHeaderComponent = getExtensionComponent(dynamicHeader);
|
|
@@ -844,7 +951,6 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
844
951
|
{params.embeded !== true &&
|
|
845
952
|
actionsAllowed.includes(`${createPermission(params.modelName)}`) &&
|
|
846
953
|
!formViewLayout.attrs.readonly &&
|
|
847
|
-
formik.dirty &&
|
|
848
954
|
<div>
|
|
849
955
|
<Button
|
|
850
956
|
label="Save"
|
|
@@ -943,6 +1049,19 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
943
1049
|
/>
|
|
944
1050
|
</div>
|
|
945
1051
|
} */}
|
|
1052
|
+
{params.embeded == true &&
|
|
1053
|
+
actionsAllowed.includes(`${deletePermission(params.modelName)}`) &&
|
|
1054
|
+
!formViewLayout.attrs.readonly &&
|
|
1055
|
+
<div>
|
|
1056
|
+
<Button
|
|
1057
|
+
size="small"
|
|
1058
|
+
type="button"
|
|
1059
|
+
label="Delete"
|
|
1060
|
+
severity="danger"
|
|
1061
|
+
onClick={() => setDeleteDialogVisible(true)}
|
|
1062
|
+
/>
|
|
1063
|
+
</div>
|
|
1064
|
+
}
|
|
946
1065
|
{params.embeded == true &&
|
|
947
1066
|
<Button outlined size="small" type="button" label="Close" onClick={() => params.handlePopupClose()} className='bg-primary-reverse' />
|
|
948
1067
|
|
|
@@ -955,7 +1074,7 @@ const SolidFormView = (params: SolidFormViewProps) => {
|
|
|
955
1074
|
</>
|
|
956
1075
|
)}
|
|
957
1076
|
</div>
|
|
958
|
-
<SolidBreadcrumb
|
|
1077
|
+
<SolidBreadcrumb />
|
|
959
1078
|
{/* {params.embeded !== true &&
|
|
960
1079
|
<div className="solid-form-stepper">
|
|
961
1080
|
<SolidFormStepper />
|
|
@@ -111,13 +111,15 @@ export class SolidSelectionStaticField implements ISolidField {
|
|
|
111
111
|
disabled={formDisabled || fieldDisabled}
|
|
112
112
|
{...formik.getFieldProps(fieldLayoutInfo.attrs.name)}
|
|
113
113
|
id={fieldLayoutInfo.attrs.name}
|
|
114
|
+
name={fieldLayoutInfo.attrs.name}
|
|
114
115
|
field="label"
|
|
115
116
|
value={formik.values[fieldLayoutInfo.attrs.name] || ''}
|
|
116
117
|
dropdown
|
|
117
118
|
suggestions={selectionStaticItems}
|
|
118
119
|
completeMethod={selectionStaticSearch}
|
|
119
120
|
// onChange={(e) => updateInputs(index, e.value)} />
|
|
120
|
-
onChange={formik.handleChange}
|
|
121
|
+
// onChange={formik.handleChange}
|
|
122
|
+
onChange={(e) => this.fieldContext.onChange(e, 'onFieldChange')}
|
|
121
123
|
className="solid-standard-autocomplete"
|
|
122
124
|
/>
|
|
123
125
|
</div>
|
|
@@ -64,6 +64,7 @@ export class SolidShortTextField implements ISolidField {
|
|
|
64
64
|
const fieldMetadata = this.fieldContext.fieldMetadata;
|
|
65
65
|
const fieldLayoutInfo = this.fieldContext.field;
|
|
66
66
|
const className = fieldLayoutInfo.attrs?.className || 'field col-12';
|
|
67
|
+
const includeWrapper = fieldLayoutInfo.attrs?.includeWrapper || 'yes';
|
|
67
68
|
const fieldLabel = fieldLayoutInfo.attrs.label ?? fieldMetadata.displayName;
|
|
68
69
|
const fieldDescription = fieldLayoutInfo.attrs.description ?? fieldMetadata.description;
|
|
69
70
|
const solidFormViewMetaData = this.fieldContext.solidFormViewMetaData;
|
|
@@ -79,29 +80,54 @@ export class SolidShortTextField implements ISolidField {
|
|
|
79
80
|
const formReadonly = solidFormViewMetaData.data.solidView?.layout?.attrs?.readonly;
|
|
80
81
|
|
|
81
82
|
return (
|
|
82
|
-
|
|
83
|
-
<div className=
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
83
|
+
<>
|
|
84
|
+
{includeWrapper === 'yes' && <div className={className}>
|
|
85
|
+
<div className="flex flex-column gap-2 mt-4">
|
|
86
|
+
{showFieldLabel != false &&
|
|
87
|
+
<label htmlFor={fieldLayoutInfo.attrs.name} className="form-field-label">{fieldLabel}
|
|
88
|
+
{/* {fieldDescription && <span className="form_field_help">({fieldDescription}) </span>} */}
|
|
89
|
+
{/* {fieldDescription && <span className="form_field_help_text">`(${fieldDescription})` </span>} */}
|
|
90
|
+
</label>
|
|
91
|
+
}
|
|
92
|
+
<InputText
|
|
93
|
+
readOnly={formReadonly || fieldReadonly || readOnlyPermission}
|
|
94
|
+
disabled={formDisabled || fieldDisabled}
|
|
95
|
+
id={fieldLayoutInfo.attrs.name}
|
|
96
|
+
name={fieldMetadata.name}
|
|
97
|
+
aria-describedby={`${fieldLayoutInfo.attrs.name}-help`}
|
|
98
|
+
// onChange={formik.handleChange}
|
|
99
|
+
onChange={(e) => this.fieldContext.onChange(e, 'onFieldChange')}
|
|
100
|
+
onBlur={(e) => this.fieldContext.onBlur(e, 'onFieldBlur')}
|
|
101
|
+
value={formik.values[fieldLayoutInfo.attrs.name] || ''}
|
|
102
|
+
/>
|
|
103
|
+
</div>
|
|
104
|
+
{isFormFieldValid(formik, fieldLayoutInfo.attrs.name) && (
|
|
105
|
+
<Message severity="error" text={formik?.errors[fieldLayoutInfo.attrs.name]?.toString()} />
|
|
106
|
+
)}
|
|
107
|
+
</div>}
|
|
108
|
+
{includeWrapper === 'no' &&
|
|
109
|
+
<>
|
|
110
|
+
{showFieldLabel != false &&
|
|
111
|
+
<label htmlFor={fieldLayoutInfo.attrs.name} className="form-field-label">{fieldLabel}
|
|
112
|
+
{/* {fieldDescription && <span className="form_field_help">({fieldDescription}) </span>} */}
|
|
113
|
+
|
|
114
|
+
{/* {fieldDescription && <span className="form_field_help_text">`(${fieldDescription})` </span>} */}
|
|
115
|
+
</label>
|
|
116
|
+
}
|
|
117
|
+
<InputText
|
|
118
|
+
readOnly={formReadonly || fieldReadonly || readOnlyPermission}
|
|
119
|
+
disabled={formDisabled || fieldDisabled}
|
|
120
|
+
id={fieldLayoutInfo.attrs.name}
|
|
121
|
+
name={fieldMetadata.name}
|
|
122
|
+
aria-describedby={`${fieldLayoutInfo.attrs.name}-help`}
|
|
123
|
+
// onChange={formik.handleChange}
|
|
124
|
+
onChange={(e) => this.fieldContext.onChange(e, 'onFieldChange')}
|
|
125
|
+
onBlur={(e) => this.fieldContext.onBlur(e, 'onFieldBlur')}
|
|
126
|
+
value={formik.values[fieldLayoutInfo.attrs.name] || ''}
|
|
127
|
+
/>
|
|
128
|
+
</>
|
|
129
|
+
}
|
|
130
|
+
</>
|
|
105
131
|
);
|
|
106
132
|
}
|
|
107
133
|
}
|
|
@@ -137,12 +137,12 @@ export class SolidRelationManyToOneField implements ISolidField {
|
|
|
137
137
|
}
|
|
138
138
|
return (
|
|
139
139
|
<div className={className}>
|
|
140
|
-
|
|
141
|
-
{
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
140
|
+
{showFieldLabel != false &&
|
|
141
|
+
<label htmlFor={fieldLayoutInfo.attrs.name} className="form-field-label">
|
|
142
|
+
{fieldLabel}
|
|
143
|
+
</label>
|
|
144
|
+
}
|
|
145
|
+
<div className="flex align-items-center gap-3">
|
|
146
146
|
<AutoComplete
|
|
147
147
|
readOnly={formReadonly || fieldReadonly || readOnlyPermission}
|
|
148
148
|
disabled={formDisabled || fieldDisabled || readOnlyPermission}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { SolidFormWidgetProps } from "@/types";
|
|
4
|
+
import parse from 'html-react-parser';
|
|
5
|
+
import Handlebars from "handlebars";
|
|
6
|
+
|
|
7
|
+
export const CustomHtml = ({ field, formData, viewMetadata, fieldsMetadata }: SolidFormWidgetProps) => {
|
|
8
|
+
let { type, attrs, body, children } = field;
|
|
9
|
+
|
|
10
|
+
// TODO: null check on this field required, show a proper error message on the UI suggesting that you are using a CustomHtml widget, however the html is not specified in the layout.
|
|
11
|
+
const html = attrs.html;
|
|
12
|
+
|
|
13
|
+
// TODO: run dompurify to avoid XSS attacks...
|
|
14
|
+
|
|
15
|
+
// TODO: assume the html is a handlebars template, we try to do variable replacement on it using formData.
|
|
16
|
+
const template = Handlebars.compile(html);
|
|
17
|
+
|
|
18
|
+
return (<div className={attrs.className}>{parse(template(formData))}</div>)
|
|
19
|
+
}
|
|
@@ -702,7 +702,7 @@ export const SolidListView = (params: SolidListViewParams) => {
|
|
|
702
702
|
loadingIcon="pi pi-spinner"
|
|
703
703
|
selection={[...selectedRecords, ...selectedRecoverRecords]}
|
|
704
704
|
onSelectionChange={onSelectionChange}
|
|
705
|
-
selectionMode="
|
|
705
|
+
selectionMode="checkbox"
|
|
706
706
|
removableSort
|
|
707
707
|
filterIcon={<FilterIcon />}
|
|
708
708
|
tableClassName="solid-data-table"
|
|
@@ -356,11 +356,6 @@ const CreateModel = ({ data, params }: any) => {
|
|
|
356
356
|
)
|
|
357
357
|
}
|
|
358
358
|
|
|
359
|
-
const breadcrumbData = [
|
|
360
|
-
{ label: 'Model', link: '/admin/core/solid-core/model-metadata/list' },
|
|
361
|
-
{ label: params.id === "new" ? 'Create Model' : 'Edit Model' },
|
|
362
|
-
];
|
|
363
|
-
|
|
364
359
|
const [isDirty, setIsDirty] = useState(false);
|
|
365
360
|
|
|
366
361
|
|
|
@@ -396,9 +391,9 @@ const CreateModel = ({ data, params }: any) => {
|
|
|
396
391
|
<Button label="Save" size="small" type="submit" onClick={handleSubmit} />
|
|
397
392
|
}
|
|
398
393
|
</div>
|
|
399
|
-
<div>
|
|
394
|
+
{/* <div>
|
|
400
395
|
<Button outlined label="Delete" size="small" severity="danger" type="button" onClick={() => setDeleteEntity(true)} />
|
|
401
|
-
</div>
|
|
396
|
+
</div> */}
|
|
402
397
|
</>
|
|
403
398
|
}
|
|
404
399
|
<CancelButton />
|
|
@@ -407,7 +402,7 @@ const CreateModel = ({ data, params }: any) => {
|
|
|
407
402
|
</>
|
|
408
403
|
}
|
|
409
404
|
</div>
|
|
410
|
-
<SolidBreadcrumb
|
|
405
|
+
<SolidBreadcrumb />
|
|
411
406
|
{/* <div className="solid-form-stepper">
|
|
412
407
|
<SolidFormStepper />
|
|
413
408
|
</div> */}
|
|
@@ -450,6 +445,7 @@ const CreateModel = ({ data, params }: any) => {
|
|
|
450
445
|
nextTab={nextTab}
|
|
451
446
|
formikFieldsMetadataRef={formikFieldsMetadataRef}
|
|
452
447
|
params={params}
|
|
448
|
+
setIsDirty={setIsDirty}
|
|
453
449
|
></FieldMetaData>
|
|
454
450
|
</TabPanel>
|
|
455
451
|
</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, params }: any) => {
|
|
14
|
+
const FieldMetaData = ({ setIsDirty, modelMetaData, fieldMetaData, setFieldMetaData, deleteModelFunction, nextTab, formikFieldsMetadataRef, params }: any) => {
|
|
15
15
|
const pathname = usePathname();
|
|
16
16
|
const msgs = useRef<Messages>(null);
|
|
17
17
|
|
|
@@ -59,7 +59,11 @@ const FieldMetaData = ({ modelMetaData, fieldMetaData, setFieldMetaData, deleteM
|
|
|
59
59
|
|
|
60
60
|
// Function to delete a row
|
|
61
61
|
const deleteRow = (rowData: any) => {
|
|
62
|
-
setFieldMetaData((prevData: any) =>
|
|
62
|
+
setFieldMetaData((prevData: any) => {
|
|
63
|
+
const updatedData = prevData.filter((item: any) => item.name !== rowData.name);
|
|
64
|
+
setIsDirty(true); // Ensure dirty state is updated immediately
|
|
65
|
+
return updatedData;
|
|
66
|
+
});
|
|
63
67
|
};
|
|
64
68
|
|
|
65
69
|
// Template for the trash (delete) icon column
|
|
@@ -156,7 +160,7 @@ const FieldMetaData = ({ modelMetaData, fieldMetaData, setFieldMetaData, deleteM
|
|
|
156
160
|
}}
|
|
157
161
|
showHeader={false}
|
|
158
162
|
>
|
|
159
|
-
<FieldMetaDataForm modelMetaData={modelMetaData} fieldMetaData={selectedFieldMetaData} allFields={fieldMetaData} setFieldMetaData={setFieldMetaData} deleteModelFunction={deleteModelFunction} setVisiblePopup={setVisiblePopup} formikFieldsMetadataRef={formikFieldsMetadataRef} params={params} setIsRequiredPopUp={setIsRequiredPopUp} showToaster={showToaster}></FieldMetaDataForm>
|
|
163
|
+
<FieldMetaDataForm setIsDirty={setIsDirty} modelMetaData={modelMetaData} fieldMetaData={selectedFieldMetaData} allFields={fieldMetaData} setFieldMetaData={setFieldMetaData} deleteModelFunction={deleteModelFunction} setVisiblePopup={setVisiblePopup} formikFieldsMetadataRef={formikFieldsMetadataRef} params={params} setIsRequiredPopUp={setIsRequiredPopUp} showToaster={showToaster}></FieldMetaDataForm>
|
|
160
164
|
</Dialog>
|
|
161
165
|
<Dialog
|
|
162
166
|
visible={isRequiredPopUp}
|