@motor-cms/ui-admin 1.0.1-alpha.0

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 (103) hide show
  1. package/README.md +77 -0
  2. package/app/components/form/inputs/CategoryTreeInput.vue +154 -0
  3. package/app/components/form/inputs/CategoryTreePicker.vue +355 -0
  4. package/app/components/form/inputs/NestedDraggable.vue +217 -0
  5. package/app/components/form/inputs/QuicklinksInput.vue +186 -0
  6. package/app/lang/de/motor-admin/CLAUDE.md +21 -0
  7. package/app/lang/de/motor-admin/ai_system_prompts.json +12 -0
  8. package/app/lang/de/motor-admin/categories.json +12 -0
  9. package/app/lang/de/motor-admin/category_trees.json +14 -0
  10. package/app/lang/de/motor-admin/clients.json +26 -0
  11. package/app/lang/de/motor-admin/config_variables.json +14 -0
  12. package/app/lang/de/motor-admin/domains.json +19 -0
  13. package/app/lang/de/motor-admin/email_templates.json +38 -0
  14. package/app/lang/de/motor-admin/global.json +5 -0
  15. package/app/lang/de/motor-admin/languages.json +16 -0
  16. package/app/lang/de/motor-admin/permissions.json +14 -0
  17. package/app/lang/de/motor-admin/roles.json +15 -0
  18. package/app/lang/de/motor-admin/users.json +22 -0
  19. package/app/lang/en/motor-admin/CLAUDE.md +7 -0
  20. package/app/lang/en/motor-admin/ai_system_prompts.json +12 -0
  21. package/app/lang/en/motor-admin/categories.json +12 -0
  22. package/app/lang/en/motor-admin/category_trees.json +14 -0
  23. package/app/lang/en/motor-admin/clients.json +26 -0
  24. package/app/lang/en/motor-admin/config_variables.json +14 -0
  25. package/app/lang/en/motor-admin/domains.json +18 -0
  26. package/app/lang/en/motor-admin/email_templates.json +33 -0
  27. package/app/lang/en/motor-admin/global.json +5 -0
  28. package/app/lang/en/motor-admin/languages.json +16 -0
  29. package/app/lang/en/motor-admin/permissions.json +14 -0
  30. package/app/lang/en/motor-admin/roles.json +15 -0
  31. package/app/lang/en/motor-admin/users.json +22 -0
  32. package/app/pages/dashboard.vue +5 -0
  33. package/app/pages/index.vue +39 -0
  34. package/app/pages/login.vue +85 -0
  35. package/app/pages/motor-admin/ai-system-prompts/CLAUDE.md +7 -0
  36. package/app/pages/motor-admin/ai-system-prompts/[id]/edit.vue +48 -0
  37. package/app/pages/motor-admin/ai-system-prompts/create.vue +40 -0
  38. package/app/pages/motor-admin/ai-system-prompts/index.vue +68 -0
  39. package/app/pages/motor-admin/category-trees/CLAUDE.md +7 -0
  40. package/app/pages/motor-admin/category-trees/[id]/CLAUDE.md +7 -0
  41. package/app/pages/motor-admin/category-trees/[id]/categories/[categoryId]/edit.vue +73 -0
  42. package/app/pages/motor-admin/category-trees/[id]/categories/create.vue +64 -0
  43. package/app/pages/motor-admin/category-trees/[id]/edit.vue +45 -0
  44. package/app/pages/motor-admin/category-trees/[id]/index.vue +81 -0
  45. package/app/pages/motor-admin/category-trees/create.vue +37 -0
  46. package/app/pages/motor-admin/category-trees/index.vue +54 -0
  47. package/app/pages/motor-admin/clients/CLAUDE.md +11 -0
  48. package/app/pages/motor-admin/clients/[id]/CLAUDE.md +11 -0
  49. package/app/pages/motor-admin/clients/[id]/edit.vue +45 -0
  50. package/app/pages/motor-admin/clients/create.vue +37 -0
  51. package/app/pages/motor-admin/clients/index.vue +46 -0
  52. package/app/pages/motor-admin/config-variables/CLAUDE.md +11 -0
  53. package/app/pages/motor-admin/config-variables/[id]/edit.vue +44 -0
  54. package/app/pages/motor-admin/config-variables/create.vue +36 -0
  55. package/app/pages/motor-admin/config-variables/index.vue +66 -0
  56. package/app/pages/motor-admin/domains/CLAUDE.md +11 -0
  57. package/app/pages/motor-admin/domains/[id]/edit.vue +54 -0
  58. package/app/pages/motor-admin/domains/create.vue +46 -0
  59. package/app/pages/motor-admin/domains/index.vue +98 -0
  60. package/app/pages/motor-admin/email-templates/CLAUDE.md +12 -0
  61. package/app/pages/motor-admin/email-templates/[id]/CLAUDE.md +7 -0
  62. package/app/pages/motor-admin/email-templates/[id]/edit.vue +56 -0
  63. package/app/pages/motor-admin/email-templates/create.vue +48 -0
  64. package/app/pages/motor-admin/email-templates/index.vue +67 -0
  65. package/app/pages/motor-admin/index.vue +12 -0
  66. package/app/pages/motor-admin/languages/CLAUDE.md +7 -0
  67. package/app/pages/motor-admin/languages/[id]/edit.vue +44 -0
  68. package/app/pages/motor-admin/languages/create.vue +36 -0
  69. package/app/pages/motor-admin/languages/index.vue +44 -0
  70. package/app/pages/motor-admin/permission-groups/CLAUDE.md +14 -0
  71. package/app/pages/motor-admin/permission-groups/[id]/CLAUDE.md +11 -0
  72. package/app/pages/motor-admin/permission-groups/[id]/edit.vue +49 -0
  73. package/app/pages/motor-admin/permission-groups/create.vue +41 -0
  74. package/app/pages/motor-admin/permission-groups/index.vue +43 -0
  75. package/app/pages/motor-admin/roles/CLAUDE.md +7 -0
  76. package/app/pages/motor-admin/roles/[id]/edit.vue +47 -0
  77. package/app/pages/motor-admin/roles/create.vue +40 -0
  78. package/app/pages/motor-admin/roles/index.vue +45 -0
  79. package/app/pages/motor-admin/theme-preview/CLAUDE.md +7 -0
  80. package/app/pages/motor-admin/theme-preview/index.vue +4801 -0
  81. package/app/pages/motor-admin/theme-preview/themes/CLAUDE.md +11 -0
  82. package/app/pages/motor-admin/theme-preview/themes/asymmetric-brutalist.md +381 -0
  83. package/app/pages/motor-admin/theme-preview/themes/bold-modern.md +231 -0
  84. package/app/pages/motor-admin/theme-preview/themes/geometric-minimal.md +778 -0
  85. package/app/pages/motor-admin/theme-preview/themes/gradient-flow.md +1057 -0
  86. package/app/pages/motor-admin/theme-preview/themes/liquid-glass.md +823 -0
  87. package/app/pages/motor-admin/theme-preview/themes/neon-amber.md +1223 -0
  88. package/app/pages/motor-admin/theme-preview/themes/neon-terminal.md +779 -0
  89. package/app/pages/motor-admin/theme-preview/themes/neon-violet.md +1134 -0
  90. package/app/pages/motor-admin/theme-preview/themes/professional-clean.md +232 -0
  91. package/app/pages/motor-admin/theme-preview/themes/refined-brutalist.md +462 -0
  92. package/app/pages/motor-admin/theme-preview/themes/wild-card.md +263 -0
  93. package/app/pages/motor-admin/users/CLAUDE.md +17 -0
  94. package/app/pages/motor-admin/users/[id]/CLAUDE.md +11 -0
  95. package/app/pages/motor-admin/users/[id]/edit.vue +83 -0
  96. package/app/pages/motor-admin/users/create.vue +40 -0
  97. package/app/pages/motor-admin/users/index.vue +66 -0
  98. package/app/pages/profile.vue +363 -0
  99. package/app/pages/search.vue +91 -0
  100. package/app/types/generated/form-meta.ts +258 -0
  101. package/app/types/generated/grid-meta.ts +172 -0
  102. package/nuxt.config.ts +1 -0
  103. package/package.json +26 -0
@@ -0,0 +1,45 @@
1
+ <!-- app/pages/motor-admin/category-trees/[id]/edit.vue -->
2
+ <script setup lang="ts">
3
+ import { categoryTreeFormMeta } from '@motor-cms/ui-core/app/types/generated/form-meta'
4
+ import { categoryTreeEditFormConfig } from '@motor-cms/ui-core/app/types/config/category-tree'
5
+
6
+ definePageMeta({ layout: 'default', permission: 'category-trees.write' })
7
+
8
+ const route = useRoute()
9
+ const { t } = useI18n()
10
+ const { fields, schema, groups, state, loading, fetching, fetchError, formRef, onSubmit, onSaveAndContinue, onSaveAndNew, deleteRecord, deleting } = await useEntityForm({
11
+ apiEndpoint: '/api/v2/category-trees',
12
+ routePrefix: '/motor-admin/category-trees',
13
+ translationPrefix: 'motor-admin.category_trees',
14
+ formMeta: categoryTreeFormMeta,
15
+ formConfig: categoryTreeEditFormConfig,
16
+ mode: 'edit',
17
+ id: route.params.id as string
18
+ })
19
+ </script>
20
+
21
+ <template>
22
+ <FormPage
23
+ :title="t('motor-admin.category_trees.edit_title')"
24
+ back-route="/motor-admin/category-trees"
25
+ :loading="fetching"
26
+ :error="fetchError"
27
+ >
28
+ <FormBase
29
+ ref="formRef"
30
+ v-model:state="state"
31
+ :fields="fields"
32
+ :schema="schema"
33
+ :groups="groups"
34
+ :loading="loading"
35
+ :delete-record="deleteRecord"
36
+ :deleting="deleting"
37
+ cancel-route="/motor-admin/category-trees"
38
+ show-save-and-continue
39
+ show-save-and-new
40
+ @submit="onSubmit"
41
+ @save-and-continue="onSaveAndContinue"
42
+ @save-and-new="onSaveAndNew"
43
+ />
44
+ </FormPage>
45
+ </template>
@@ -0,0 +1,81 @@
1
+ <!-- app/pages/motor-admin/category-trees/[id]/index.vue -->
2
+ <script setup lang="ts">
3
+ import type { components } from '@motor-cms/ui-core/app/types/generated/api'
4
+ import type { RowActionDef } from '@motor-cms/ui-core/app/types/grid'
5
+ import { categoryMeta } from '@motor-cms/ui-core/app/types/generated/grid-meta'
6
+
7
+ definePageMeta({ permission: 'category-trees.read' })
8
+
9
+ type Category = components['schemas']['CategoryResource']
10
+ type CategoryTree = components['schemas']['CategoryTreeResource']
11
+
12
+ const route = useRoute()
13
+ const client = useSanctumClient()
14
+ const { t } = useI18n()
15
+
16
+ const treeId = route.params.id as string
17
+
18
+ const { data: treeRes } = useAsyncData(
19
+ `category-tree-${treeId}`,
20
+ () => client<{ data: CategoryTree }>(`/api/v2/category-trees/${treeId}`)
21
+ )
22
+ const treeName = computed(() => (treeRes.value?.data.name as string) ?? `#${treeId}`)
23
+
24
+ const columns = columnsFromMeta<Category>(categoryMeta, t, {
25
+ pick: ['name']
26
+ })
27
+
28
+ // Override name column to use indented-text renderer
29
+ const nameCol = columns.find(c => c.key === 'name')
30
+ if (nameCol) {
31
+ nameCol.renderer = 'indented-text'
32
+ }
33
+
34
+ columns.push(createdAtColumn(t))
35
+
36
+ const rowActions: RowActionDef<Category>[] = [
37
+ {
38
+ key: 'edit',
39
+ label: t('motor-core.grid.edit'),
40
+ icon: 'i-lucide-pencil',
41
+ to: row => `/motor-admin/category-trees/${treeId}/categories/${row.id}/edit`
42
+ },
43
+ {
44
+ key: 'delete',
45
+ label: t('motor-core.grid.delete'),
46
+ icon: 'i-lucide-trash-2',
47
+ color: 'error',
48
+ confirm: t('motor-core.grid.confirm_delete_row'),
49
+ handler: async (row) => {
50
+ await client(`/api/v2/category-trees/${treeId}/categories/${row.id}`, { method: 'DELETE' })
51
+ }
52
+ }
53
+ ]
54
+
55
+ const fetchCategories = useGridFetch<Category>(`/api/v2/category-trees/${treeId}/categories`)
56
+ </script>
57
+
58
+ <template>
59
+ <GridPage
60
+ :title="treeName ? t('motor-admin.category_trees.children_title', { name: treeName }) : t('motor-admin.categories.title')"
61
+ :subtitle="t('motor-admin.category_trees.children_subtitle')"
62
+ :add-route="`/motor-admin/category-trees/${treeId}/categories/create`"
63
+ :add-label="t('motor-admin.categories.add')"
64
+ back-route="/motor-admin/category-trees"
65
+ :back-label="t('motor-admin.category_trees.title')"
66
+ write-permission="categories.write"
67
+ >
68
+ <GridBase
69
+ id="categories-grid"
70
+ :fetch="fetchCategories"
71
+ :columns="columns"
72
+ :row-actions="rowActions"
73
+ :row-click-to="(row: any) => `/motor-admin/category-trees/${treeId}/categories/${row.id}/edit`"
74
+ :add-route="`/motor-admin/category-trees/${treeId}/categories/create`"
75
+ :add-label="t('motor-admin.categories.add')"
76
+ disable-default-actions
77
+ write-permission="categories.write"
78
+ delete-permission="categories.delete"
79
+ />
80
+ </GridPage>
81
+ </template>
@@ -0,0 +1,37 @@
1
+ <!-- app/pages/motor-admin/category-trees/create.vue -->
2
+ <script setup lang="ts">
3
+ import { categoryTreeFormMeta } from '@motor-cms/ui-core/app/types/generated/form-meta'
4
+ import { categoryTreeFormConfig } from '@motor-cms/ui-core/app/types/config/category-tree'
5
+
6
+ definePageMeta({ layout: 'default', permission: 'category-trees.write' })
7
+
8
+ const { t } = useI18n()
9
+ const { fields, schema, groups, state, loading, formRef, onSubmit, onSaveAndNew } = await useEntityForm({
10
+ apiEndpoint: '/api/v2/category-trees',
11
+ routePrefix: '/motor-admin/category-trees',
12
+ translationPrefix: 'motor-admin.category_trees',
13
+ formMeta: categoryTreeFormMeta,
14
+ formConfig: categoryTreeFormConfig,
15
+ mode: 'create'
16
+ })
17
+ </script>
18
+
19
+ <template>
20
+ <FormPage
21
+ :title="t('motor-admin.category_trees.create_title')"
22
+ back-route="/motor-admin/category-trees"
23
+ >
24
+ <FormBase
25
+ ref="formRef"
26
+ v-model:state="state"
27
+ :fields="fields"
28
+ :schema="schema"
29
+ :groups="groups"
30
+ :loading="loading"
31
+ cancel-route="/motor-admin/category-trees"
32
+ show-save-and-new
33
+ @submit="onSubmit"
34
+ @save-and-new="onSaveAndNew"
35
+ />
36
+ </FormPage>
37
+ </template>
@@ -0,0 +1,54 @@
1
+ <!-- app/pages/motor-admin/category-trees/index.vue -->
2
+ <script setup lang="ts">
3
+ import type { components } from '@motor-cms/ui-core/app/types/generated/api'
4
+ import type { RowActionDef } from '@motor-cms/ui-core/app/types/grid'
5
+ import { categoryTreeMeta } from '@motor-cms/ui-core/app/types/generated/grid-meta'
6
+
7
+ definePageMeta({ permission: 'category-trees.read' })
8
+
9
+ type CategoryTree = components['schemas']['CategoryTreeResource']
10
+
11
+ const { t } = useI18n()
12
+
13
+ const columns = columnsFromMeta<CategoryTree>(categoryTreeMeta, t, {
14
+ pick: ['name', 'scope']
15
+ })
16
+
17
+ columns.push(createdAtColumn(t))
18
+
19
+ const rowActions: RowActionDef<CategoryTree>[] = [
20
+ {
21
+ key: 'children',
22
+ label: t('motor-admin.category_trees.children'),
23
+ icon: 'i-lucide-list-tree',
24
+ to: row => `/motor-admin/category-trees/${row.id}`
25
+ },
26
+ { key: 'delete', label: '', enabled: false }
27
+ ]
28
+
29
+ const filters = [useScopeFilter()]
30
+
31
+ const fetchCategoryTrees = useGridFetch<CategoryTree>('/api/v2/category-trees')
32
+ </script>
33
+
34
+ <template>
35
+ <GridPage
36
+ :title="t('motor-admin.category_trees.title')"
37
+ :subtitle="t('motor-admin.category_trees.subtitle')"
38
+ add-route="/motor-admin/category-trees/create"
39
+ :add-label="t('motor-admin.category_trees.add')"
40
+ write-permission="category-trees.write"
41
+ >
42
+ <GridBase
43
+ id="category-trees-grid"
44
+ :fetch="fetchCategoryTrees"
45
+ :columns="columns"
46
+ :filters="filters"
47
+ :row-actions="rowActions"
48
+ base-path="/motor-admin/category-trees"
49
+ :row-click-to="(row: any) => `/motor-admin/category-trees/${row.id}`"
50
+ write-permission="category-trees.write"
51
+ delete-permission="category-trees.delete"
52
+ />
53
+ </GridPage>
54
+ </template>
@@ -0,0 +1,11 @@
1
+ <claude-mem-context>
2
+ # Recent Activity
3
+
4
+ <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
5
+
6
+ ### Feb 12, 2026
7
+
8
+ | ID | Time | T | Title | Read |
9
+ |----|------|---|-------|------|
10
+ | #24263 | 3:10 PM | 🟣 | Users Create Form with Cached Select Options | ~329 |
11
+ </claude-mem-context>
@@ -0,0 +1,11 @@
1
+ <claude-mem-context>
2
+ # Recent Activity
3
+
4
+ <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
5
+
6
+ ### Feb 12, 2026
7
+
8
+ | ID | Time | T | Title | Read |
9
+ |----|------|---|-------|------|
10
+ | #24261 | 3:09 PM | 🔵 | Email Templates Form Pattern with Slug Auto-Generation | ~414 |
11
+ </claude-mem-context>
@@ -0,0 +1,45 @@
1
+ <!-- app/pages/motor-admin/clients/[id]/edit.vue -->
2
+ <script setup lang="ts">
3
+ import { clientFormMeta } from '../../../../types/generated/form-meta'
4
+ import { clientFormConfig } from '@motor-cms/ui-core/app/types/config/client'
5
+
6
+ definePageMeta({ layout: 'default', permission: 'clients.write' })
7
+
8
+ const route = useRoute()
9
+ const { t } = useI18n()
10
+ const { fields, schema, groups, state, loading, fetching, fetchError, formRef, onSubmit, onSaveAndContinue, onSaveAndNew, deleteRecord, deleting } = await useEntityForm({
11
+ apiEndpoint: '/api/v2/clients',
12
+ routePrefix: '/motor-admin/clients',
13
+ translationPrefix: 'motor-admin.clients',
14
+ formMeta: clientFormMeta,
15
+ formConfig: clientFormConfig,
16
+ mode: 'edit',
17
+ id: route.params.id as string
18
+ })
19
+ </script>
20
+
21
+ <template>
22
+ <FormPage
23
+ :title="t('motor-admin.clients.edit_title')"
24
+ back-route="/motor-admin/clients"
25
+ :loading="fetching"
26
+ :error="fetchError"
27
+ >
28
+ <FormBase
29
+ ref="formRef"
30
+ v-model:state="state"
31
+ :fields="fields"
32
+ :schema="schema"
33
+ :groups="groups"
34
+ :loading="loading"
35
+ :delete-record="deleteRecord"
36
+ :deleting="deleting"
37
+ cancel-route="/motor-admin/clients"
38
+ show-save-and-continue
39
+ show-save-and-new
40
+ @submit="onSubmit"
41
+ @save-and-continue="onSaveAndContinue"
42
+ @save-and-new="onSaveAndNew"
43
+ />
44
+ </FormPage>
45
+ </template>
@@ -0,0 +1,37 @@
1
+ <!-- app/pages/motor-admin/clients/create.vue -->
2
+ <script setup lang="ts">
3
+ import { clientFormMeta } from '../../../types/generated/form-meta'
4
+ import { clientFormConfig } from '@motor-cms/ui-core/app/types/config/client'
5
+
6
+ definePageMeta({ layout: 'default', permission: 'clients.write' })
7
+
8
+ const { t } = useI18n()
9
+ const { fields, schema, groups, state, loading, formRef, onSubmit, onSaveAndNew } = await useEntityForm({
10
+ apiEndpoint: '/api/v2/clients',
11
+ routePrefix: '/motor-admin/clients',
12
+ translationPrefix: 'motor-admin.clients',
13
+ formMeta: clientFormMeta,
14
+ formConfig: clientFormConfig,
15
+ mode: 'create'
16
+ })
17
+ </script>
18
+
19
+ <template>
20
+ <FormPage
21
+ :title="t('motor-admin.clients.create_title')"
22
+ back-route="/motor-admin/clients"
23
+ >
24
+ <FormBase
25
+ ref="formRef"
26
+ v-model:state="state"
27
+ :fields="fields"
28
+ :schema="schema"
29
+ :groups="groups"
30
+ :loading="loading"
31
+ cancel-route="/motor-admin/clients"
32
+ show-save-and-new
33
+ @submit="onSubmit"
34
+ @save-and-new="onSaveAndNew"
35
+ />
36
+ </FormPage>
37
+ </template>
@@ -0,0 +1,46 @@
1
+ <!-- app/pages/motor-admin/clients/index.vue -->
2
+ <script setup lang="ts">
3
+ import type { components } from '@motor-cms/ui-core/app/types/generated/api'
4
+ import { clientMeta } from '../../../types/generated/grid-meta'
5
+
6
+ definePageMeta({ permission: 'clients.read' })
7
+
8
+ type Client = components['schemas']['ClientResource']
9
+
10
+ const { t } = useI18n()
11
+
12
+ const columns = columnsFromMeta<Client>(clientMeta, t, {
13
+ pick: ['name', 'slug', 'city', 'country_iso_3166_1', 'website', 'is_active', 'contact_email'],
14
+ overrides: {
15
+ slug: { defaultHidden: true },
16
+ country_iso_3166_1: { renderer: 'badge' }
17
+ }
18
+ })
19
+
20
+ columns.push(createdAtColumn(t))
21
+
22
+ const filters = [useIsActiveFilter()]
23
+
24
+ const fetchClients = useGridFetch<Client>('/api/v2/clients')
25
+ </script>
26
+
27
+ <template>
28
+ <GridPage
29
+ :title="t('motor-admin.clients.title')"
30
+ :subtitle="t('motor-admin.clients.subtitle')"
31
+ add-route="/motor-admin/clients/create"
32
+ :add-label="t('motor-admin.clients.add')"
33
+ write-permission="clients.write"
34
+ >
35
+ <GridBase
36
+ id="clients-grid"
37
+ :fetch="fetchClients"
38
+ :columns="columns"
39
+ :filters="filters"
40
+ base-path="/motor-admin/clients"
41
+ :row-click-to="(row: any) => `/motor-admin/clients/${row.id}/edit`"
42
+ write-permission="clients.write"
43
+ delete-permission="clients.delete"
44
+ />
45
+ </GridPage>
46
+ </template>
@@ -0,0 +1,11 @@
1
+ <claude-mem-context>
2
+ # Recent Activity
3
+
4
+ <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
5
+
6
+ ### Feb 12, 2026
7
+
8
+ | ID | Time | T | Title | Read |
9
+ |----|------|---|-------|------|
10
+ | #24251 | 1:14 PM | 🔵 | Comprehensive Application Refactoring Staged for Commit | ~515 |
11
+ </claude-mem-context>
@@ -0,0 +1,44 @@
1
+ <script setup lang="ts">
2
+ import { configVariableFormMeta } from '../../../../types/generated/form-meta'
3
+ import { configVariableFormConfig } from '@motor-cms/ui-core/app/types/config/config-variable'
4
+
5
+ definePageMeta({ layout: 'default', permission: 'config-variables.write' })
6
+
7
+ const route = useRoute()
8
+ const { t } = useI18n()
9
+ const { fields, schema, groups, state, loading, fetching, fetchError, formRef, onSubmit, onSaveAndContinue, onSaveAndNew, deleteRecord, deleting } = await useEntityForm({
10
+ apiEndpoint: '/api/v2/config-variables',
11
+ routePrefix: '/motor-admin/config-variables',
12
+ translationPrefix: 'motor-admin.config_variables',
13
+ formMeta: configVariableFormMeta,
14
+ formConfig: configVariableFormConfig,
15
+ mode: 'edit',
16
+ id: route.params.id as string
17
+ })
18
+ </script>
19
+
20
+ <template>
21
+ <FormPage
22
+ :title="t('motor-admin.config_variables.edit_title')"
23
+ back-route="/motor-admin/config-variables"
24
+ :loading="fetching"
25
+ :error="fetchError"
26
+ >
27
+ <FormBase
28
+ ref="formRef"
29
+ v-model:state="state"
30
+ :fields="fields"
31
+ :schema="schema"
32
+ :groups="groups"
33
+ :loading="loading"
34
+ :delete-record="deleteRecord"
35
+ :deleting="deleting"
36
+ cancel-route="/motor-admin/config-variables"
37
+ show-save-and-continue
38
+ show-save-and-new
39
+ @submit="onSubmit"
40
+ @save-and-continue="onSaveAndContinue"
41
+ @save-and-new="onSaveAndNew"
42
+ />
43
+ </FormPage>
44
+ </template>
@@ -0,0 +1,36 @@
1
+ <script setup lang="ts">
2
+ import { configVariableFormMeta } from '../../../types/generated/form-meta'
3
+ import { configVariableFormConfig } from '@motor-cms/ui-core/app/types/config/config-variable'
4
+
5
+ definePageMeta({ layout: 'default', permission: 'config-variables.write' })
6
+
7
+ const { t } = useI18n()
8
+ const { fields, schema, groups, state, loading, formRef, onSubmit, onSaveAndNew } = await useEntityForm({
9
+ apiEndpoint: '/api/v2/config-variables',
10
+ routePrefix: '/motor-admin/config-variables',
11
+ translationPrefix: 'motor-admin.config_variables',
12
+ formMeta: configVariableFormMeta,
13
+ formConfig: configVariableFormConfig,
14
+ mode: 'create'
15
+ })
16
+ </script>
17
+
18
+ <template>
19
+ <FormPage
20
+ :title="t('motor-admin.config_variables.create_title')"
21
+ back-route="/motor-admin/config-variables"
22
+ >
23
+ <FormBase
24
+ ref="formRef"
25
+ v-model:state="state"
26
+ :fields="fields"
27
+ :schema="schema"
28
+ :groups="groups"
29
+ :loading="loading"
30
+ cancel-route="/motor-admin/config-variables"
31
+ show-save-and-new
32
+ @submit="onSubmit"
33
+ @save-and-new="onSaveAndNew"
34
+ />
35
+ </FormPage>
36
+ </template>
@@ -0,0 +1,66 @@
1
+ <!-- app/pages/motor-admin/config-variables/index.vue -->
2
+ <script setup lang="ts">
3
+ import type { components } from '@motor-cms/ui-core/app/types/generated/api'
4
+ import type { BulkActionDef } from '@motor-cms/ui-core/app/types/grid'
5
+ import { configVariableMeta } from '../../../types/generated/grid-meta'
6
+
7
+ definePageMeta({ permission: 'config-variables.read' })
8
+
9
+ type ConfigVariable = components['schemas']['ConfigVariableResource']
10
+
11
+ const client = useSanctumClient()
12
+ const { t } = useI18n()
13
+
14
+ const columns = columnsFromMeta<ConfigVariable>(configVariableMeta, t, {
15
+ pick: ['package', 'group', 'name', 'value', 'is_invisible'],
16
+ overrides: {
17
+ package: { renderer: 'badge' },
18
+ group: { renderer: 'badge' }
19
+ }
20
+ })
21
+
22
+ columns.push(createdAtColumn(t, { defaultHidden: true }))
23
+
24
+ const filters = [usePackageFilter(), useGroupFilter(), useIsInvisibleFilter()]
25
+
26
+ const bulkActions: BulkActionDef[] = [
27
+ {
28
+ key: 'delete',
29
+ label: t('motor-core.grid.delete_selected'),
30
+ icon: 'i-lucide-trash-2',
31
+ color: 'error',
32
+ permission: 'config-variables.delete',
33
+ confirm: count => t('motor-core.grid.confirm_delete', { count }),
34
+ handler: async (ids) => {
35
+ await client('/api/v2/config-variables/bulk-delete', {
36
+ method: 'POST',
37
+ body: { ids }
38
+ })
39
+ }
40
+ }
41
+ ]
42
+
43
+ const fetchConfigVariables = useGridFetch<ConfigVariable>('/api/v2/config-variables')
44
+ </script>
45
+
46
+ <template>
47
+ <GridPage
48
+ :title="t('motor-admin.config_variables.title')"
49
+ :subtitle="t('motor-admin.config_variables.subtitle')"
50
+ add-route="/motor-admin/config-variables/create"
51
+ :add-label="t('motor-admin.config_variables.add')"
52
+ write-permission="config-variables.write"
53
+ >
54
+ <GridBase
55
+ id="config-variables-grid"
56
+ :fetch="fetchConfigVariables"
57
+ :columns="columns"
58
+ :filters="filters"
59
+ :bulk-actions="bulkActions"
60
+ base-path="/motor-admin/config-variables"
61
+ :row-click-to="(row: any) => `/motor-admin/config-variables/${row.id}/edit`"
62
+ write-permission="config-variables.write"
63
+ delete-permission="config-variables.delete"
64
+ />
65
+ </GridPage>
66
+ </template>
@@ -0,0 +1,11 @@
1
+ <claude-mem-context>
2
+ # Recent Activity
3
+
4
+ <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
5
+
6
+ ### Feb 12, 2026
7
+
8
+ | ID | Time | T | Title | Read |
9
+ |----|------|---|-------|------|
10
+ | #24269 | 3:11 PM | 🟣 | Permissions Multi-Select Field Added to Permission-Groups Form | ~435 |
11
+ </claude-mem-context>
@@ -0,0 +1,54 @@
1
+ <!-- app/pages/motor-admin/domains/[id]/edit.vue -->
2
+ <script setup lang="ts">
3
+ import { domainFormMeta } from '../../../../types/generated/form-meta'
4
+ import { domainFormConfig, domainSelectOptionConfigs, domainProtocolOptions } from '@motor-cms/ui-core/app/types/config/domain'
5
+
6
+ definePageMeta({ layout: 'default', permission: 'domains.write' })
7
+
8
+ const route = useRoute()
9
+ const { t } = useI18n()
10
+
11
+ const { fields, schema, groups, state, loading, fetching, fetchError, formRef, selectOptions, selectOptionsLoading, onSubmit, onSaveAndContinue, onSaveAndNew, deleteRecord, deleting } = await useEntityForm({
12
+ apiEndpoint: '/api/v2/domains',
13
+ routePrefix: '/motor-admin/domains',
14
+ translationPrefix: 'motor-admin.domains',
15
+ formMeta: domainFormMeta,
16
+ formConfig: domainFormConfig,
17
+ mode: 'edit',
18
+ id: route.params.id as string,
19
+ selectOptionConfigs: domainSelectOptionConfigs
20
+ })
21
+
22
+ const mergedSelectOptions = computed(() => ({
23
+ ...selectOptions?.value,
24
+ protocol: domainProtocolOptions
25
+ }))
26
+ </script>
27
+
28
+ <template>
29
+ <FormPage
30
+ :title="t('motor-admin.domains.edit_title')"
31
+ back-route="/motor-admin/domains"
32
+ :loading="fetching"
33
+ :error="fetchError"
34
+ >
35
+ <FormBase
36
+ ref="formRef"
37
+ v-model:state="state"
38
+ :fields="fields"
39
+ :schema="schema"
40
+ :groups="groups"
41
+ :select-options="mergedSelectOptions"
42
+ :select-options-loading="selectOptionsLoading"
43
+ :loading="loading"
44
+ :delete-record="deleteRecord"
45
+ :deleting="deleting"
46
+ cancel-route="/motor-admin/domains"
47
+ show-save-and-continue
48
+ show-save-and-new
49
+ @submit="onSubmit"
50
+ @save-and-continue="onSaveAndContinue"
51
+ @save-and-new="onSaveAndNew"
52
+ />
53
+ </FormPage>
54
+ </template>
@@ -0,0 +1,46 @@
1
+ <!-- app/pages/motor-admin/domains/create.vue -->
2
+ <script setup lang="ts">
3
+ import { domainFormMeta } from '../../../types/generated/form-meta'
4
+ import { domainFormConfig, domainSelectOptionConfigs, domainProtocolOptions } from '@motor-cms/ui-core/app/types/config/domain'
5
+
6
+ definePageMeta({ layout: 'default', permission: 'domains.write' })
7
+
8
+ const { t } = useI18n()
9
+
10
+ const { fields, schema, groups, state, loading, selectOptions, selectOptionsLoading, formRef, onSubmit, onSaveAndNew } = await useEntityForm({
11
+ apiEndpoint: '/api/v2/domains',
12
+ routePrefix: '/motor-admin/domains',
13
+ translationPrefix: 'motor-admin.domains',
14
+ formMeta: domainFormMeta,
15
+ formConfig: domainFormConfig,
16
+ mode: 'create',
17
+ selectOptionConfigs: domainSelectOptionConfigs
18
+ })
19
+
20
+ const mergedSelectOptions = computed(() => ({
21
+ ...selectOptions?.value,
22
+ protocol: domainProtocolOptions
23
+ }))
24
+ </script>
25
+
26
+ <template>
27
+ <FormPage
28
+ :title="t('motor-admin.domains.create_title')"
29
+ back-route="/motor-admin/domains"
30
+ >
31
+ <FormBase
32
+ ref="formRef"
33
+ v-model:state="state"
34
+ :fields="fields"
35
+ :schema="schema"
36
+ :groups="groups"
37
+ :select-options="mergedSelectOptions"
38
+ :select-options-loading="selectOptionsLoading"
39
+ :loading="loading"
40
+ cancel-route="/motor-admin/domains"
41
+ show-save-and-new
42
+ @submit="onSubmit"
43
+ @save-and-new="onSaveAndNew"
44
+ />
45
+ </FormPage>
46
+ </template>