@solidstarters/solid-core-ui 1.1.31 → 1.1.33
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/core/extension/solid-core/emailTemplate/emailFormTypeChangeHandler.d.ts +7 -0
- package/dist/components/core/extension/solid-core/emailTemplate/emailFormTypeChangeHandler.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/emailTemplate/emailFormTypeChangeHandler.js +17 -0
- package/dist/components/core/extension/solid-core/emailTemplate/emailFormTypeChangeHandler.js.map +1 -0
- package/dist/components/core/extension/solid-core/emailTemplate/emailFormTypeLoad.d.ts +7 -0
- package/dist/components/core/extension/solid-core/emailTemplate/emailFormTypeLoad.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/emailTemplate/emailFormTypeLoad.js +17 -0
- package/dist/components/core/extension/solid-core/emailTemplate/emailFormTypeLoad.js.map +1 -0
- package/dist/components/core/extension/solid-core/roleMetadata/RolePermissionsManyToManyFieldWidget.d.ts +3 -0
- package/dist/components/core/extension/solid-core/roleMetadata/RolePermissionsManyToManyFieldWidget.d.ts.map +1 -0
- package/dist/components/core/extension/solid-core/roleMetadata/RolePermissionsManyToManyFieldWidget.js +78 -0
- package/dist/components/core/extension/solid-core/roleMetadata/RolePermissionsManyToManyFieldWidget.js.map +1 -0
- package/dist/components/core/form/SolidFormView.d.ts.map +1 -1
- package/dist/components/core/form/SolidFormView.js +89 -36
- package/dist/components/core/form/SolidFormView.js.map +1 -1
- package/dist/components/core/form/fields/SolidBooleanField.d.ts +1 -0
- package/dist/components/core/form/fields/SolidBooleanField.d.ts.map +1 -1
- package/dist/components/core/form/fields/SolidBooleanField.js +36 -8
- package/dist/components/core/form/fields/SolidBooleanField.js.map +1 -1
- package/dist/components/core/form/fields/SolidLongTextField.d.ts +2 -0
- package/dist/components/core/form/fields/SolidLongTextField.d.ts.map +1 -1
- package/dist/components/core/form/fields/SolidLongTextField.js +32 -3
- package/dist/components/core/form/fields/SolidLongTextField.js.map +1 -1
- package/dist/components/core/form/fields/SolidSelectionStaticField.d.ts +1 -0
- package/dist/components/core/form/fields/SolidSelectionStaticField.d.ts.map +1 -1
- package/dist/components/core/form/fields/SolidSelectionStaticField.js +19 -20
- package/dist/components/core/form/fields/SolidSelectionStaticField.js.map +1 -1
- package/dist/components/core/form/fields/relations/SolidRelationManyToManyField.d.ts +1 -3
- package/dist/components/core/form/fields/relations/SolidRelationManyToManyField.d.ts.map +1 -1
- package/dist/components/core/form/fields/relations/SolidRelationManyToManyField.js +19 -274
- package/dist/components/core/form/fields/relations/SolidRelationManyToManyField.js.map +1 -1
- package/dist/components/core/form/fields/relations/widgets/SolidRelationManyToManyAutocompleteWidget.d.ts +3 -0
- package/dist/components/core/form/fields/relations/widgets/SolidRelationManyToManyAutocompleteWidget.d.ts.map +1 -0
- package/dist/components/core/form/fields/relations/widgets/SolidRelationManyToManyAutocompleteWidget.js +38 -0
- package/dist/components/core/form/fields/relations/widgets/SolidRelationManyToManyAutocompleteWidget.js.map +1 -0
- package/dist/components/core/form/fields/relations/widgets/SolidRelationManyToManyCheckboxWidget.d.ts +3 -0
- package/dist/components/core/form/fields/relations/widgets/SolidRelationManyToManyCheckboxWidget.d.ts.map +1 -0
- package/dist/components/core/form/fields/relations/widgets/SolidRelationManyToManyCheckboxWidget.js +48 -0
- package/dist/components/core/form/fields/relations/widgets/SolidRelationManyToManyCheckboxWidget.js.map +1 -0
- package/dist/components/core/form/fields/relations/widgets/helpers/InlineRelationEntityDialog.d.ts +2 -0
- package/dist/components/core/form/fields/relations/widgets/helpers/InlineRelationEntityDialog.d.ts.map +1 -0
- package/dist/components/core/form/fields/relations/widgets/helpers/InlineRelationEntityDialog.js +35 -0
- package/dist/components/core/form/fields/relations/widgets/helpers/InlineRelationEntityDialog.js.map +1 -0
- package/dist/components/core/form/fields/relations/widgets/helpers/useRelationEntityHandler.d.ts +6 -0
- package/dist/components/core/form/fields/relations/widgets/helpers/useRelationEntityHandler.d.ts.map +1 -0
- package/dist/components/core/form/fields/relations/widgets/helpers/useRelationEntityHandler.js +119 -0
- package/dist/components/core/form/fields/relations/widgets/helpers/useRelationEntityHandler.js.map +1 -0
- package/dist/components/core/form/fields/widgets/SolidBooleanCheckboxFieldWidget.d.ts +3 -0
- package/dist/components/core/form/fields/widgets/SolidBooleanCheckboxFieldWidget.d.ts.map +1 -0
- package/dist/components/core/form/fields/widgets/SolidBooleanCheckboxFieldWidget.js +57 -0
- package/dist/components/core/form/fields/widgets/SolidBooleanCheckboxFieldWidget.js.map +1 -0
- package/dist/components/core/form/fields/widgets/SolidBooleanSelectFieldWidget.d.ts +3 -0
- package/dist/components/core/form/fields/widgets/SolidBooleanSelectFieldWidget.d.ts.map +1 -0
- package/dist/components/core/form/fields/widgets/SolidBooleanSelectFieldWidget.js +30 -0
- package/dist/components/core/form/fields/widgets/SolidBooleanSelectFieldWidget.js.map +1 -0
- package/dist/components/core/form/fields/widgets/SolidSelectionStaticAutocompleteFieldWidget.d.ts +3 -0
- package/dist/components/core/form/fields/widgets/SolidSelectionStaticAutocompleteFieldWidget.d.ts.map +1 -0
- package/dist/components/core/form/fields/widgets/SolidSelectionStaticAutocompleteFieldWidget.js +50 -0
- package/dist/components/core/form/fields/widgets/SolidSelectionStaticAutocompleteFieldWidget.js.map +1 -0
- package/dist/components/core/form/fields/widgets/SolidSelectionStaticRadioFieldWidget.d.ts +3 -0
- package/dist/components/core/form/fields/widgets/SolidSelectionStaticRadioFieldWidget.d.ts.map +1 -0
- package/dist/components/core/form/fields/widgets/SolidSelectionStaticRadioFieldWidget.js +32 -0
- package/dist/components/core/form/fields/widgets/SolidSelectionStaticRadioFieldWidget.js.map +1 -0
- package/dist/helpers/registry.d.ts +1 -1
- package/dist/helpers/registry.d.ts.map +1 -1
- package/dist/helpers/registry.js +27 -2
- package/dist/helpers/registry.js.map +1 -1
- package/package.json +1 -1
- package/src/components/core/extension/solid-core/emailTemplate/emailFormTypeChangeHandler.ts +18 -0
- package/src/components/core/extension/solid-core/emailTemplate/emailFormTypeLoad.ts +18 -0
- package/src/components/core/extension/solid-core/roleMetadata/RolePermissionsManyToManyFieldWidget.tsx +123 -0
- package/src/components/core/form/SolidFormView.tsx +75 -21
- package/src/components/core/form/fields/SolidBooleanField.tsx +45 -37
- package/src/components/core/form/fields/SolidLongTextField.tsx +79 -20
- package/src/components/core/form/fields/SolidSelectionStaticField.tsx +33 -46
- package/src/components/core/form/fields/relations/SolidRelationManyToManyField.tsx +20 -356
- package/src/components/core/form/fields/relations/widgets/SolidRelationManyToManyAutocompleteWidget.tsx +74 -0
- package/src/components/core/form/fields/relations/widgets/SolidRelationManyToManyCheckboxWidget.tsx +103 -0
- package/src/components/core/form/fields/relations/widgets/helpers/InlineRelationEntityDialog.tsx +33 -0
- package/src/components/core/form/fields/relations/widgets/helpers/useRelationEntityHandler.ts +64 -0
- package/src/components/core/form/fields/widgets/SolidBooleanCheckboxFieldWidget.tsx +79 -0
- package/src/components/core/form/fields/widgets/SolidBooleanSelectFieldWidget.tsx +68 -0
- package/src/components/core/form/fields/widgets/SolidSelectionStaticAutocompleteFieldWidget.tsx +72 -0
- package/src/components/core/form/fields/widgets/SolidSelectionStaticRadioFieldWidget.tsx +71 -0
- package/src/helpers/registry.ts +29 -2
- package/src/types/solid-core.d.ts +23 -1
package/src/components/core/form/fields/relations/widgets/SolidRelationManyToManyCheckboxWidget.tsx
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { SolidRelationManyToManyFieldWidgetProps } from "@/types/solid-core";
|
|
3
|
+
import { capitalize } from "lodash";
|
|
4
|
+
import { Checkbox } from "primereact/checkbox";
|
|
5
|
+
import { Panel } from "primereact/panel";
|
|
6
|
+
import { useEffect, useState } from "react";
|
|
7
|
+
import { Button } from "primereact/button";
|
|
8
|
+
import { useRelationEntityHandler } from "./helpers/useRelationEntityHandler";
|
|
9
|
+
import { InlineRelationEntityDialog } from "./helpers/InlineRelationEntityDialog";
|
|
10
|
+
|
|
11
|
+
export const SolidRelationManyToManyCheckboxWidget = ({formik, fieldContext }: SolidRelationManyToManyFieldWidgetProps) => {
|
|
12
|
+
const fieldMetadata = fieldContext.fieldMetadata;
|
|
13
|
+
const fieldLayoutInfo = fieldContext.field;
|
|
14
|
+
const showFieldLabel = fieldLayoutInfo?.attrs?.showLabel;
|
|
15
|
+
|
|
16
|
+
const readOnlyPermission = fieldContext.readOnly;
|
|
17
|
+
const [visibleCreateDialog, setVisibleCreateDialog] = useState(false);
|
|
18
|
+
const { autoCompleteItems, fetchRelationEntities, addNewRelation } = useRelationEntityHandler({ fieldContext, formik });
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
fetchRelationEntities();
|
|
22
|
+
}, []);
|
|
23
|
+
|
|
24
|
+
const handleCheckboxChange = (e: any) => {
|
|
25
|
+
if (formik.values[fieldLayoutInfo.attrs.name].some((item: any) => item.value === e.value)) {
|
|
26
|
+
formik.setFieldValue(fieldLayoutInfo.attrs.name, formik.values[fieldLayoutInfo.attrs.name].filter((s: any) => s.value !== e.value));
|
|
27
|
+
} else {
|
|
28
|
+
formik.setFieldValue(fieldLayoutInfo.attrs.name, [...formik.values[fieldLayoutInfo.attrs.name], e]);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const headerTemplate = (options: any) => {
|
|
33
|
+
const className = `${options.className} justify-content-space-between`;
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div className={className}>
|
|
37
|
+
<div className="flex align-items-center gap-3">
|
|
38
|
+
{showFieldLabel != false &&
|
|
39
|
+
<label className="form-field-label">
|
|
40
|
+
{capitalize(fieldLayoutInfo.attrs.name)}
|
|
41
|
+
{fieldMetadata.required && <span className="text-red-500"> *</span>}
|
|
42
|
+
</label>
|
|
43
|
+
}
|
|
44
|
+
{fieldContext.field.attrs.inlineCreate && (
|
|
45
|
+
<>
|
|
46
|
+
<Button
|
|
47
|
+
icon="pi pi-plus"
|
|
48
|
+
rounded
|
|
49
|
+
outlined
|
|
50
|
+
aria-label="Filter"
|
|
51
|
+
type="button"
|
|
52
|
+
size="small"
|
|
53
|
+
onClick={() => setVisibleCreateDialog(true)}
|
|
54
|
+
className="custom-add-button"
|
|
55
|
+
/>
|
|
56
|
+
<InlineRelationEntityDialog
|
|
57
|
+
visible={visibleCreateDialog}
|
|
58
|
+
setVisible={setVisibleCreateDialog}
|
|
59
|
+
fieldContext={fieldContext}
|
|
60
|
+
onCreate={addNewRelation}
|
|
61
|
+
/>
|
|
62
|
+
</>
|
|
63
|
+
)}
|
|
64
|
+
{/* <div className="many-to-many-add" >
|
|
65
|
+
<Button icon="pi pi-plus"
|
|
66
|
+
rounded
|
|
67
|
+
outlined
|
|
68
|
+
aria-label="Filter"
|
|
69
|
+
type="button"
|
|
70
|
+
onClick={() => autoCompleteSearch()}
|
|
71
|
+
/>
|
|
72
|
+
</div> */}
|
|
73
|
+
</div>
|
|
74
|
+
<div>
|
|
75
|
+
{options.togglerElement}
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
return (
|
|
81
|
+
<div>
|
|
82
|
+
|
|
83
|
+
<Panel toggleable headerTemplate={headerTemplate}>
|
|
84
|
+
<div className="formgrid grid">
|
|
85
|
+
{autoCompleteItems && autoCompleteItems.map((a: any, i: number) => {
|
|
86
|
+
return (
|
|
87
|
+
<div key={a.label} className={`field col-6 flex gap-2 ${i >= 2 ? 'mt-3' : ''}`}>
|
|
88
|
+
<Checkbox
|
|
89
|
+
readOnly={readOnlyPermission}
|
|
90
|
+
inputId={a.label}
|
|
91
|
+
checked={formik.values[fieldLayoutInfo.attrs.name].some((item: any) => item.label === a.label)}
|
|
92
|
+
onChange={() => handleCheckboxChange(a)}
|
|
93
|
+
/>
|
|
94
|
+
<label htmlFor={a.label} className="form-field-label m-0"> {a.label}</label>
|
|
95
|
+
</div>
|
|
96
|
+
)
|
|
97
|
+
})}
|
|
98
|
+
</div>
|
|
99
|
+
</Panel>
|
|
100
|
+
</div>
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
}
|
package/src/components/core/form/fields/relations/widgets/helpers/InlineRelationEntityDialog.tsx
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Dialog } from "primereact/dialog";
|
|
2
|
+
import { camelCase } from "lodash";
|
|
3
|
+
import SolidFormView from "@/components/core/form/SolidFormView";
|
|
4
|
+
|
|
5
|
+
export const InlineRelationEntityDialog = ({ visible, setVisible, fieldContext, onCreate }: any) => {
|
|
6
|
+
const fieldLayoutInfo = fieldContext.field;
|
|
7
|
+
|
|
8
|
+
const params = {
|
|
9
|
+
moduleName: fieldContext.fieldMetadata.relationModelModuleName,
|
|
10
|
+
id: "new",
|
|
11
|
+
embeded: true,
|
|
12
|
+
layout: fieldLayoutInfo?.attrs?.inlineCreateLayout,
|
|
13
|
+
customCreateHandler: (values: any) => {
|
|
14
|
+
setVisible(false);
|
|
15
|
+
onCreate(values);
|
|
16
|
+
},
|
|
17
|
+
inlineCreateAutoSave: fieldLayoutInfo?.attrs?.inlineCreateAutoSave,
|
|
18
|
+
handlePopupClose: () => setVisible(false),
|
|
19
|
+
modelName: camelCase(fieldContext.fieldMetadata.relationCoModelSingularName)
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Dialog
|
|
24
|
+
visible={visible}
|
|
25
|
+
showHeader={false}
|
|
26
|
+
style={{ width: fieldLayoutInfo?.attrs?.inlineCreateLayout?.attrs?.width ?? "60vw" }}
|
|
27
|
+
onHide={() => setVisible(false)}
|
|
28
|
+
className="solid-dialog"
|
|
29
|
+
>
|
|
30
|
+
<SolidFormView {...params} />
|
|
31
|
+
</Dialog>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import qs from "qs";
|
|
3
|
+
import { createSolidEntityApi } from "@/redux/api/solidEntityApi";
|
|
4
|
+
|
|
5
|
+
export const useRelationEntityHandler = ({ fieldContext, formik, autoCompleteLimit = 1000 }: any) => {
|
|
6
|
+
const fieldMetadata = fieldContext.fieldMetadata;
|
|
7
|
+
const fieldLayoutInfo = fieldContext.field;
|
|
8
|
+
|
|
9
|
+
const entityApi = createSolidEntityApi(fieldMetadata.relationCoModelSingularName);
|
|
10
|
+
const { useLazyGetSolidEntitiesQuery } = entityApi;
|
|
11
|
+
const [triggerGetSolidEntities] = useLazyGetSolidEntitiesQuery();
|
|
12
|
+
|
|
13
|
+
const [autoCompleteItems, setAutoCompleteItems] = useState([]);
|
|
14
|
+
|
|
15
|
+
const fetchRelationEntities = async (query = "", limit = autoCompleteLimit) => {
|
|
16
|
+
const queryData = {
|
|
17
|
+
offset: 0,
|
|
18
|
+
limit: limit,
|
|
19
|
+
filters: {
|
|
20
|
+
[fieldMetadata?.relationModel?.userKeyField?.name]: {
|
|
21
|
+
'$containsi': query
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const autocompleteQs = qs.stringify(queryData, { encodeValuesOnly: true });
|
|
27
|
+
|
|
28
|
+
const response = await triggerGetSolidEntities(autocompleteQs);
|
|
29
|
+
const data = response.data;
|
|
30
|
+
|
|
31
|
+
if (data) {
|
|
32
|
+
const mappedItems = data.records.map((item: any) => ({
|
|
33
|
+
label: item[fieldMetadata?.relationModel?.userKeyField?.name],
|
|
34
|
+
value: item['id'],
|
|
35
|
+
original: item
|
|
36
|
+
}));
|
|
37
|
+
setAutoCompleteItems(mappedItems);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const addNewRelation = (values: any) => {
|
|
42
|
+
const currentData = formik.values[fieldLayoutInfo.attrs.name] || [];
|
|
43
|
+
const jsonValues = Object.fromEntries(values.entries());
|
|
44
|
+
const newItem = {
|
|
45
|
+
label: jsonValues[fieldMetadata?.relationModel?.userKeyField?.name],
|
|
46
|
+
value: "new",
|
|
47
|
+
original: jsonValues,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
formik.setFieldValue(fieldLayoutInfo.attrs.name, [...currentData, newItem]);
|
|
51
|
+
|
|
52
|
+
// Optionally add to autocomplete list
|
|
53
|
+
setAutoCompleteItems((prev: any) => {
|
|
54
|
+
const exists = prev.some((item: any) => item.label === newItem.label);
|
|
55
|
+
return exists ? prev : [...prev, newItem];
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
autoCompleteItems,
|
|
61
|
+
fetchRelationEntities,
|
|
62
|
+
addNewRelation
|
|
63
|
+
};
|
|
64
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { SolidBooleanFieldWidgetProps } from "@/types/solid-core";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { Checkbox, CheckboxChangeEvent } from "primereact/checkbox";
|
|
5
|
+
import { Message } from "primereact/message";
|
|
6
|
+
import { classNames } from "primereact/utils";
|
|
7
|
+
|
|
8
|
+
export const SolidBooleanFieldCheckboxWidget = ({ formik, fieldContext }: SolidBooleanFieldWidgetProps) => {
|
|
9
|
+
const fieldMetadata = fieldContext.fieldMetadata;
|
|
10
|
+
const fieldLayoutInfo = fieldContext.field;
|
|
11
|
+
const className = fieldLayoutInfo.attrs?.className || "field col-12";
|
|
12
|
+
const fieldLabel = fieldLayoutInfo.attrs.label ?? fieldMetadata.displayName;
|
|
13
|
+
const solidFormViewMetaData = fieldContext.solidFormViewMetaData;
|
|
14
|
+
const showFieldLabel = fieldLayoutInfo?.attrs?.showLabel;
|
|
15
|
+
const readOnlyPermission = fieldContext.readOnly;
|
|
16
|
+
|
|
17
|
+
// Set default value to false on mount
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (formik.values[fieldLayoutInfo.attrs.name] === undefined) {
|
|
20
|
+
console.log("Setting default value:", false);
|
|
21
|
+
formik.setFieldValue(fieldLayoutInfo.attrs.name, false);
|
|
22
|
+
}
|
|
23
|
+
}, []);
|
|
24
|
+
|
|
25
|
+
const handleChange = (e: CheckboxChangeEvent) => {
|
|
26
|
+
const newValue = e.checked; // This returns `true` or `false`
|
|
27
|
+
console.log(`${fieldLayoutInfo.attrs.name}, new value:`, newValue);
|
|
28
|
+
|
|
29
|
+
formik.setFieldValue(fieldLayoutInfo.attrs.name, newValue === true ? 'true' : 'false');
|
|
30
|
+
formik.setTouched({ ...formik.touched, [fieldLayoutInfo.attrs.name]: true }); // Ensure Formik registers the change
|
|
31
|
+
// ✅ Check if Formik updated the value correctly
|
|
32
|
+
setTimeout(() => {
|
|
33
|
+
console.log("Formik values after update:", formik.values);
|
|
34
|
+
}, 0);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const isFormFieldValid = (formik:any, fieldName:any) =>
|
|
38
|
+
formik.touched[fieldName] && formik.errors[fieldName];
|
|
39
|
+
|
|
40
|
+
const fieldDisabled = fieldLayoutInfo.attrs?.disabled;
|
|
41
|
+
const fieldReadonly = fieldLayoutInfo.attrs?.readonly;
|
|
42
|
+
const formDisabled = solidFormViewMetaData.data.solidView?.layout?.attrs?.disabled;
|
|
43
|
+
const formReadonly = solidFormViewMetaData.data.solidView?.layout?.attrs?.readonly;
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<div className={className}>
|
|
47
|
+
<div className="relative">
|
|
48
|
+
<div className="flex flex-column gap-2 mt-4">
|
|
49
|
+
{showFieldLabel !== false && (
|
|
50
|
+
<label htmlFor={fieldLayoutInfo.attrs.name} className="form-field-label">
|
|
51
|
+
{fieldLabel}
|
|
52
|
+
{fieldMetadata.required && <span className="text-red-500"> *</span>}
|
|
53
|
+
</label>
|
|
54
|
+
)}
|
|
55
|
+
|
|
56
|
+
<div className="flex align-items-center">
|
|
57
|
+
<Checkbox
|
|
58
|
+
id={fieldLayoutInfo.attrs.name}
|
|
59
|
+
checked={formik.values[fieldLayoutInfo.attrs.name] === 'true' || formik.initialValues[fieldLayoutInfo.attrs.name] === 'true'}
|
|
60
|
+
onChange={handleChange}
|
|
61
|
+
disabled={formDisabled || fieldDisabled}
|
|
62
|
+
readOnly={formReadonly || fieldReadonly || readOnlyPermission}
|
|
63
|
+
className={classNames("", {
|
|
64
|
+
"p-invalid": isFormFieldValid(formik, fieldLayoutInfo.attrs.name),
|
|
65
|
+
})}
|
|
66
|
+
/>
|
|
67
|
+
<span className="ml-2">{fieldLabel || "Yes"}</span>
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
{isFormFieldValid(formik, fieldLayoutInfo.attrs.name) && (
|
|
72
|
+
<div className="absolute mt-1">
|
|
73
|
+
<Message severity="error" text={formik.errors[fieldLayoutInfo.attrs.name]?.toString()} />
|
|
74
|
+
</div>
|
|
75
|
+
)}
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { SolidBooleanFieldWidgetProps } from "@/types/solid-core";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { Message } from "primereact/message";
|
|
5
|
+
import { classNames } from "primereact/utils";
|
|
6
|
+
import { SelectButton } from "primereact/selectbutton";
|
|
7
|
+
|
|
8
|
+
export const SolidBooleanFieldSelectWidget = ({ formik, fieldContext }: SolidBooleanFieldWidgetProps) => {
|
|
9
|
+
const fieldMetadata = fieldContext.fieldMetadata;
|
|
10
|
+
const fieldLayoutInfo = fieldContext.field;
|
|
11
|
+
const className = fieldLayoutInfo.attrs?.className || 'field col-12';
|
|
12
|
+
const fieldLabel = fieldLayoutInfo.attrs.label ?? fieldMetadata.displayName;
|
|
13
|
+
const fieldDescription = fieldLayoutInfo.attrs.description ?? fieldMetadata.description;
|
|
14
|
+
const booleanOptions = ["false", "true"];
|
|
15
|
+
const solidFormViewMetaData = fieldContext.solidFormViewMetaData;
|
|
16
|
+
const showFieldLabel = fieldLayoutInfo?.attrs?.showLabel;
|
|
17
|
+
const readOnlyPermission = fieldContext.readOnly;
|
|
18
|
+
|
|
19
|
+
useEffect(() => { formik.setFieldValue(fieldLayoutInfo.attrs.name, "false") }, [])
|
|
20
|
+
|
|
21
|
+
const isFormFieldValid = (formik: any, fieldName: string) => formik.touched[fieldName] && formik.errors[fieldName];
|
|
22
|
+
|
|
23
|
+
const fieldDisabled = fieldLayoutInfo.attrs?.disabled;
|
|
24
|
+
const fieldReadonly = fieldLayoutInfo.attrs?.readonly;
|
|
25
|
+
|
|
26
|
+
const formDisabled = solidFormViewMetaData.data.solidView?.layout?.attrs?.disabled;
|
|
27
|
+
const formReadonly = solidFormViewMetaData.data.solidView?.layout?.attrs?.readonly;
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<div className={className}>
|
|
31
|
+
<div className="relative">
|
|
32
|
+
<div className="flex flex-column gap-2 mt-4">
|
|
33
|
+
{showFieldLabel != false &&
|
|
34
|
+
<label htmlFor={fieldLayoutInfo.attrs.name} className="form-field-label">{fieldLabel}
|
|
35
|
+
{fieldMetadata.required && <span className="text-red-500"> *</span>}
|
|
36
|
+
{/* {fieldDescription && <span className="form_field_help">({fieldDescription}) </span>} */}
|
|
37
|
+
</label>
|
|
38
|
+
}
|
|
39
|
+
{/* <InputText
|
|
40
|
+
id={fieldLayoutInfo.attrs.name}
|
|
41
|
+
className="small-input"
|
|
42
|
+
aria-describedby={`${fieldLayoutInfo.attrs.name}-help`}
|
|
43
|
+
onChange={formik.handleChange}
|
|
44
|
+
value={formik.values[fieldLayoutInfo.attrs.name] || ''}
|
|
45
|
+
/> */}
|
|
46
|
+
<SelectButton
|
|
47
|
+
readOnly={formReadonly || fieldReadonly || readOnlyPermission}
|
|
48
|
+
disabled={formDisabled || fieldDisabled}
|
|
49
|
+
id={fieldLayoutInfo.attrs.name}
|
|
50
|
+
aria-describedby={`${fieldLayoutInfo.attrs.name}-help`}
|
|
51
|
+
onChange={(e) => {formik.setFieldValue(fieldLayoutInfo.attrs.name, e.value); console.log("value is",e.value)}} // Custom handling for boolean input
|
|
52
|
+
value={formik.values[fieldLayoutInfo.attrs.name] ? formik.values[fieldLayoutInfo.attrs.name].toString() : "false"}
|
|
53
|
+
options={booleanOptions}
|
|
54
|
+
className={classNames("", {
|
|
55
|
+
"p-invalid": isFormFieldValid(formik, "defaultValue"),
|
|
56
|
+
})}
|
|
57
|
+
|
|
58
|
+
/>
|
|
59
|
+
</div>
|
|
60
|
+
{isFormFieldValid(formik, fieldLayoutInfo.attrs.name) && (
|
|
61
|
+
<div className="absolute mt-1">
|
|
62
|
+
<Message severity="error" text={formik?.errors[fieldLayoutInfo.attrs.name]?.toString()} />
|
|
63
|
+
</div>
|
|
64
|
+
)}
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
}
|
package/src/components/core/form/fields/widgets/SolidSelectionStaticAutocompleteFieldWidget.tsx
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { SolidSelectionStaticFieldWidgetProps } from "@/types/solid-core";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { Message } from "primereact/message";
|
|
5
|
+
import { classNames } from "primereact/utils";
|
|
6
|
+
import { SelectButton } from "primereact/selectbutton";
|
|
7
|
+
import { AutoComplete, AutoCompleteCompleteEvent } from "primereact/autocomplete";
|
|
8
|
+
|
|
9
|
+
export const SolidSelectionStaticAutocompleteWidget = ({ formik, fieldContext }: SolidSelectionStaticFieldWidgetProps) => {
|
|
10
|
+
const fieldMetadata = fieldContext.fieldMetadata;
|
|
11
|
+
const fieldLayoutInfo = fieldContext.field;
|
|
12
|
+
const className = fieldLayoutInfo.attrs?.className || 'field col-12';
|
|
13
|
+
const fieldLabel = fieldLayoutInfo.attrs.label ?? fieldMetadata.displayName;
|
|
14
|
+
const fieldDescription = fieldLayoutInfo.attrs.description ?? fieldMetadata.description;
|
|
15
|
+
const solidFormViewMetaData = fieldContext.solidFormViewMetaData;
|
|
16
|
+
const showFieldLabel = fieldLayoutInfo?.attrs?.showLabel;
|
|
17
|
+
const readOnlyPermission = fieldContext.readOnly;
|
|
18
|
+
const fieldDisabled = fieldLayoutInfo.attrs?.disabled;
|
|
19
|
+
const fieldReadonly = fieldLayoutInfo.attrs?.readonly;
|
|
20
|
+
|
|
21
|
+
const formDisabled = solidFormViewMetaData.data.solidView?.layout?.attrs?.disabled;
|
|
22
|
+
const formReadonly = solidFormViewMetaData.data.solidView?.layout?.attrs?.readonly;
|
|
23
|
+
|
|
24
|
+
const [selectionStaticItems, setSelectionStaticItems] = useState([]);
|
|
25
|
+
const selectionStaticSearch = (event: AutoCompleteCompleteEvent) => {
|
|
26
|
+
const selectionStaticData = fieldMetadata.selectionStaticValues.map((i: string) => {
|
|
27
|
+
return {
|
|
28
|
+
label: i.split(":")[1],
|
|
29
|
+
value: i.split(":")[0]
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
const suggestionData = selectionStaticData.filter((t: any) => t.value.toLowerCase().startsWith(event.query.toLowerCase()));
|
|
33
|
+
setSelectionStaticItems(suggestionData)
|
|
34
|
+
}
|
|
35
|
+
const isFormFieldValid = (formik: any, fieldName: string) => formik.touched[fieldName] && formik.errors[fieldName];
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div className={className}>
|
|
39
|
+
<div className="relative">
|
|
40
|
+
<div className="flex flex-column gap-2 mt-4">
|
|
41
|
+
{showFieldLabel != false &&
|
|
42
|
+
<label htmlFor={fieldLayoutInfo.attrs.name} className="form-field-label">{fieldLabel}
|
|
43
|
+
{fieldMetadata.required && <span className="text-red-500"> *</span>}
|
|
44
|
+
{/* {fieldDescription && <span className="form_field_help">({fieldDescription}) </span>} */}
|
|
45
|
+
</label>
|
|
46
|
+
}
|
|
47
|
+
<AutoComplete
|
|
48
|
+
readOnly={formReadonly || fieldReadonly || readOnlyPermission}
|
|
49
|
+
disabled={formDisabled || fieldDisabled}
|
|
50
|
+
{...formik.getFieldProps(fieldLayoutInfo.attrs.name)}
|
|
51
|
+
id={fieldLayoutInfo.attrs.name}
|
|
52
|
+
name={fieldLayoutInfo.attrs.name}
|
|
53
|
+
field="label"
|
|
54
|
+
value={formik.values[fieldLayoutInfo.attrs.name] || ''}
|
|
55
|
+
dropdown
|
|
56
|
+
suggestions={selectionStaticItems}
|
|
57
|
+
completeMethod={selectionStaticSearch}
|
|
58
|
+
// onChange={(e) => updateInputs(index, e.value)} />
|
|
59
|
+
// onChange={formik.handleChange}
|
|
60
|
+
onChange={(e) => fieldContext.onChange(e, 'onFieldChange')}
|
|
61
|
+
className="solid-standard-autocomplete"
|
|
62
|
+
/>
|
|
63
|
+
</div>
|
|
64
|
+
{isFormFieldValid(formik, fieldLayoutInfo.attrs.name) && (
|
|
65
|
+
<div className="absolute mt-1">
|
|
66
|
+
<Message severity="error" text={formik?.errors[fieldLayoutInfo.attrs.name]?.toString()} />
|
|
67
|
+
</div>
|
|
68
|
+
)}
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { SolidSelectionStaticFieldWidgetProps } from "@/types/solid-core";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { Message } from "primereact/message";
|
|
5
|
+
import { classNames } from "primereact/utils";
|
|
6
|
+
import { SelectButton } from "primereact/selectbutton";
|
|
7
|
+
import { AutoComplete, AutoCompleteCompleteEvent } from "primereact/autocomplete";
|
|
8
|
+
import { RadioButton } from "primereact/radiobutton";
|
|
9
|
+
|
|
10
|
+
export const SolidSelectionStaticRadioWidget = ({ formik, fieldContext }: SolidSelectionStaticFieldWidgetProps) => {
|
|
11
|
+
const fieldMetadata = fieldContext.fieldMetadata;
|
|
12
|
+
const fieldLayoutInfo = fieldContext.field;
|
|
13
|
+
const className = fieldLayoutInfo.attrs?.className || 'field col-12';
|
|
14
|
+
const fieldLabel = fieldLayoutInfo.attrs.label ?? fieldMetadata.displayName;
|
|
15
|
+
const showFieldLabel = fieldLayoutInfo?.attrs?.showLabel;
|
|
16
|
+
const readOnlyPermission = fieldContext.readOnly;
|
|
17
|
+
|
|
18
|
+
const fieldDisabled = fieldLayoutInfo.attrs?.disabled;
|
|
19
|
+
const fieldReadonly = fieldLayoutInfo.attrs?.readonly;
|
|
20
|
+
const formDisabled = fieldContext.solidFormViewMetaData.data.solidView?.layout?.attrs?.disabled;
|
|
21
|
+
const formReadonly = fieldContext.solidFormViewMetaData.data.solidView?.layout?.attrs?.readonly;
|
|
22
|
+
|
|
23
|
+
const fieldName = fieldLayoutInfo.attrs.name;
|
|
24
|
+
|
|
25
|
+
// Convert selectionStaticValues to usable radio options
|
|
26
|
+
const radioOptions = fieldMetadata.selectionStaticValues.map((i: string) => {
|
|
27
|
+
const [value, label] = i.split(":");
|
|
28
|
+
return { label, value };
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const isFormFieldValid = (formik: any, fieldName: string) =>
|
|
32
|
+
formik.touched[fieldName] && formik.errors[fieldName];
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<div className={className}>
|
|
36
|
+
<div className="relative">
|
|
37
|
+
<div className="flex flex-column gap-2 mt-4">
|
|
38
|
+
{showFieldLabel !== false && (
|
|
39
|
+
<label htmlFor={fieldName} className="form-field-label">
|
|
40
|
+
{fieldLabel}
|
|
41
|
+
{fieldMetadata.required && <span className="text-red-500"> *</span>}
|
|
42
|
+
</label>
|
|
43
|
+
)}
|
|
44
|
+
<div className="flex flex-wrap gap-3">
|
|
45
|
+
{radioOptions.map((option: any) => (
|
|
46
|
+
<div key={option.value} className="flex items-center">
|
|
47
|
+
<RadioButton
|
|
48
|
+
id={`${fieldName}-${option.value}`}
|
|
49
|
+
name={fieldName}
|
|
50
|
+
value={option}
|
|
51
|
+
checked={formik.values[fieldName]?.value === option.value}
|
|
52
|
+
onChange={(e) => formik.setFieldValue(fieldName, e.value)}
|
|
53
|
+
disabled={formReadonly || fieldReadonly || readOnlyPermission || formDisabled || fieldDisabled}
|
|
54
|
+
className="mr-2"
|
|
55
|
+
/>
|
|
56
|
+
<label htmlFor={`${fieldName}-${option.value}`} className="cursor-pointer">
|
|
57
|
+
{option.label}
|
|
58
|
+
</label>
|
|
59
|
+
</div>
|
|
60
|
+
))}
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
{isFormFieldValid(formik, fieldName) && (
|
|
64
|
+
<div className="absolute mt-1">
|
|
65
|
+
<Message severity="error" text={formik?.errors[fieldName]?.toString()} />
|
|
66
|
+
</div>
|
|
67
|
+
)}
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
}
|
package/src/helpers/registry.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
import hanldeEmailFormTypeChange from "@/components/core/extension/solid-core/emailTemplate/emailFormTypeChangeHandler";
|
|
2
|
+
import hanldeEmailFormTypeLoad from "@/components/core/extension/solid-core/emailTemplate/emailFormTypeLoad";
|
|
3
|
+
import { RolePermissionsManyToManyFieldWidget } from "@/components/core/extension/solid-core/roleMetadata/RolePermissionsManyToManyFieldWidget";
|
|
4
|
+
import { SolidRelationManyToManyAutocompleteWidget } from "@/components/core/form/fields/relations/widgets/SolidRelationManyToManyAutocompleteWidget";
|
|
5
|
+
import { SolidRelationManyToManyCheckboxWidget } from "@/components/core/form/fields/relations/widgets/SolidRelationManyToManyCheckboxWidget";
|
|
1
6
|
import { CustomHtml } from "@/components/core/form/widgets/CustomHtml";
|
|
2
7
|
import React from "react";
|
|
8
|
+
import { SolidBooleanFieldCheckboxWidget } from "@/components/core/form/fields/widgets/SolidBooleanCheckboxFieldWidget";
|
|
9
|
+
import { SolidBooleanFieldSelectWidget } from "@/components/core/form/fields/widgets/SolidBooleanSelectFieldWidget";
|
|
10
|
+
import { SolidSelectionStaticAutocompleteWidget } from "@/components/core/form/fields/widgets/SolidSelectionStaticAutocompleteFieldWidget";
|
|
11
|
+
import { SolidSelectionStaticRadioWidget } from "@/components/core/form/fields/widgets/SolidSelectionStaticRadioFieldWidget";
|
|
3
12
|
|
|
4
13
|
type ExtensionRegistry = {
|
|
5
14
|
components: Record<string, React.ComponentType<any>>;
|
|
@@ -11,9 +20,13 @@ const extensionRegistry: ExtensionRegistry = {
|
|
|
11
20
|
functions: {},
|
|
12
21
|
};
|
|
13
22
|
|
|
14
|
-
export const registerExtensionComponent = (name: string, component: React.ComponentType<any
|
|
23
|
+
export const registerExtensionComponent = (name: string, component: React.ComponentType<any>, aliases: string[] = []) => {
|
|
15
24
|
// console.log(`registerExtensionComponent invoked... ${name}`);
|
|
16
25
|
extensionRegistry.components[name] = component;
|
|
26
|
+
for (let i = 0; i < aliases.length; i++) {
|
|
27
|
+
const alias = aliases[i];
|
|
28
|
+
extensionRegistry.components[alias] = component;
|
|
29
|
+
}
|
|
17
30
|
};
|
|
18
31
|
|
|
19
32
|
export const registerExtensionFunction = (name: string, fn: (...args: any[]) => any) => {
|
|
@@ -55,10 +68,24 @@ export const getExtensionFunction = (name: string) => {
|
|
|
55
68
|
|
|
56
69
|
// Register all the dynamic widget & functions from inside solid-core-ui
|
|
57
70
|
// Common
|
|
58
|
-
registerExtensionComponent("CustomHtml", CustomHtml);
|
|
71
|
+
registerExtensionComponent("CustomHtml", CustomHtml, []);
|
|
72
|
+
registerExtensionComponent("SolidRelationManyToManyCheckboxWidget", SolidRelationManyToManyCheckboxWidget, ["checkbox"]);
|
|
73
|
+
registerExtensionComponent("SolidRelationManyToManyAutocompleteWidget", SolidRelationManyToManyAutocompleteWidget, ["autocomplete"]);
|
|
74
|
+
registerExtensionComponent("SolidBooleanFieldCheckboxWidget", SolidBooleanFieldCheckboxWidget, ["field-checkbox"]);
|
|
75
|
+
registerExtensionComponent("SolidBooleanFieldSelectWidget", SolidBooleanFieldSelectWidget, ["field-selectbox"]);
|
|
76
|
+
registerExtensionComponent("SolidSelectionStaticAutocompleteWidget", SolidSelectionStaticAutocompleteWidget, ["field-autocomplete"]);
|
|
77
|
+
registerExtensionComponent("SolidSelectionStaticRadioWidget", SolidSelectionStaticRadioWidget, ["field-radio"]);
|
|
59
78
|
|
|
60
79
|
|
|
61
80
|
// ModuleMetadata
|
|
62
81
|
|
|
63
82
|
|
|
64
83
|
// ModelMetadata
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
// Email Template
|
|
87
|
+
registerExtensionFunction("emailFormTypeChangeHandler", hanldeEmailFormTypeChange);
|
|
88
|
+
registerExtensionFunction("emailFormTypeLoad", hanldeEmailFormTypeLoad);
|
|
89
|
+
|
|
90
|
+
// RoleMetadata
|
|
91
|
+
registerExtensionComponent("RolePermissionsManyToManyFieldWidget", RolePermissionsManyToManyFieldWidget, ["inputSwitch"]);
|
|
@@ -67,6 +67,7 @@ export type LayoutAttribute = {
|
|
|
67
67
|
label?: string;
|
|
68
68
|
className?: string;
|
|
69
69
|
inlineCreate?: string;
|
|
70
|
+
renderMode?: string;
|
|
70
71
|
};
|
|
71
72
|
|
|
72
73
|
// Generic representation of any node in our layout
|
|
@@ -78,7 +79,7 @@ export type LayoutNode = {
|
|
|
78
79
|
};
|
|
79
80
|
|
|
80
81
|
// Event type
|
|
81
|
-
export type SolidUiEvents = "onFieldChange" | "onFieldBlur" | "onCustomWidgetRender";
|
|
82
|
+
export type SolidUiEvents = "onFieldChange" | "onFieldBlur" | "onCustomWidgetRender" | "onFormDataLoad" | "onFormLayoutLoad";
|
|
82
83
|
export type SolidUiEvent = {
|
|
83
84
|
type: SolidUiEvents;
|
|
84
85
|
modifiedField?: string;
|
|
@@ -89,6 +90,13 @@ export type SolidUiEvent = {
|
|
|
89
90
|
fieldsMetadata: FieldsMetadata;
|
|
90
91
|
};
|
|
91
92
|
|
|
93
|
+
export type SolidLoadForm = {
|
|
94
|
+
type: SolidUiEvents;
|
|
95
|
+
formData: Record<string, any>;
|
|
96
|
+
viewMetadata: SolidView;
|
|
97
|
+
fieldsMetadata: FieldsMetadata;
|
|
98
|
+
}
|
|
99
|
+
|
|
92
100
|
export type SolidFormWidgetProps = {
|
|
93
101
|
field: any;
|
|
94
102
|
// This comes from Formik...
|
|
@@ -96,3 +104,17 @@ export type SolidFormWidgetProps = {
|
|
|
96
104
|
viewMetadata: SolidView;
|
|
97
105
|
fieldsMetadata: FieldsMetadata;
|
|
98
106
|
};
|
|
107
|
+
|
|
108
|
+
export type SolidRelationManyToManyFieldWidgetProps = {
|
|
109
|
+
formik: any;
|
|
110
|
+
fieldContext?: SolidFieldProps;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export type SolidBooleanFieldWidgetProps = {
|
|
114
|
+
formik: any;
|
|
115
|
+
fieldContext?: SolidFieldProps;
|
|
116
|
+
};
|
|
117
|
+
export type SolidSelectionStaticFieldWidgetProps = {
|
|
118
|
+
formik: any;
|
|
119
|
+
fieldContext?: SolidFieldProps;
|
|
120
|
+
};
|