refactor: update ConfigPanels component to receive useConfigPanels data

This commit is contained in:
axolotle 2024-07-24 17:01:39 +02:00
parent d3f843b1b1
commit 8af40dd04a

View file

@ -1,88 +1,87 @@
<script setup lang="ts"> <script
import { useVuelidate, type BaseValidation } from '@vuelidate/core' setup
import { computed, defineAsyncComponent, toRef } from 'vue' lang="ts"
import { useRoute, useRouter } from 'vue-router' generic="NestedMV extends Obj, MV extends Obj<NestedMV>"
>
import type { CustomRoute, Obj } from '@/types/commons' import type { FormValidation } from '@/composables/form'
import type { KeyOfStr, Obj } from '@/types/commons'
import type { ConfigPanel, ConfigPanels } from '@/types/configPanels'
defineOptions({ defineOptions({
inheritAttrs: false, inheritAttrs: false,
}) })
const RoutableTabs = defineAsyncComponent( const props = defineProps<{
() => import('@/components/RoutableTabs.vue'), // modelValue: MV[keyof MV]
) panel: ConfigPanel<NestedMV, MV>
routes: ConfigPanels<NestedMV, MV>['routes']
const props = withDefaults( validations: FormValidation<NestedMV>
defineProps<{
panels: Obj[]
forms: Obj<Obj>
validations: BaseValidation
externalResults: Obj
errors?: Obj // never used
noRedirect?: boolean
routes?: CustomRoute[]
}>(),
{
errors: undefined,
routes: undefined,
noRedirect: false,
},
)
const slots = defineSlots<{
'tab-top': any
'tab-before': any
'tab-after': any
}>() }>()
const externalResults = toRef(props, 'externalResults') const emit = defineEmits<{
const rules = computed(() => ({ forms: props.validations })) apply: [action?: KeyOfStr<typeof props.panel.fields>]
const v$ = useVuelidate(rules, props.forms, { 'update:modelValue': [modelValue: MV[keyof MV]]
$externalResults: externalResults, }>()
})
const router = useRouter() const slots = defineSlots<{
const route = useRoute() 'tab-top'?: any
const routes = computed(() => { 'tab-before'?: any
return ( default?: any
props.routes || 'tab-after'?: any
props.panels.map((panel) => ({ }>()
to: { params: { tabId: panel.id } },
text: panel.name,
icon: panel.icon || 'wrench',
}))
)
})
if (!props.noRedirect && !route.params.tabId) { const modelValue = defineModel<NestedMV>({ required: true })
router.replace({ params: { tabId: props.panels[0].id } })
}
</script> </script>
<template> <template>
<div class="config-panel"> <BCard v-if="routes.length > 1" no-body class="config-panel">
<!-- FIXME vue3 - weird stuff with event binding, need to propagate by hand for now --> <BCardHeader header-tag="nav">
<RoutableTabs <BNav card-header fill pills>
v-if="routes.length > 1" <BNavItem
v-bind="{ panels, forms, v: v$, ...$attrs }" v-for="route in routes"
:routes="routes" :key="route.text"
:to="route.to"
:active="$route.params.tabId === route.to.params?.tabId"
>
<!-- FIXME added :active="" because `exact-active-class` not working https://github.com/bootstrap-vue-next/bootstrap-vue-next/issues/1754 -->
<!-- exact-active-class="active" -->
<YIcon v-if="route.icon" :iname="route.icon" />
{{ route.text }}
</BNavItem>
</BNav>
</BCardHeader>
<CardForm
v-model="modelValue"
:fields="panel.fields"
:no-footer="!panel.hasApplyButton"
:sections="panel.sections"
:validations="validations"
as-tab
@submit="emit('apply')"
@action="emit('apply', $event)"
> >
<template #tab-top> <template #top>
<slot name="tab-top" /> <slot name="tab-top" />
</template> </template>
<template #tab-before> <template v-if="panel.help" #disclaimer>
<div class="alert alert-info" v-html="panel.help" />
</template>
<template #before-form>
<slot name="tab-before" /> <slot name="tab-before" />
</template> </template>
<template #tab-after> <template v-if="slots.default" #default>
<slot name="default" />
</template>
<template #after-form>
<slot name="tab-after" /> <slot name="tab-after" />
</template> </template>
</RoutableTabs> </CardForm>
</BCard>
<YCard v-else :title="routes[0].text" :icon="routes[0].icon"> <YCard v-else :title="routes[0].text" :icon="routes[0].icon">
<slot name="tab-top" /> <slot name="tab-top" />
<slot name="tab-before" /> <slot name="tab-before" />
<slot name="tab-after" /> <slot name="default" />
</YCard> <slot name="tab-after" />
</div> </YCard>
</template> </template>