52 lines
1.7 KiB
Vue
52 lines
1.7 KiB
Vue
<script setup lang="ts">
|
|
import { computed } from 'vue';
|
|
import { resolveWidgetComponent } from '@/components/widgets';
|
|
import { useTranslations } from '@/composables/useVanguard';
|
|
import AppLayout from '@/layouts/AppLayout.vue';
|
|
import type { WidgetPayload } from '@/types';
|
|
|
|
const props = defineProps<{ widgets: WidgetPayload[] }>();
|
|
|
|
const { __ } = useTranslations();
|
|
|
|
/**
|
|
* Bootstrap's col-md-{n} becomes a span on a 12 column grid. The classes are
|
|
* written out in full so Tailwind can see them when scanning source.
|
|
*/
|
|
const WIDTHS: Record<string, string> = {
|
|
'1': 'md:col-span-1',
|
|
'2': 'md:col-span-2',
|
|
'3': 'md:col-span-3',
|
|
'4': 'md:col-span-4',
|
|
'5': 'md:col-span-5',
|
|
'6': 'md:col-span-6',
|
|
'7': 'md:col-span-7',
|
|
'8': 'md:col-span-8',
|
|
'9': 'md:col-span-9',
|
|
'10': 'md:col-span-10',
|
|
'11': 'md:col-span-11',
|
|
'12': 'md:col-span-12',
|
|
};
|
|
|
|
const resolved = computed(() =>
|
|
props.widgets
|
|
.map((widget, index) => ({
|
|
key: `${widget.component}-${index}`,
|
|
component: resolveWidgetComponent(widget.component),
|
|
props: widget.props,
|
|
widthClass: widget.width ? (WIDTHS[widget.width] ?? 'md:col-span-12') : 'md:col-span-12',
|
|
}))
|
|
.filter((widget) => widget.component !== undefined),
|
|
);
|
|
</script>
|
|
|
|
<template>
|
|
<AppLayout :title="__('Dashboard')" :heading="__('Dashboard')" :breadcrumbs="[{ label: __('Dashboard') }]">
|
|
<div class="grid grid-cols-1 gap-4 md:grid-cols-12">
|
|
<div v-for="widget in resolved" :key="widget.key" :class="widget.widthClass">
|
|
<component :is="widget.component" v-bind="widget.props" />
|
|
</div>
|
|
</div>
|
|
</AppLayout>
|
|
</template>
|