@sfxcode/nuxt-ui-mongocamp 1.1.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 (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +308 -0
  3. package/dist/module.d.mts +8 -0
  4. package/dist/module.json +12 -0
  5. package/dist/module.mjs +35 -0
  6. package/dist/runtime/components/MongocampAccount.d.vue.ts +3 -0
  7. package/dist/runtime/components/MongocampAccount.vue +197 -0
  8. package/dist/runtime/components/MongocampAccount.vue.d.ts +3 -0
  9. package/dist/runtime/components/MongocampCollectionData.d.vue.ts +6 -0
  10. package/dist/runtime/components/MongocampCollectionData.vue +511 -0
  11. package/dist/runtime/components/MongocampCollectionData.vue.d.ts +6 -0
  12. package/dist/runtime/components/MongocampCollectionInfos.d.vue.ts +9 -0
  13. package/dist/runtime/components/MongocampCollectionInfos.vue +393 -0
  14. package/dist/runtime/components/MongocampCollectionInfos.vue.d.ts +9 -0
  15. package/dist/runtime/components/MongocampCollections.d.vue.ts +7 -0
  16. package/dist/runtime/components/MongocampCollections.vue +231 -0
  17. package/dist/runtime/components/MongocampCollections.vue.d.ts +7 -0
  18. package/dist/runtime/components/MongocampDatabases.d.vue.ts +3 -0
  19. package/dist/runtime/components/MongocampDatabases.vue +112 -0
  20. package/dist/runtime/components/MongocampDatabases.vue.d.ts +3 -0
  21. package/dist/runtime/components/MongocampJobs.d.vue.ts +3 -0
  22. package/dist/runtime/components/MongocampJobs.vue +354 -0
  23. package/dist/runtime/components/MongocampJobs.vue.d.ts +3 -0
  24. package/dist/runtime/components/MongocampLogin.d.vue.ts +3 -0
  25. package/dist/runtime/components/MongocampLogin.vue +63 -0
  26. package/dist/runtime/components/MongocampLogin.vue.d.ts +3 -0
  27. package/dist/runtime/components/MongocampRoleGrants.d.vue.ts +6 -0
  28. package/dist/runtime/components/MongocampRoleGrants.vue +276 -0
  29. package/dist/runtime/components/MongocampRoleGrants.vue.d.ts +6 -0
  30. package/dist/runtime/components/MongocampRoles.d.vue.ts +6 -0
  31. package/dist/runtime/components/MongocampRoles.vue +272 -0
  32. package/dist/runtime/components/MongocampRoles.vue.d.ts +6 -0
  33. package/dist/runtime/components/MongocampUsers.d.vue.ts +3 -0
  34. package/dist/runtime/components/MongocampUsers.vue +320 -0
  35. package/dist/runtime/components/MongocampUsers.vue.d.ts +3 -0
  36. package/dist/runtime/components/MongocampVersion.d.vue.ts +3 -0
  37. package/dist/runtime/components/MongocampVersion.vue +25 -0
  38. package/dist/runtime/components/MongocampVersion.vue.d.ts +3 -0
  39. package/dist/runtime/composables/useMongocampAccount.d.ts +7 -0
  40. package/dist/runtime/composables/useMongocampAccount.js +28 -0
  41. package/dist/runtime/composables/useMongocampAdmin.d.ts +14 -0
  42. package/dist/runtime/composables/useMongocampAdmin.js +48 -0
  43. package/dist/runtime/composables/useMongocampBucket.d.ts +15 -0
  44. package/dist/runtime/composables/useMongocampBucket.js +109 -0
  45. package/dist/runtime/composables/useMongocampCollection.d.ts +17 -0
  46. package/dist/runtime/composables/useMongocampCollection.js +12 -0
  47. package/dist/runtime/composables/useMongocampDocument.d.ts +13 -0
  48. package/dist/runtime/composables/useMongocampDocument.js +18 -0
  49. package/dist/runtime/composables/useMongocampDynamicForm.d.ts +14 -0
  50. package/dist/runtime/composables/useMongocampDynamicForm.js +231 -0
  51. package/dist/runtime/composables/useMongocampIndex.d.ts +9 -0
  52. package/dist/runtime/composables/useMongocampIndex.js +23 -0
  53. package/dist/runtime/composables/useMongocampJobs.d.ts +9 -0
  54. package/dist/runtime/composables/useMongocampJobs.js +25 -0
  55. package/dist/runtime/composables/useMongocampQuery.d.ts +99 -0
  56. package/dist/runtime/composables/useMongocampQuery.js +108 -0
  57. package/dist/runtime/composables/useMongocampQueryBuilder.d.ts +30 -0
  58. package/dist/runtime/composables/useMongocampQueryBuilder.js +112 -0
  59. package/dist/runtime/composables/useMongocampSchema.d.ts +14 -0
  60. package/dist/runtime/composables/useMongocampSchema.js +142 -0
  61. package/dist/runtime/composables/useMongocampSystem.d.ts +12 -0
  62. package/dist/runtime/composables/useMongocampSystem.js +21 -0
  63. package/dist/runtime/plugin.d.ts +6 -0
  64. package/dist/runtime/plugin.js +23 -0
  65. package/dist/runtime/server/tsconfig.json +3 -0
  66. package/dist/types.d.mts +3 -0
  67. package/package.json +99 -0
@@ -0,0 +1,112 @@
1
+ <script setup>
2
+ import { h, ref, resolveComponent } from "vue";
3
+ import { useMongocampSystem } from "#imports";
4
+ const { getDatabaseInfos, listCollectionsByDatabase } = useMongocampSystem();
5
+ const databases = ref([]);
6
+ const loading = ref(false);
7
+ const sorting = ref([]);
8
+ const errorMessage = ref("");
9
+ async function fetchDatabases() {
10
+ loading.value = true;
11
+ errorMessage.value = "";
12
+ try {
13
+ const infos = await getDatabaseInfos();
14
+ const rows = await Promise.all(
15
+ infos.map(async (info) => {
16
+ const collections = await listCollectionsByDatabase(info.name);
17
+ return {
18
+ name: info.name,
19
+ sizeKb: Math.round(info.sizeOnDisk / 1024),
20
+ empty: info.empty,
21
+ collectionCount: collections.length
22
+ };
23
+ })
24
+ );
25
+ databases.value = rows;
26
+ } catch (e) {
27
+ errorMessage.value = e instanceof Error ? e.message : "Failed to load databases";
28
+ } finally {
29
+ loading.value = false;
30
+ }
31
+ }
32
+ const UBadge = resolveComponent("UBadge");
33
+ const UButton = resolveComponent("UButton");
34
+ function sortHeader(column, label) {
35
+ const isSorted = column.getIsSorted();
36
+ return h(UButton, {
37
+ color: "neutral",
38
+ variant: "ghost",
39
+ label,
40
+ icon: isSorted === "asc" ? "i-lucide-arrow-up-narrow-wide" : isSorted === "desc" ? "i-lucide-arrow-down-wide-narrow" : "i-lucide-arrow-up-down",
41
+ class: "-mx-2.5",
42
+ onClick: () => column.toggleSorting(isSorted === "asc")
43
+ });
44
+ }
45
+ const columns = [
46
+ {
47
+ accessorKey: "name",
48
+ header: ({ column }) => sortHeader(column, "Database")
49
+ },
50
+ {
51
+ accessorKey: "sizeKb",
52
+ header: ({ column }) => sortHeader(column, "Size (KB)")
53
+ },
54
+ {
55
+ accessorKey: "collectionCount",
56
+ header: "Collections",
57
+ cell: ({ row }) => h(UBadge, { label: String(row.original.collectionCount), color: "primary", variant: "subtle" })
58
+ },
59
+ {
60
+ accessorKey: "empty",
61
+ header: "Empty",
62
+ cell: ({ row }) => row.original.empty ? h(UBadge, { label: "Empty", color: "neutral", variant: "subtle" }) : h("span", { class: "text-dimmed" }, "\u2014")
63
+ }
64
+ ];
65
+ fetchDatabases();
66
+ </script>
67
+
68
+ <template>
69
+ <div class="flex flex-col gap-4">
70
+ <div class="flex items-center justify-between gap-4">
71
+ <h2 class="text-xl font-semibold">
72
+ Databases
73
+ </h2>
74
+ <UTooltip text="Refresh">
75
+ <UButton
76
+ icon="i-lucide-refresh-cw"
77
+ color="neutral"
78
+ variant="ghost"
79
+ :loading="loading"
80
+ aria-label="Refresh"
81
+ @click="fetchDatabases"
82
+ />
83
+ </UTooltip>
84
+ </div>
85
+
86
+ <UAlert
87
+ v-if="errorMessage"
88
+ color="error"
89
+ variant="subtle"
90
+ icon="i-lucide-circle-alert"
91
+ title="Failed to load databases"
92
+ :description="errorMessage"
93
+ >
94
+ <template #actions>
95
+ <UButton
96
+ label="Retry"
97
+ color="error"
98
+ variant="subtle"
99
+ icon="i-lucide-refresh-cw"
100
+ @click="fetchDatabases"
101
+ />
102
+ </template>
103
+ </UAlert>
104
+
105
+ <UTable
106
+ v-model:sorting="sorting"
107
+ :data="databases"
108
+ :columns="columns"
109
+ :loading="loading"
110
+ />
111
+ </div>
112
+ </template>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,354 @@
1
+ <script setup>
2
+ import { h, reactive, ref, resolveComponent } from "vue";
3
+ import { useMongocampJobs, useToast } from "#imports";
4
+ const { listJobs, listPossibleJobs, registerJob, updateJob, executeJob, deleteJob } = useMongocampJobs();
5
+ const toast = useToast();
6
+ const jobs = ref([]);
7
+ const loading = ref(false);
8
+ const sorting = ref([]);
9
+ const isAddModalOpen = ref(false);
10
+ const isEditModalOpen = ref(false);
11
+ const isDeleteModalOpen = ref(false);
12
+ const errorMessage = ref("");
13
+ const executingJobs = ref(/* @__PURE__ */ new Set());
14
+ function jobKey(group, name) {
15
+ return `${group}/${name}`;
16
+ }
17
+ async function fetchJobs() {
18
+ loading.value = true;
19
+ try {
20
+ jobs.value = await listJobs();
21
+ } finally {
22
+ loading.value = false;
23
+ }
24
+ }
25
+ const emptyJobConfig = () => ({ name: "", group: "", className: "", description: "", cronExpression: "", priority: 5 });
26
+ const newJob = ref(emptyJobConfig());
27
+ const editJobOriginal = ref({ group: "", name: "" });
28
+ const editJobClassName = ref("");
29
+ const editJob = ref({ name: "", group: "", description: "", cronExpression: "", priority: 5 });
30
+ function extractSelectValue(raw) {
31
+ if (typeof raw === "object" && raw !== null) {
32
+ const obj = raw;
33
+ return obj.value ?? obj.label ?? "";
34
+ }
35
+ return String(raw ?? "");
36
+ }
37
+ const addJobSchema = reactive([
38
+ {
39
+ $formkit: "nuxtUIInput",
40
+ name: "name",
41
+ label: "Name",
42
+ validation: "required"
43
+ },
44
+ {
45
+ $formkit: "nuxtUIInput",
46
+ name: "group",
47
+ label: "Group",
48
+ validation: "required"
49
+ },
50
+ {
51
+ $formkit: "nuxtUISelectMenu",
52
+ name: "className",
53
+ label: "Job Class",
54
+ options: [],
55
+ validation: "required"
56
+ },
57
+ {
58
+ $formkit: "nuxtUIInput",
59
+ name: "description",
60
+ label: "Description"
61
+ },
62
+ {
63
+ $formkit: "nuxtUIInput",
64
+ name: "cronExpression",
65
+ label: "Cron Expression",
66
+ help: "Quartz cron syntax, e.g. 0 0 * * * ?",
67
+ validation: "required"
68
+ },
69
+ {
70
+ $formkit: "nuxtUIInputNumber",
71
+ name: "priority",
72
+ label: "Priority"
73
+ }
74
+ ]);
75
+ const editJobSchema = reactive([
76
+ {
77
+ $formkit: "nuxtUIInput",
78
+ name: "name",
79
+ label: "Name",
80
+ validation: "required"
81
+ },
82
+ {
83
+ $formkit: "nuxtUIInput",
84
+ name: "group",
85
+ label: "Group",
86
+ validation: "required"
87
+ },
88
+ {
89
+ $formkit: "nuxtUIInput",
90
+ name: "description",
91
+ label: "Description"
92
+ },
93
+ {
94
+ $formkit: "nuxtUIInput",
95
+ name: "cronExpression",
96
+ label: "Cron Expression",
97
+ help: "Quartz cron syntax, e.g. 0 0 * * * ?",
98
+ validation: "required"
99
+ },
100
+ {
101
+ $formkit: "nuxtUIInputNumber",
102
+ name: "priority",
103
+ label: "Priority"
104
+ }
105
+ ]);
106
+ async function openAdd() {
107
+ errorMessage.value = "";
108
+ addJobSchema[2].options = await listPossibleJobs();
109
+ newJob.value = emptyJobConfig();
110
+ isAddModalOpen.value = true;
111
+ }
112
+ async function handleAddJob() {
113
+ errorMessage.value = "";
114
+ try {
115
+ const className = extractSelectValue(newJob.value.className);
116
+ await registerJob({ ...newJob.value, className });
117
+ isAddModalOpen.value = false;
118
+ await fetchJobs();
119
+ } catch (e) {
120
+ errorMessage.value = e instanceof Error ? e.message : "Failed to register job";
121
+ }
122
+ }
123
+ function openEdit(job) {
124
+ errorMessage.value = "";
125
+ editJobOriginal.value = { group: job.group, name: job.name };
126
+ editJobClassName.value = job.jobClassName;
127
+ editJob.value = {
128
+ name: job.name,
129
+ group: job.group,
130
+ description: job.description,
131
+ cronExpression: job.cronExpression,
132
+ priority: job.priority
133
+ };
134
+ isEditModalOpen.value = true;
135
+ }
136
+ async function handleEditJob() {
137
+ errorMessage.value = "";
138
+ try {
139
+ const jobConfig = { ...editJob.value, className: editJobClassName.value };
140
+ await updateJob(editJobOriginal.value.group, editJobOriginal.value.name, jobConfig);
141
+ isEditModalOpen.value = false;
142
+ await fetchJobs();
143
+ } catch (e) {
144
+ errorMessage.value = e instanceof Error ? e.message : "Failed to update job";
145
+ }
146
+ }
147
+ const jobToDelete = ref({ group: "", name: "" });
148
+ function confirmDelete(group, name) {
149
+ jobToDelete.value = { group, name };
150
+ isDeleteModalOpen.value = true;
151
+ }
152
+ async function handleDeleteJob() {
153
+ await deleteJob(jobToDelete.value.group, jobToDelete.value.name);
154
+ isDeleteModalOpen.value = false;
155
+ await fetchJobs();
156
+ }
157
+ async function handleExecuteJob(group, name) {
158
+ const key = jobKey(group, name);
159
+ executingJobs.value.add(key);
160
+ try {
161
+ await executeJob(group, name);
162
+ toast.add({ title: "Job executed", description: `"${name}" was triggered.`, color: "success" });
163
+ } catch {
164
+ toast.add({ title: "Execution failed", description: `Could not execute "${name}".`, color: "error" });
165
+ } finally {
166
+ executingJobs.value.delete(key);
167
+ }
168
+ }
169
+ function formatFireTime(date) {
170
+ if (!date) return "\u2014";
171
+ return new Date(date).toLocaleString();
172
+ }
173
+ const UButton = resolveComponent("UButton");
174
+ const UTooltip = resolveComponent("UTooltip");
175
+ function withTooltip(text, node) {
176
+ return h(UTooltip, { text }, { default: () => node });
177
+ }
178
+ function sortHeader(column, label) {
179
+ const isSorted = column.getIsSorted();
180
+ return h(UButton, {
181
+ color: "neutral",
182
+ variant: "ghost",
183
+ label,
184
+ icon: isSorted === "asc" ? "i-lucide-arrow-up-narrow-wide" : isSorted === "desc" ? "i-lucide-arrow-down-wide-narrow" : "i-lucide-arrow-up-down",
185
+ class: "-mx-2.5",
186
+ onClick: () => column.toggleSorting(isSorted === "asc")
187
+ });
188
+ }
189
+ const columns = [
190
+ {
191
+ accessorKey: "name",
192
+ header: ({ column }) => sortHeader(column, "Name")
193
+ },
194
+ {
195
+ accessorKey: "group",
196
+ header: ({ column }) => sortHeader(column, "Group")
197
+ },
198
+ {
199
+ accessorKey: "cronExpression",
200
+ header: "Cron Expression",
201
+ cell: ({ row }) => h("span", { class: "font-mono text-xs" }, row.original.cronExpression)
202
+ },
203
+ {
204
+ accessorKey: "nextScheduledFireTime",
205
+ header: "Next Fire Time",
206
+ cell: ({ row }) => h("span", formatFireTime(row.original.nextScheduledFireTime))
207
+ },
208
+ {
209
+ accessorKey: "priority",
210
+ header: ({ column }) => sortHeader(column, "Priority")
211
+ },
212
+ {
213
+ id: "actions",
214
+ header: "",
215
+ cell: ({ row }) => {
216
+ const key = jobKey(row.original.group, row.original.name);
217
+ return h("div", { class: "flex gap-1 justify-end" }, [
218
+ withTooltip("Execute now", h(UButton, {
219
+ "icon": "i-lucide-play",
220
+ "color": "neutral",
221
+ "variant": "ghost",
222
+ "size": "sm",
223
+ "aria-label": "Execute now",
224
+ "loading": executingJobs.value.has(key),
225
+ "onClick": () => handleExecuteJob(row.original.group, row.original.name)
226
+ })),
227
+ withTooltip("Edit job", h(UButton, {
228
+ "icon": "i-lucide-pencil",
229
+ "color": "neutral",
230
+ "variant": "ghost",
231
+ "size": "sm",
232
+ "aria-label": "Edit job",
233
+ "onClick": () => openEdit(row.original)
234
+ })),
235
+ withTooltip("Delete job", h(UButton, {
236
+ "icon": "i-lucide-trash-2",
237
+ "color": "error",
238
+ "variant": "ghost",
239
+ "size": "sm",
240
+ "aria-label": "Delete job",
241
+ "onClick": () => confirmDelete(row.original.group, row.original.name)
242
+ }))
243
+ ]);
244
+ }
245
+ }
246
+ ];
247
+ fetchJobs();
248
+ </script>
249
+
250
+ <template>
251
+ <div class="flex flex-col gap-4">
252
+ <div class="flex items-center justify-between gap-4">
253
+ <h2 class="text-xl font-semibold">
254
+ Jobs
255
+ </h2>
256
+ <div class="flex items-center gap-2">
257
+ <UTooltip text="Refresh">
258
+ <UButton
259
+ icon="i-lucide-refresh-cw"
260
+ color="neutral"
261
+ variant="ghost"
262
+ :loading="loading"
263
+ aria-label="Refresh"
264
+ @click="fetchJobs"
265
+ />
266
+ </UTooltip>
267
+ <UButton
268
+ icon="i-lucide-plus"
269
+ label="Add Job"
270
+ @click="openAdd"
271
+ />
272
+ </div>
273
+ </div>
274
+
275
+ <UTable
276
+ v-model:sorting="sorting"
277
+ :data="jobs"
278
+ :columns="columns"
279
+ :loading="loading"
280
+ />
281
+
282
+ <!-- Add Job Modal -->
283
+ <UModal
284
+ v-model:open="isAddModalOpen"
285
+ title="Add Job"
286
+ >
287
+ <template #body>
288
+ <FUDataEdit
289
+ :data="newJob"
290
+ :schema="addJobSchema"
291
+ submit-label="Add Job"
292
+ submit-icon="i-lucide-plus"
293
+ @data-saved="handleAddJob"
294
+ />
295
+ <p
296
+ v-if="errorMessage"
297
+ class="mt-2 text-sm text-error-500"
298
+ >
299
+ {{ errorMessage }}
300
+ </p>
301
+ </template>
302
+ </UModal>
303
+
304
+ <!-- Edit Job Modal -->
305
+ <UModal
306
+ v-model:open="isEditModalOpen"
307
+ :title="`Edit Job: ${editJobOriginal.name}`"
308
+ >
309
+ <template #body>
310
+ <FUDataEdit
311
+ :data="editJob"
312
+ :schema="editJobSchema"
313
+ submit-label="Save Changes"
314
+ submit-icon="i-lucide-save"
315
+ @data-saved="handleEditJob"
316
+ />
317
+ <p
318
+ v-if="errorMessage"
319
+ class="mt-2 text-sm text-error-500"
320
+ >
321
+ {{ errorMessage }}
322
+ </p>
323
+ </template>
324
+ </UModal>
325
+
326
+ <!-- Delete Confirmation Modal -->
327
+ <UModal
328
+ v-model:open="isDeleteModalOpen"
329
+ title="Delete Job"
330
+ :ui="{ footer: 'justify-end' }"
331
+ >
332
+ <template #body>
333
+ <p>
334
+ Are you sure you want to delete job <strong>{{ jobToDelete.name }}</strong>?
335
+ This action cannot be undone.
336
+ </p>
337
+ </template>
338
+ <template #footer>
339
+ <UButton
340
+ label="Cancel"
341
+ color="neutral"
342
+ variant="ghost"
343
+ @click="isDeleteModalOpen = false"
344
+ />
345
+ <UButton
346
+ label="Delete"
347
+ color="error"
348
+ icon="i-lucide-trash-2"
349
+ @click="handleDeleteJob"
350
+ />
351
+ </template>
352
+ </UModal>
353
+ </div>
354
+ </template>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,63 @@
1
+ <script setup>
2
+ import { consola } from "consola";
3
+ import { ref, reactive } from "vue";
4
+ import { useMongocampAuth } from "#imports";
5
+ import { navigateTo, useCookie } from "#app";
6
+ const { login } = useMongocampAuth();
7
+ const errorMessage = ref("");
8
+ const loginMail = useCookie("mongocamp_login", { maxAge: 30 * 24 * 60 * 60 });
9
+ const data = ref({ userId: loginMail.value, password: "" });
10
+ const schema = reactive(
11
+ [
12
+ {
13
+ $el: "h3",
14
+ children: "Mongocamp Login"
15
+ },
16
+ {
17
+ $formkit: "nuxtUIInput",
18
+ name: "userId",
19
+ label: "Email",
20
+ validation: "required|email"
21
+ },
22
+ {
23
+ $formkit: "nuxtUIInput",
24
+ name: "password",
25
+ label: "Password",
26
+ inputType: "password",
27
+ validation: "required|length:3"
28
+ }
29
+ ]
30
+ );
31
+ async function actionLogin() {
32
+ errorMessage.value = "";
33
+ const loginId = data.value?.userId || "";
34
+ try {
35
+ await login(loginId, data.value?.password);
36
+ loginMail.value = loginId;
37
+ navigateTo("/secured");
38
+ } catch (e) {
39
+ consola.log(e);
40
+ errorMessage.value = "Wrong Login or Password !";
41
+ }
42
+ }
43
+ </script>
44
+
45
+ <template>
46
+ <div class="flex flex-col items-center justify-center gap-4 p-4 w-1/2">
47
+ <UPageCard class="w-full max-w-md">
48
+ <FUDataEdit
49
+ :data="data"
50
+ :schema="schema"
51
+ submit-label="Login"
52
+ debug-data
53
+ @data-saved="actionLogin"
54
+ />
55
+ <div
56
+ v-if="errorMessage.length > 0"
57
+ class="m-4 mt-2 text-2xl text-red-700 font-medium"
58
+ >
59
+ {{ errorMessage }}
60
+ </div>
61
+ </UPageCard>
62
+ </div>
63
+ </template>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,6 @@
1
+ type __VLS_Props = {
2
+ roleName: string;
3
+ };
4
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;