feat(frontend): Add applicationFormTemplate, add list for application froms, refactoring
This commit is contained in:
@@ -1,11 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-for="(formElement, index) in props.modelValue" :key="formElement.id">
|
<template v-for="(formElement, index) in props.modelValue" :key="formElement.id">
|
||||||
<component
|
<UFormField>
|
||||||
:is="getResolvedComponent(formElement)"
|
<component
|
||||||
:form-options="formElement.options"
|
:is="getResolvedComponent(formElement)"
|
||||||
@update:form-options="updateFormOptions($event, index)"
|
:form-options="formElement.options"
|
||||||
/>
|
@update:form-options="updateFormOptions($event, index)"
|
||||||
</div>
|
/>
|
||||||
|
</UFormField>
|
||||||
|
<USeparator />
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
type PagedApplicationFormDto,
|
type PagedApplicationFormDto,
|
||||||
ResponseError
|
ResponseError
|
||||||
} from '~/.api-client'
|
} from '~/.api-client'
|
||||||
|
import { useApplicationFormApi } from './useApplicationFormApi'
|
||||||
|
|
||||||
const currentApplicationForm: Ref<ApplicationFormDto | undefined> = ref()
|
const currentApplicationForm: Ref<ApplicationFormDto | undefined> = ref()
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ApplicationFormApi, Configuration } from '../.api-client'
|
import { ApplicationFormApi, Configuration } from '../../.api-client'
|
||||||
import type { CreateApplicationFormDto, ApplicationFormDto, PagedApplicationFormDto } from '~/.api-client'
|
import type { CreateApplicationFormDto, ApplicationFormDto, PagedApplicationFormDto } from '~/.api-client'
|
||||||
import { cleanDoubleSlashes, withoutTrailingSlash } from 'ufo'
|
import { cleanDoubleSlashes, withoutTrailingSlash } from 'ufo'
|
||||||
|
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
import {
|
||||||
|
type CreateApplicationFormDto,
|
||||||
|
type ApplicationFormDto,
|
||||||
|
type PagedApplicationFormDto,
|
||||||
|
ResponseError
|
||||||
|
} from '~/.api-client'
|
||||||
|
import { useApplicationFormTemplateApi } from './useApplicationFormTemplateApi'
|
||||||
|
|
||||||
|
const currentApplicationForm: Ref<ApplicationFormDto | undefined> = ref()
|
||||||
|
|
||||||
|
export function useApplicationFormTemplate() {
|
||||||
|
const applicationFormApi = useApplicationFormTemplateApi()
|
||||||
|
|
||||||
|
async function createApplicationFormTemplate(
|
||||||
|
createApplicationFormDto: CreateApplicationFormDto
|
||||||
|
): Promise<ApplicationFormDto> {
|
||||||
|
try {
|
||||||
|
currentApplicationForm.value = await applicationFormApi.createApplicationFormTemplate(createApplicationFormDto)
|
||||||
|
return currentApplicationForm.value
|
||||||
|
} catch (e: unknown) {
|
||||||
|
if (e instanceof ResponseError) {
|
||||||
|
console.error('Failed creating application form:', e.response)
|
||||||
|
} else {
|
||||||
|
console.error('Failed creating application form:', e)
|
||||||
|
}
|
||||||
|
return Promise.reject(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getAllApplicationFormTemplates(): Promise<PagedApplicationFormDto> {
|
||||||
|
try {
|
||||||
|
return await applicationFormApi.getAllApplicationFormTemplates()
|
||||||
|
} catch (e: unknown) {
|
||||||
|
if (e instanceof ResponseError) {
|
||||||
|
console.error('Failed retrieving application forms:', e.response)
|
||||||
|
} else {
|
||||||
|
console.error('Failed retrieving application forms:', e)
|
||||||
|
}
|
||||||
|
return Promise.reject(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getApplicationFormTemplateById(id: string): Promise<ApplicationFormDto> {
|
||||||
|
try {
|
||||||
|
return await applicationFormApi.getApplicationFormTemplateById(id)
|
||||||
|
} catch (e: unknown) {
|
||||||
|
if (e instanceof ResponseError) {
|
||||||
|
console.error(`Failed retrieving application form with ID ${id}:`, e.response)
|
||||||
|
} else {
|
||||||
|
console.error(`Failed retrieving application form with ID ${id}:`, e)
|
||||||
|
}
|
||||||
|
return Promise.reject(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateApplicationFormTemplate(
|
||||||
|
id?: string,
|
||||||
|
applicationFormDto?: ApplicationFormDto
|
||||||
|
): Promise<ApplicationFormDto> {
|
||||||
|
if (!id || !applicationFormDto) {
|
||||||
|
return Promise.reject(new Error('ID or application form DTO missing'))
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
currentApplicationForm.value = await applicationFormApi.updateApplicationFormTemplate(id, applicationFormDto)
|
||||||
|
return currentApplicationForm.value
|
||||||
|
} catch (e: unknown) {
|
||||||
|
if (e instanceof ResponseError) {
|
||||||
|
console.error(`Failed updating application form with ID ${id}:`, e.response)
|
||||||
|
} else {
|
||||||
|
console.error(`Failed updating application form with ID ${id}:`, e)
|
||||||
|
}
|
||||||
|
return Promise.reject(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteApplicationFormTemplateById(id: string): Promise<void> {
|
||||||
|
try {
|
||||||
|
return await applicationFormApi.deleteApplicationFormTemplateById(id)
|
||||||
|
} catch (e: unknown) {
|
||||||
|
if (e instanceof ResponseError) {
|
||||||
|
console.error(`Failed deleting application form with ID ${id}:`, e.response)
|
||||||
|
} else {
|
||||||
|
console.error(`Failed deleting application form with ID ${id}:`, e)
|
||||||
|
}
|
||||||
|
return Promise.reject(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
createApplicationFormTemplate,
|
||||||
|
getAllApplicationFormTemplates,
|
||||||
|
getApplicationFormTemplateById,
|
||||||
|
updateApplicationFormTemplate,
|
||||||
|
deleteApplicationFormTemplateById
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import { ApplicationFormTemplateApi, Configuration } from '../../.api-client'
|
||||||
|
import type { CreateApplicationFormDto, ApplicationFormDto, PagedApplicationFormDto } from '~/.api-client'
|
||||||
|
import { cleanDoubleSlashes, withoutTrailingSlash } from 'ufo'
|
||||||
|
|
||||||
|
export function useApplicationFormTemplateApi() {
|
||||||
|
const appBaseUrl = useRuntimeConfig().app.baseURL
|
||||||
|
const { serverApiBaseUrl, serverApiBasePath, clientProxyBasePath } = useRuntimeConfig().public
|
||||||
|
|
||||||
|
const basePath = withoutTrailingSlash(
|
||||||
|
cleanDoubleSlashes(import.meta.client ? appBaseUrl + clientProxyBasePath : serverApiBaseUrl + serverApiBasePath)
|
||||||
|
)
|
||||||
|
|
||||||
|
const applicationFormApiClient = new ApplicationFormTemplateApi(new Configuration({ basePath }))
|
||||||
|
|
||||||
|
async function createApplicationFormTemplate(
|
||||||
|
createApplicationFormDto: CreateApplicationFormDto
|
||||||
|
): Promise<ApplicationFormDto> {
|
||||||
|
return applicationFormApiClient.createApplicationFormTemplate({ createApplicationFormDto })
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getAllApplicationFormTemplates(): Promise<PagedApplicationFormDto> {
|
||||||
|
return applicationFormApiClient.getAllApplicationFormTemplates()
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getApplicationFormTemplateById(id: string): Promise<ApplicationFormDto> {
|
||||||
|
return applicationFormApiClient.getApplicationFormTemplateById({ id })
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateApplicationFormTemplate(
|
||||||
|
id: string,
|
||||||
|
applicationFormDto: ApplicationFormDto
|
||||||
|
): Promise<ApplicationFormDto> {
|
||||||
|
return applicationFormApiClient.updateApplicationFormTemplate({ id, applicationFormDto })
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteApplicationFormTemplateById(id: string): Promise<void> {
|
||||||
|
return applicationFormApiClient.deleteApplicationFormTemplate({ id })
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
createApplicationFormTemplate,
|
||||||
|
getAllApplicationFormTemplates,
|
||||||
|
getApplicationFormTemplateById,
|
||||||
|
updateApplicationFormTemplate,
|
||||||
|
deleteApplicationFormTemplateById
|
||||||
|
}
|
||||||
|
}
|
||||||
2
legalconsenthub/composables/index.ts
Normal file
2
legalconsenthub/composables/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export { useApplicationFormTemplate } from './applicationFormTemplate/useApplicationFormTemplate'
|
||||||
|
export { useApplicationForm } from './applicationForm/useApplicationForm'
|
||||||
@@ -8,6 +8,12 @@
|
|||||||
class="bg-(--ui-bg-elevated)/25"
|
class="bg-(--ui-bg-elevated)/25"
|
||||||
:ui="{ footer: 'lg:border-t lg:border-(--ui-border)' }"
|
:ui="{ footer: 'lg:border-t lg:border-(--ui-border)' }"
|
||||||
>
|
>
|
||||||
|
<template #header>
|
||||||
|
<NuxtLink to="/">
|
||||||
|
<img src="../public/favicon.ico" alt="Logo" />
|
||||||
|
</NuxtLink>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #default="{ collapsed }">
|
<template #default="{ collapsed }">
|
||||||
<UDashboardSearchButton :collapsed="collapsed" class="bg-transparent ring-(--ui-border)" />
|
<UDashboardSearchButton :collapsed="collapsed" class="bg-transparent ring-(--ui-border)" />
|
||||||
|
|
||||||
|
|||||||
@@ -6,15 +6,7 @@
|
|||||||
<UDashboardSidebarCollapse />
|
<UDashboardSidebarCollapse />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #right>
|
<template #right />
|
||||||
<UTooltip text="Notifications" :shortcuts="['N']">
|
|
||||||
<UButton color="neutral" variant="ghost" square>
|
|
||||||
<UChip color="error" inset>
|
|
||||||
<UIcon name="i-lucide-bell" class="size-5 shrink-0" />
|
|
||||||
</UChip>
|
|
||||||
</UButton>
|
|
||||||
</UTooltip>
|
|
||||||
</template>
|
|
||||||
</UDashboardNavbar>
|
</UDashboardNavbar>
|
||||||
|
|
||||||
<UDashboardToolbar>
|
<UDashboardToolbar>
|
||||||
@@ -23,11 +15,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #body>
|
<template #body>
|
||||||
Ampel Status: {{ validationStatus }}
|
<div class="flex flex-col gap-4 sm:gap-6 lg:gap-12 w-full lg:max-w-2xl mx-auto">
|
||||||
<UForm class="space-y-4" :state="{}" @submit="onSubmit">
|
<UPageCard title="Ampelstatus" variant="naked" orientation="horizontal" class="mb-4">
|
||||||
<FormEngine v-model="formElements" />
|
{{ ampelStatusEmoji }}
|
||||||
<UButton type="submit">Submit</UButton>
|
</UPageCard>
|
||||||
</UForm>
|
|
||||||
|
<UPageCard variant="subtle">
|
||||||
|
<UForm class="space-y-4" :state="{}" @submit="onSubmit">
|
||||||
|
<FormEngine v-model="formElements" />
|
||||||
|
<UButton type="submit">Submit</UButton>
|
||||||
|
</UForm>
|
||||||
|
</UPageCard>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</UDashboardPanel>
|
</UDashboardPanel>
|
||||||
</template>
|
</template>
|
||||||
@@ -37,11 +36,11 @@ import { ComplianceStatus, type PagedApplicationFormDto } from '~/.api-client'
|
|||||||
import { useApplicationFormValidator } from '~/composables/useApplicationFormValidator'
|
import { useApplicationFormValidator } from '~/composables/useApplicationFormValidator'
|
||||||
import type { FormElementId } from '~/types/FormElement'
|
import type { FormElementId } from '~/types/FormElement'
|
||||||
|
|
||||||
const { getAllApplicationForms, updateApplicationForm } = useApplicationForm()
|
const { getAllApplicationFormTemplates, updateApplicationFormTemplate } = useApplicationFormTemplate()
|
||||||
const { validateFormElements, getHighestComplianceStatus } = useApplicationFormValidator()
|
const { validateFormElements, getHighestComplianceStatus } = useApplicationFormValidator()
|
||||||
|
|
||||||
const { data } = await useAsyncData<PagedApplicationFormDto>(async () => {
|
const { data } = await useAsyncData<PagedApplicationFormDto>(async () => {
|
||||||
return await getAllApplicationForms()
|
return await getAllApplicationFormTemplates()
|
||||||
})
|
})
|
||||||
|
|
||||||
const formElements = computed({
|
const formElements = computed({
|
||||||
@@ -64,7 +63,20 @@ watch(
|
|||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const ampelStatusEmoji = computed(() => {
|
||||||
|
switch (validationStatus.value) {
|
||||||
|
case ComplianceStatus.Critical:
|
||||||
|
return '🔴'
|
||||||
|
case ComplianceStatus.Warning:
|
||||||
|
return '🟡'
|
||||||
|
case ComplianceStatus.NonCritical:
|
||||||
|
return '🟢'
|
||||||
|
default:
|
||||||
|
return '🟢'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
async function onSubmit() {
|
async function onSubmit() {
|
||||||
await updateApplicationForm(data?.value?.content[0].id, data?.value?.content[0])
|
await updateApplicationFormTemplate(data?.value?.content[0].id, data?.value?.content[0])
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -7,15 +7,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #right>
|
<template #right>
|
||||||
<UTooltip text="Notifications" :shortcuts="['N']">
|
<UDropdownMenu :items="items">
|
||||||
<UButton color="neutral" variant="ghost" square>
|
<UButton icon="i-lucide-plus" size="md" class="rounded-full" />
|
||||||
<UChip color="error" inset>
|
</UDropdownMenu>
|
||||||
<UIcon name="i-lucide-bell" class="size-5 shrink-0" />
|
|
||||||
</UChip>
|
|
||||||
</UButton>
|
|
||||||
</UTooltip>
|
|
||||||
|
|
||||||
<UButton icon="i-lucide-plus" size="md" class="rounded-full" @click="navigateTo('/create')" />
|
|
||||||
</template>
|
</template>
|
||||||
</UDashboardNavbar>
|
</UDashboardNavbar>
|
||||||
|
|
||||||
@@ -25,17 +19,47 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #body>
|
<template #body>
|
||||||
<div>
|
<UPageList>
|
||||||
<pre>{{ session }}</pre>
|
<UPageCard
|
||||||
<h1>{{ session.data ? 'Du bist eingeloggt' : 'Nicht eingeloggt' }}</h1>
|
v-for="(applicationFormElem, index) in applicationForm"
|
||||||
<button v-if="session?.data" @click="authClient.signOut()">Sign out</button>
|
:key="index"
|
||||||
</div>
|
variant="ghost"
|
||||||
<Register />
|
:to="`application-forms/${applicationFormElem.id}`"
|
||||||
<Login />
|
>
|
||||||
|
<template #body>
|
||||||
|
#{{ index }} {{ applicationFormElem.id }} {{ applicationFormElem.createdAt }}
|
||||||
|
{{ applicationFormElem.isTemplate }}
|
||||||
|
</template>
|
||||||
|
</UPageCard>
|
||||||
|
</UPageList>
|
||||||
</template>
|
</template>
|
||||||
</UDashboardPanel>
|
</UDashboardPanel>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const session = authClient.useSession()
|
import type { PagedApplicationFormDto } from '~/.api-client'
|
||||||
|
const { getAllApplicationForms } = useApplicationForm()
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
label: 'Neuer Mitbestimmungsantrag',
|
||||||
|
icon: 'i-lucide-send',
|
||||||
|
to: '/create'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
const { data } = await useAsyncData<PagedApplicationFormDto>(async () => {
|
||||||
|
return await getAllApplicationForms()
|
||||||
|
})
|
||||||
|
|
||||||
|
const applicationForm = computed({
|
||||||
|
get: () => data?.value?.content ?? [],
|
||||||
|
set: (val) => {
|
||||||
|
if (val && data.value) {
|
||||||
|
data.value.content = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
45
legalconsenthub/pages/login.vue
Normal file
45
legalconsenthub/pages/login.vue
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<template>
|
||||||
|
<UDashboardPanel id="home">
|
||||||
|
<template #header>
|
||||||
|
<UDashboardNavbar title="Home" :ui="{ right: 'gap-3' }">
|
||||||
|
<template #leading>
|
||||||
|
<UDashboardSidebarCollapse />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #right>
|
||||||
|
<UDropdownMenu :items="items">
|
||||||
|
<UButton icon="i-lucide-plus" size="md" class="rounded-full" />
|
||||||
|
</UDropdownMenu>
|
||||||
|
</template>
|
||||||
|
</UDashboardNavbar>
|
||||||
|
|
||||||
|
<UDashboardToolbar>
|
||||||
|
<template #left> toolbar left </template>
|
||||||
|
</UDashboardToolbar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #body>
|
||||||
|
<div>
|
||||||
|
<pre>{{ session }}</pre>
|
||||||
|
<h1>{{ session.data ? 'Du bist eingeloggt' : 'Nicht eingeloggt' }}</h1>
|
||||||
|
<button v-if="session?.data" @click="authClient.signOut()">Sign out</button>
|
||||||
|
</div>
|
||||||
|
<Register />
|
||||||
|
<Login />
|
||||||
|
</template>
|
||||||
|
</UDashboardPanel>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
const session = authClient.useSession()
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
label: 'Neuer Mitbestimmungsantrag',
|
||||||
|
icon: 'i-lucide-send',
|
||||||
|
to: '/create'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
</script>
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 15 KiB |
Reference in New Issue
Block a user