Frontend ​
Directory Structure ​
vue/src/js/
├── components/ # inputs, layouts, table, modals, form
├── hooks/ # useForm, useTable, useInput, etc.
├── utils/ # schema, helpers, getFormData
└── store/ # Vuex (config, user, language, etc.)Component Organization ​
| Location | Purpose |
|---|---|
components/inputs/ | Form input components |
components/layouts/ | Main, Sidebar, Home |
components/table/ | Table, TableActions |
components/modals/ | Modal, DynamicModal, ModalMedia |
components/customs/ | App-specific overrides (UeCustom*) |
components/labs/ | Experimental — not guaranteed stable |
Form Flow ​
- Form.vue — receives
schemaandmodelValue, usesuseForm - FormBase — iterates over
flatCombinedArraySorted(flattened schema + model) - FormBaseField — renders each field by
obj.schema.type:- Special cases:
preview,dynamic-component,title,radio,array,wrap/group - Default:
<component :is="mapTypeToComponent(obj.schema.type)" v-bind="bindSchema(obj)" />
- Special cases:
- Input components — receive
obj.schemaviabindSchema(obj)
Table Flow ​
- Table.vue — uses
useTable, passes props tov-data-table-server - useTable — orchestrates:
useTableItem— edited item, create/edit/deleteuseTableHeaders— column definitionsuseTableFilters— search, main filters, advanced filtersuseTableForms— form modal open/closeuseTableItemActions— row actionsuseTableModals— dialogs
- store/api/datatable.js — axios calls for index, delete, restore, bulk actions
Input Registry ​
components/inputs/registry.js:
- builtInTypeMap — Vuetify primitives (
text→v-text-field, etc.) - hydrateTypeMap — Hydrate output types → custom components
- customTypeMap — App-registered via
registerInputType(type, component)
js
import { registerInputType, mapTypeToComponent } from '@/components/inputs/registry'
registerInputType('my-input', 'VMyInput')
const component = mapTypeToComponent('my-input') // => 'VMyInput'Hooks ​
For the full hook reference including all 38 composables, see Vue Hooks.
| Hook | Purpose |
|---|---|
| useForm | Form state, validation, submit, schema/model sync |
| useFormBaseLogic | Form base logic for FormBase |
| useInput | Input state, modelValue, boundProps from schema |
| useTable | Main table composable |
| useTableItem, useTableHeaders, useTableFilters | Table sub-hooks |
| useValidation | Validation rules, invokeRuleGenerator |
| useCurrency, useCurrencyNumber | Currency formatting |
| useMediaLibrary, useMediaItems | Media selection |
| useConfig, useUser, useLocale | App state |
| useAlert | Global alert notifications |
| useAuthorization | Permission and role checks |
| useCache | Client-side key-value cache |
| useCastAttributes | Dynamic $notation attribute interpolation |
| useDraggable | Sortable drag-and-drop props |
| useDynamicModal | Inject-based global modal service |
| useFile / useImage | File / image media-library inputs |
| useFilepond | FilePond upload props and rules |
| useFormatter | Table column value formatters |
| useInertiaRequests | In-flight Inertia request state |
| useInputFetch | Paginated remote fetch for select inputs |
| useInputHandlers | Slot-driven input click handlers |
| useItemActions | Form action buttons |
| useModal | Modal open/close, width, fullscreen |
| useModelValue | v-model two-way binding helper |
| useModule | Module i18n name and permission key |
| useNavigationLayout | Topbar / bottom-nav config |
| useRandKey | Unique component instance key |
| useRepeater | Repeater block state management |
| useSidebar | Sidebar open/close, rail, resize |
| useSvg | SVG symbol utilities |
| useActiveTableItem | Active row / detail-panel state |
Utils ​
| File | Purpose |
|---|---|
| schema.js | isViewOnlyInput, processInputs, flattenGroupSchema |
| getFormData.js | getSchema, getModel, getSubmitFormData |
| helpers.js | isset, isObject, dataGet (prefer over window.__*) |
| formEvents.js | handleInputEvents, setSchemaInputField |
Store (Vuex) ​
Modules: config, user, language, alert, media-library, browser, cache, ambient
API modules: store/api/datatable.js, store/api/form.js, store/api/media-library.js
Schema Contract ​
See Hydrates for common schema keys. Frontend receives schema via Inertia; FormBase flattens and combines with model before rendering.