@@ -1463,7 +1630,8 @@ const getComponentIcon = (type) => {
'form-section': 'material-symbols:view-module-outline',
'info-display': 'heroicons:information-circle',
'dynamic-list': 'heroicons:list-bullet',
- 'repeating-table': 'heroicons:table-cells'
+ 'repeating-table': 'heroicons:table-cells',
+ 'repeating-group': 'heroicons:list-bullet'
}
return icons[type] || 'heroicons:square-3-stack-3d'
}
@@ -1498,7 +1666,8 @@ const getComponentTypeName = (type) => {
'form-section': 'Form Section',
'info-display': 'Information Display',
'dynamic-list': 'Dynamic List',
- 'repeating-table': 'Data Table'
+ 'repeating-table': 'Data Table',
+ 'repeating-group': 'Repeating Group'
}
return names[type] || 'Form Field'
}
@@ -1533,7 +1702,8 @@ const getComponentDescription = (type) => {
'form-section': 'Visual container to group related form fields into sections',
'info-display': 'Read-only information display in organized format',
'dynamic-list': 'Dynamic list for displaying and managing items',
- 'repeating-table': 'Structured table for collecting multiple records with forms'
+ 'repeating-table': 'Structured table for collecting multiple records with forms',
+ 'repeating-group': 'Collect multiple entries of the same data structure'
}
return descriptions[type] || 'Configure this form field'
}
@@ -1558,14 +1728,14 @@ const showField = (fieldName) => {
if (!props.component) return false
const fieldConfig = {
- label: ['text', 'textarea', 'number', 'email', 'password', 'url', 'tel', 'mask', 'select', 'checkbox', 'radio', 'switch', 'date', 'time', 'datetime-local', 'range', 'color', 'file', 'otp', 'dropzone', 'button', 'form-section', 'dynamic-list', 'repeating-table'],
- name: ['text', 'textarea', 'number', 'email', 'password', 'url', 'tel', 'mask', 'hidden', 'select', 'checkbox', 'radio', 'switch', 'date', 'time', 'datetime-local', 'range', 'color', 'file', 'otp', 'dropzone', 'button', 'form-section', 'dynamic-list', 'repeating-table'],
+ label: ['text', 'textarea', 'number', 'email', 'password', 'url', 'tel', 'mask', 'select', 'checkbox', 'radio', 'switch', 'date', 'time', 'datetime-local', 'range', 'color', 'file', 'otp', 'dropzone', 'button', 'form-section', 'dynamic-list', 'repeating-table', 'repeating-group'],
+ name: ['text', 'textarea', 'number', 'email', 'password', 'url', 'tel', 'mask', 'hidden', 'select', 'checkbox', 'radio', 'switch', 'date', 'time', 'datetime-local', 'range', 'color', 'file', 'otp', 'dropzone', 'button', 'form-section', 'dynamic-list', 'repeating-table', 'repeating-group'],
placeholder: ['text', 'textarea', 'number', 'email', 'password', 'url', 'tel', 'mask', 'select', 'dynamic-list'],
- help: ['text', 'textarea', 'number', 'email', 'password', 'url', 'tel', 'mask', 'hidden', 'select', 'checkbox', 'radio', 'switch', 'date', 'time', 'datetime-local', 'range', 'color', 'file', 'otp', 'dropzone', 'button', 'form-section', 'dynamic-list', 'repeating-table'],
+ help: ['text', 'textarea', 'number', 'email', 'password', 'url', 'tel', 'mask', 'hidden', 'select', 'checkbox', 'radio', 'switch', 'date', 'time', 'datetime-local', 'range', 'color', 'file', 'otp', 'dropzone', 'button', 'form-section', 'dynamic-list', 'repeating-table', 'repeating-group'],
value: ['heading', 'paragraph', 'hidden'],
- width: ['text', 'textarea', 'number', 'email', 'password', 'url', 'tel', 'mask', 'select', 'checkbox', 'radio', 'switch', 'date', 'time', 'datetime-local', 'range', 'color', 'file', 'otp', 'dropzone', 'button', 'heading', 'paragraph', 'form-section', 'info-display', 'dynamic-list', 'repeating-table'],
+ width: ['text', 'textarea', 'number', 'email', 'password', 'url', 'tel', 'mask', 'select', 'checkbox', 'radio', 'switch', 'date', 'time', 'datetime-local', 'range', 'color', 'file', 'otp', 'dropzone', 'button', 'heading', 'paragraph', 'form-section', 'info-display', 'dynamic-list', 'repeating-table', 'repeating-group'],
options: ['select', 'checkbox', 'radio'],
- conditionalLogic: ['text', 'textarea', 'number', 'email', 'password', 'url', 'tel', 'select', 'checkbox', 'radio', 'switch', 'date', 'time', 'datetime-local', 'range', 'color', 'file', 'form-section', 'dynamic-list', 'repeating-table']
+ conditionalLogic: ['text', 'textarea', 'number', 'email', 'password', 'url', 'tel', 'select', 'checkbox', 'radio', 'switch', 'date', 'time', 'datetime-local', 'range', 'color', 'file', 'form-section', 'dynamic-list', 'repeating-table', 'repeating-group']
}
return fieldConfig[fieldName]?.includes(props.component.type) || false
@@ -1574,7 +1744,7 @@ const showField = (fieldName) => {
const hasOptions = computed(() => showField('options'))
const hasSpecificSettings = computed(() => {
if (!props.component) return false
- const specificTypes = ['mask', 'otp', 'dropzone', 'range', 'button', 'form-section', 'dynamic-list', 'repeating-table']
+ const specificTypes = ['mask', 'otp', 'dropzone', 'range', 'button', 'form-section', 'dynamic-list', 'repeating-table', 'repeating-group']
return specificTypes.includes(props.component.type)
})
@@ -2031,6 +2201,42 @@ const removeNestedComponent = (index) => {
}
}
+// Repeating group field management
+const addGroupField = () => {
+ if (!configModel.value.fields) {
+ configModel.value.fields = []
+ }
+
+ configModel.value.fields.push({
+ type: 'text',
+ name: `field_${configModel.value.fields.length + 1}`,
+ label: `Field ${configModel.value.fields.length + 1}`,
+ placeholder: 'Enter value'
+ })
+}
+
+const removeGroupField = (index) => {
+ if (configModel.value.fields) {
+ configModel.value.fields.splice(index, 1)
+ }
+}
+
+const addFieldOption = (field) => {
+ if (!field.options) {
+ field.options = []
+ }
+ field.options.push({
+ label: `Option ${field.options.length + 1}`,
+ value: `option_${field.options.length + 1}`
+ })
+}
+
+const removeFieldOption = (field, optionIndex) => {
+ if (field.options) {
+ field.options.splice(optionIndex, 1)
+ }
+}
+
// Type changing methods
const handleTypeChange = (newType) => {
if (newType === props.component.type) return
diff --git a/components/RsModal.vue b/components/RsModal.vue
index 660e788..d135ab0 100644
--- a/components/RsModal.vue
+++ b/components/RsModal.vue
@@ -1,5 +1,5 @@