fixes in DeviceCertificats and DeviceTasks dialogs
This commit is contained in:
8
management-ui/package-lock.json
generated
8
management-ui/package-lock.json
generated
@@ -18,7 +18,7 @@
|
|||||||
"hls.js": "^1.6.13",
|
"hls.js": "^1.6.13",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
"lucide-vue-next": "^0.525.0",
|
"lucide-vue-next": "^0.525.0",
|
||||||
"reka-ui": "^2.5.0",
|
"reka-ui": "^2.6.1",
|
||||||
"tailwind-merge": "^3.3.1",
|
"tailwind-merge": "^3.3.1",
|
||||||
"tailwindcss": "^4.1.11",
|
"tailwindcss": "^4.1.11",
|
||||||
"tw-animate-css": "^1.3.6",
|
"tw-animate-css": "^1.3.6",
|
||||||
@@ -2462,9 +2462,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/reka-ui": {
|
"node_modules/reka-ui": {
|
||||||
"version": "2.5.0",
|
"version": "2.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.6.1.tgz",
|
||||||
"integrity": "sha512-81aMAmJeVCy2k0E6x7n1kypDY6aM1ldLis5+zcdV1/JtoAlSDck5OBsyLRJU9CfgbrQp1ImnRnBSmC4fZ2fkZQ==",
|
"integrity": "sha512-XK7cJDQoNuGXfCNzBBo/81Yg/OgjPwvbabnlzXG2VsdSgNsT6iIkuPBPr+C0Shs+3bb0x0lbPvgQAhMSCKm5Ww==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/dom": "^1.6.13",
|
"@floating-ui/dom": "^1.6.13",
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
"hls.js": "^1.6.13",
|
"hls.js": "^1.6.13",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
"lucide-vue-next": "^0.525.0",
|
"lucide-vue-next": "^0.525.0",
|
||||||
"reka-ui": "^2.5.0",
|
"reka-ui": "^2.6.1",
|
||||||
"tailwind-merge": "^3.3.1",
|
"tailwind-merge": "^3.3.1",
|
||||||
"tailwindcss": "^4.1.11",
|
"tailwindcss": "^4.1.11",
|
||||||
"tw-animate-css": "^1.3.6",
|
"tw-animate-css": "^1.3.6",
|
||||||
|
|||||||
@@ -9,22 +9,24 @@ export const buttonVariants = cva(
|
|||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
default:
|
default:
|
||||||
"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
"bg-primary text-primary-foreground hover:bg-primary/90",
|
||||||
destructive:
|
destructive:
|
||||||
"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
||||||
outline:
|
outline:
|
||||||
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
||||||
secondary:
|
secondary:
|
||||||
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||||
ghost:
|
ghost:
|
||||||
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
||||||
link: "text-primary underline-offset-4 hover:underline",
|
link: "text-primary underline-offset-4 hover:underline",
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
"default": "h-9 px-4 py-2 has-[>svg]:px-3",
|
||||||
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
"sm": "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
||||||
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
"lg": "h-10 rounded-md px-6 has-[>svg]:px-4",
|
||||||
icon: "size-9",
|
"icon": "size-9",
|
||||||
|
"icon-sm": "size-8",
|
||||||
|
"icon-lg": "size-10",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
@@ -33,5 +35,4 @@ export const buttonVariants = cva(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
export type ButtonVariants = VariantProps<typeof buttonVariants>
|
export type ButtonVariants = VariantProps<typeof buttonVariants>
|
||||||
|
|||||||
26
management-ui/src/components/ui/pagination/Pagination.vue
Normal file
26
management-ui/src/components/ui/pagination/Pagination.vue
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { PaginationRootEmits, PaginationRootProps } from "reka-ui"
|
||||||
|
import type { HTMLAttributes } from "vue"
|
||||||
|
import { reactiveOmit } from "@vueuse/core"
|
||||||
|
import { PaginationRoot, useForwardPropsEmits } from "reka-ui"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const props = defineProps<PaginationRootProps & {
|
||||||
|
class?: HTMLAttributes["class"]
|
||||||
|
}>()
|
||||||
|
const emits = defineEmits<PaginationRootEmits>()
|
||||||
|
|
||||||
|
const delegatedProps = reactiveOmit(props, "class")
|
||||||
|
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PaginationRoot
|
||||||
|
v-slot="slotProps"
|
||||||
|
data-slot="pagination"
|
||||||
|
v-bind="forwarded"
|
||||||
|
:class="cn('mx-auto flex w-full justify-center', props.class)"
|
||||||
|
>
|
||||||
|
<slot v-bind="slotProps" />
|
||||||
|
</PaginationRoot>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { PaginationListProps } from "reka-ui"
|
||||||
|
import type { HTMLAttributes } from "vue"
|
||||||
|
import { reactiveOmit } from "@vueuse/core"
|
||||||
|
import { PaginationList } from "reka-ui"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const props = defineProps<PaginationListProps & { class?: HTMLAttributes["class"] }>()
|
||||||
|
|
||||||
|
const delegatedProps = reactiveOmit(props, "class")
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PaginationList
|
||||||
|
v-slot="slotProps"
|
||||||
|
data-slot="pagination-content"
|
||||||
|
v-bind="delegatedProps"
|
||||||
|
:class="cn('flex flex-row items-center gap-1', props.class)"
|
||||||
|
>
|
||||||
|
<slot v-bind="slotProps" />
|
||||||
|
</PaginationList>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { PaginationEllipsisProps } from "reka-ui"
|
||||||
|
import type { HTMLAttributes } from "vue"
|
||||||
|
import { reactiveOmit } from "@vueuse/core"
|
||||||
|
import { MoreHorizontal } from "lucide-vue-next"
|
||||||
|
import { PaginationEllipsis } from "reka-ui"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const props = defineProps<PaginationEllipsisProps & { class?: HTMLAttributes["class"] }>()
|
||||||
|
|
||||||
|
const delegatedProps = reactiveOmit(props, "class")
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PaginationEllipsis
|
||||||
|
data-slot="pagination-ellipsis"
|
||||||
|
v-bind="delegatedProps"
|
||||||
|
:class="cn('flex size-9 items-center justify-center', props.class)"
|
||||||
|
>
|
||||||
|
<slot>
|
||||||
|
<MoreHorizontal class="size-4" />
|
||||||
|
<span class="sr-only">More pages</span>
|
||||||
|
</slot>
|
||||||
|
</PaginationEllipsis>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { PaginationFirstProps } from "reka-ui"
|
||||||
|
import type { HTMLAttributes } from "vue"
|
||||||
|
import type { ButtonVariants } from '@/components/ui/button'
|
||||||
|
import { reactiveOmit } from "@vueuse/core"
|
||||||
|
import { ChevronLeftIcon } from "lucide-vue-next"
|
||||||
|
import { PaginationFirst, useForwardProps } from "reka-ui"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { buttonVariants } from '@/components/ui/button'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<PaginationFirstProps & {
|
||||||
|
size?: ButtonVariants["size"]
|
||||||
|
class?: HTMLAttributes["class"]
|
||||||
|
}>(), {
|
||||||
|
size: "default",
|
||||||
|
})
|
||||||
|
|
||||||
|
const delegatedProps = reactiveOmit(props, "class", "size")
|
||||||
|
const forwarded = useForwardProps(delegatedProps)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PaginationFirst
|
||||||
|
data-slot="pagination-first"
|
||||||
|
:class="cn(buttonVariants({ variant: 'ghost', size }), 'gap-1 px-2.5 sm:pr-2.5', props.class)"
|
||||||
|
v-bind="forwarded"
|
||||||
|
>
|
||||||
|
<slot>
|
||||||
|
<ChevronLeftIcon />
|
||||||
|
<span class="hidden sm:block">First</span>
|
||||||
|
</slot>
|
||||||
|
</PaginationFirst>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { PaginationListItemProps } from "reka-ui"
|
||||||
|
import type { HTMLAttributes } from "vue"
|
||||||
|
import type { ButtonVariants } from '@/components/ui/button'
|
||||||
|
import { reactiveOmit } from "@vueuse/core"
|
||||||
|
import { PaginationListItem } from "reka-ui"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { buttonVariants } from '@/components/ui/button'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<PaginationListItemProps & {
|
||||||
|
size?: ButtonVariants["size"]
|
||||||
|
class?: HTMLAttributes["class"]
|
||||||
|
isActive?: boolean
|
||||||
|
}>(), {
|
||||||
|
size: "icon",
|
||||||
|
})
|
||||||
|
|
||||||
|
const delegatedProps = reactiveOmit(props, "class", "size", "isActive")
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PaginationListItem
|
||||||
|
data-slot="pagination-item"
|
||||||
|
v-bind="delegatedProps"
|
||||||
|
:class="cn(
|
||||||
|
buttonVariants({
|
||||||
|
variant: isActive ? 'outline' : 'ghost',
|
||||||
|
size,
|
||||||
|
}),
|
||||||
|
props.class)"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</PaginationListItem>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { PaginationLastProps } from "reka-ui"
|
||||||
|
import type { HTMLAttributes } from "vue"
|
||||||
|
import type { ButtonVariants } from '@/components/ui/button'
|
||||||
|
import { reactiveOmit } from "@vueuse/core"
|
||||||
|
import { ChevronRightIcon } from "lucide-vue-next"
|
||||||
|
import { PaginationLast, useForwardProps } from "reka-ui"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { buttonVariants } from '@/components/ui/button'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<PaginationLastProps & {
|
||||||
|
size?: ButtonVariants["size"]
|
||||||
|
class?: HTMLAttributes["class"]
|
||||||
|
}>(), {
|
||||||
|
size: "default",
|
||||||
|
})
|
||||||
|
|
||||||
|
const delegatedProps = reactiveOmit(props, "class", "size")
|
||||||
|
const forwarded = useForwardProps(delegatedProps)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PaginationLast
|
||||||
|
data-slot="pagination-last"
|
||||||
|
:class="cn(buttonVariants({ variant: 'ghost', size }), 'gap-1 px-2.5 sm:pr-2.5', props.class)"
|
||||||
|
v-bind="forwarded"
|
||||||
|
>
|
||||||
|
<slot>
|
||||||
|
<span class="hidden sm:block">Last</span>
|
||||||
|
<ChevronRightIcon />
|
||||||
|
</slot>
|
||||||
|
</PaginationLast>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { PaginationNextProps } from "reka-ui"
|
||||||
|
import type { HTMLAttributes } from "vue"
|
||||||
|
import type { ButtonVariants } from '@/components/ui/button'
|
||||||
|
import { reactiveOmit } from "@vueuse/core"
|
||||||
|
import { ChevronRightIcon } from "lucide-vue-next"
|
||||||
|
import { PaginationNext, useForwardProps } from "reka-ui"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { buttonVariants } from '@/components/ui/button'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<PaginationNextProps & {
|
||||||
|
size?: ButtonVariants["size"]
|
||||||
|
class?: HTMLAttributes["class"]
|
||||||
|
}>(), {
|
||||||
|
size: "default",
|
||||||
|
})
|
||||||
|
|
||||||
|
const delegatedProps = reactiveOmit(props, "class", "size")
|
||||||
|
const forwarded = useForwardProps(delegatedProps)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PaginationNext
|
||||||
|
data-slot="pagination-next"
|
||||||
|
:class="cn(buttonVariants({ variant: 'ghost', size }), 'gap-1 px-2.5 sm:pr-2.5', props.class)"
|
||||||
|
v-bind="forwarded"
|
||||||
|
>
|
||||||
|
<slot>
|
||||||
|
<span class="hidden sm:block">Next</span>
|
||||||
|
<ChevronRightIcon />
|
||||||
|
</slot>
|
||||||
|
</PaginationNext>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import type { PaginationPrevProps } from "reka-ui"
|
||||||
|
import type { HTMLAttributes } from "vue"
|
||||||
|
import type { ButtonVariants } from '@/components/ui/button'
|
||||||
|
import { reactiveOmit } from "@vueuse/core"
|
||||||
|
import { ChevronLeftIcon } from "lucide-vue-next"
|
||||||
|
import { PaginationPrev, useForwardProps } from "reka-ui"
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { buttonVariants } from '@/components/ui/button'
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<PaginationPrevProps & {
|
||||||
|
size?: ButtonVariants["size"]
|
||||||
|
class?: HTMLAttributes["class"]
|
||||||
|
}>(), {
|
||||||
|
size: "default",
|
||||||
|
})
|
||||||
|
|
||||||
|
const delegatedProps = reactiveOmit(props, "class", "size")
|
||||||
|
const forwarded = useForwardProps(delegatedProps)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<PaginationPrev
|
||||||
|
data-slot="pagination-previous"
|
||||||
|
:class="cn(buttonVariants({ variant: 'ghost', size }), 'gap-1 px-2.5 sm:pr-2.5', props.class)"
|
||||||
|
v-bind="forwarded"
|
||||||
|
>
|
||||||
|
<slot>
|
||||||
|
<ChevronLeftIcon />
|
||||||
|
<span class="hidden sm:block">Previous</span>
|
||||||
|
</slot>
|
||||||
|
</PaginationPrev>
|
||||||
|
</template>
|
||||||
8
management-ui/src/components/ui/pagination/index.ts
Normal file
8
management-ui/src/components/ui/pagination/index.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export { default as Pagination } from "./Pagination.vue"
|
||||||
|
export { default as PaginationContent } from "./PaginationContent.vue"
|
||||||
|
export { default as PaginationEllipsis } from "./PaginationEllipsis.vue"
|
||||||
|
export { default as PaginationFirst } from "./PaginationFirst.vue"
|
||||||
|
export { default as PaginationItem } from "./PaginationItem.vue"
|
||||||
|
export { default as PaginationLast } from "./PaginationLast.vue"
|
||||||
|
export { default as PaginationNext } from "./PaginationNext.vue"
|
||||||
|
export { default as PaginationPrevious } from "./PaginationPrevious.vue"
|
||||||
@@ -17,7 +17,7 @@ import type { ColumnDef } from '@tanstack/vue-table'
|
|||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: { type: Boolean as PropType<boolean>, required: true },
|
modelValue: { type: Boolean as PropType<boolean>, required: true },
|
||||||
device: { type: Object as PropType<Device>, required: false },
|
device: { type: Object as PropType<Device>, required: false },
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -39,8 +39,8 @@ type DeviceCertListDto = { certs: DeviceCertDto[] }
|
|||||||
|
|
||||||
// --- local state ---
|
// --- local state ---
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const error = ref<string | null>(null)
|
const error = ref<string | null>(null)
|
||||||
const certs = ref<DeviceCertDto[]>([])
|
const certs = ref<DeviceCertDto[]>([])
|
||||||
|
|
||||||
const guid = computed(() => props.device?.guid ?? '')
|
const guid = computed(() => props.device?.guid ?? '')
|
||||||
|
|
||||||
@@ -55,8 +55,8 @@ const columns: ColumnDef<DeviceCertDto, any>[] = [
|
|||||||
{ accessorKey: 'issuerCN', header: 'Issuer CN' },
|
{ accessorKey: 'issuerCN', header: 'Issuer CN' },
|
||||||
{ accessorKey: 'subjectDN', header: 'Subject DN' },
|
{ accessorKey: 'subjectDN', header: 'Subject DN' },
|
||||||
{ accessorKey: 'notBefore', header: 'Not Before', cell: ({ row }) => fmt(row.original.notBefore) },
|
{ accessorKey: 'notBefore', header: 'Not Before', cell: ({ row }) => fmt(row.original.notBefore) },
|
||||||
{ accessorKey: 'notAfter', header: 'Not After', cell: ({ row }) => fmt(row.original.notAfter) },
|
{ accessorKey: 'notAfter', header: 'Not After', cell: ({ row }) => fmt(row.original.notAfter) },
|
||||||
{ accessorKey: 'createdAt', header: 'Created', cell: ({ row }) => fmt(row.original.createdAt) },
|
{ accessorKey: 'createdAt', header: 'Created', cell: ({ row }) => fmt(row.original.createdAt) },
|
||||||
]
|
]
|
||||||
|
|
||||||
async function loadCerts() {
|
async function loadCerts() {
|
||||||
@@ -91,7 +91,7 @@ function close() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Dialog :open="props.modelValue" @update:open="(v:boolean) => emit('update:modelValue', v)">
|
<Dialog :open="props.modelValue" @update:open="(v: boolean) => emit('update:modelValue', v)">
|
||||||
<DialogContent class="sm:min-w-[1000px]">
|
<DialogContent class="sm:min-w-[1000px]">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
@@ -102,7 +102,7 @@ function close() {
|
|||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2 pt-8">
|
||||||
<Button variant="outline" :disabled="loading || !guid" @click="loadCerts">
|
<Button variant="outline" :disabled="loading || !guid" @click="loadCerts">
|
||||||
{{ loading ? 'Loading…' : 'Refresh' }}
|
{{ loading ? 'Loading…' : 'Refresh' }}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -117,11 +117,13 @@ function close() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<DataTableNoCheckboxScroll
|
<div class="flex-1 min-h-0 pb-2">
|
||||||
:columns="columns"
|
<DataTableNoCheckboxScroll
|
||||||
:data="certs"
|
:columns="columns"
|
||||||
minTableWidth="min-w-[900px]"
|
:data="certs"
|
||||||
/>
|
minTableWidth="min-w-[900px]" />
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
|
|||||||
@@ -100,17 +100,22 @@ const task_columns: ColumnDef<TaskDto, any>[] = [
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Dialog :open="props.modelValue" @update:open="(v: boolean) => emit('update:modelValue', v)">
|
<Dialog :open="props.modelValue" @update:open="(v: boolean) => emit('update:modelValue', v)">
|
||||||
<DialogContent class="sm:min-w-[1200px] max-h-[80vh] p-0 flex flex-col">
|
<DialogContent class="sm:min-w-[1000px]">
|
||||||
<DialogHeader class="flex flex-row items-center justify-between gap-4">
|
<DialogHeader>
|
||||||
<div>
|
<div class="flex items-center justify-between">
|
||||||
<DialogTitle>Tasks</DialogTitle>
|
<div>
|
||||||
<DialogDescription>{{ props.device?.guid }}</DialogDescription>
|
<DialogTitle>Tasks</DialogTitle>
|
||||||
</div>
|
<DialogDescription class="mt-1 break-all">
|
||||||
<div class="flex gap-2">
|
{{ props.device?.guid }}
|
||||||
<Button variant="outline" :disabled="loading || !props.device?.guid" @click="fetchTasks">
|
</DialogDescription>
|
||||||
{{ loading ? 'Loading…' : 'Refresh' }}
|
</div>
|
||||||
</Button>
|
<div class="flex gap-2 pt-8">
|
||||||
|
<Button variant="outline" :disabled="loading || !props.device?.guid" @click="fetchTasks">
|
||||||
|
{{ loading ? 'Loading…' : 'Refresh' }}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<div v-if="error" class="text-sm text-red-600 mb-3">{{ error }}</div>
|
<div v-if="error" class="text-sm text-red-600 mb-3">{{ error }}</div>
|
||||||
@@ -120,8 +125,11 @@ const task_columns: ColumnDef<TaskDto, any>[] = [
|
|||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<!-- SCROLLABLE MIDDLE: flex-1 + min-h-0 so child can overflow -->
|
<!-- SCROLLABLE MIDDLE: flex-1 + min-h-0 so child can overflow -->
|
||||||
<div class="flex-1 min-h-0 px-6 pb-4">
|
<div class="flex-1 min-h-0 pb-2">
|
||||||
<DataTableNoCheckboxScroll :columns="task_columns" :data="tasks" minTableWidth="min-w-[800px]" />
|
<DataTableNoCheckboxScroll
|
||||||
|
:columns="task_columns"
|
||||||
|
:data="tasks"
|
||||||
|
minTableWidth="min-w-[900px]" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*","src/types/**/*"]
|
"@/*": ["./src/*","src/types/*"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user