Added license management module
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
<script setup lang="ts">
|
||||
import { License } from '@/types'
|
||||
import { toLocalDate } from '@/lib/utils'
|
||||
import Fuse from 'fuse.js'
|
||||
import { onMounted, ref, computed } from 'vue'
|
||||
import AppLayout from '@/layouts/AppLayout.vue'
|
||||
import AppHeader from '@/components/AppHeader.vue'
|
||||
import { Head } from '@inertiajs/vue3'
|
||||
import { Table, TableRow, TableBody, TableCell, TableFooter, TableHead, TableHeader } from '@/components/ui/crm-table'
|
||||
import { Input } from '@/components/ui/crm-input'
|
||||
import { Badge } from '@/components/ui/crm-badge'
|
||||
import Button from '@/components/ui/crm-button/Button.vue'
|
||||
import { ButtonGroup } from '@/components/ui/button-group'
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import { Kbd, KbdGroup } from '@/components/ui/kbd'
|
||||
import LicenseService from '@/services/LicenseService';
|
||||
import { Check, Download, Trash2, Plus, Delete, Search } from 'lucide-vue-next'
|
||||
import { alertStore } from "@/stores/alertStore"
|
||||
import { toast } from 'vue-sonner';
|
||||
|
||||
interface Props {
|
||||
licenseData: License[]
|
||||
}
|
||||
const props = defineProps<Props>()
|
||||
const licenses = ref([] as License[])
|
||||
const searchQuery = ref('')
|
||||
const searchField = ref()
|
||||
const alert = alertStore()
|
||||
|
||||
onMounted(() => {
|
||||
licenses.value = props.licenseData
|
||||
})
|
||||
|
||||
const fuse = computed(() => {
|
||||
return new Fuse(props.licenseData, {
|
||||
keys: ['name', 'email', 'product', 'version'],
|
||||
threshold: 0.3
|
||||
})
|
||||
})
|
||||
|
||||
const filteredLicenses = computed(() => {
|
||||
|
||||
let licenses = props.licenseData
|
||||
|
||||
// Filter by search query
|
||||
if (searchQuery.value) {
|
||||
licenses = fuse.value.search(searchQuery.value).map(result => result.item)
|
||||
}
|
||||
|
||||
return licenses
|
||||
})
|
||||
|
||||
const downloadLicense = (id: number) => {
|
||||
window.open('/licenses/download/' + id)
|
||||
}
|
||||
|
||||
const deleteLicense = (id: number) => {
|
||||
alert.show(
|
||||
"Möchtest Du diese Lizenz wirklich löschen?",
|
||||
null,
|
||||
{
|
||||
actionText: "Löschen",
|
||||
actionVariant: "destructive",
|
||||
onAction: async () => {
|
||||
LicenseService.deleteLicense(id).then(() => {
|
||||
licenses.value = licenses.value.filter(license => license.id != id)
|
||||
}).catch((error) => {
|
||||
toast.error('Fehler beim Löschen der Lizenz', { duration: 5000, description: error.message })
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<Head title="Lizenzen" />
|
||||
|
||||
<AppLayout title="Lizenzen">
|
||||
|
||||
<!-- Header functions -->
|
||||
<AppHeader>
|
||||
<template #left>
|
||||
</template>
|
||||
|
||||
<template #middle>
|
||||
<!-- Search field -->
|
||||
<Input ref="search-field" id="search" type="text" placeholder="Filtern" class="px-8 bg-background"
|
||||
v-model="searchQuery" />
|
||||
<span class="absolute start-0 inset-y-0 flex items-center justify-center px-2">
|
||||
<Search class="size-4 text-muted-foreground" />
|
||||
</span>
|
||||
<span class="absolute end-0 inset-y-0 flex items-center justify-center px-0 mr-1">
|
||||
<Button :size="'sm'" :variant="'ghost'" @click="searchQuery = ''; searchField.focus();">
|
||||
<Delete class="size-4 text-muted-foreground" />
|
||||
</Button>
|
||||
</span>
|
||||
</template>
|
||||
<template #right>
|
||||
<!-- New button -->
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<Button @click="">
|
||||
<Plus />
|
||||
Neu
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<span>Neue Lizenz anlegen</span>
|
||||
<KbdGroup class="ml-2">
|
||||
<Kbd class="visible-mac">⌘ N</Kbd>
|
||||
<Kbd class="visible-pc">Ctrl N</Kbd>
|
||||
</KbdGroup>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</template>
|
||||
</AppHeader>
|
||||
|
||||
<!-- License table -->
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead class="w-1/100 text-center">Gültig bis</TableHead>
|
||||
<TableHead>Produkt</TableHead>
|
||||
<TableHead>Version</TableHead>
|
||||
<TableHead colspan="2">Lizenznehmer</TableHead>
|
||||
<TableHead class="w-1/100 print:hidden"></TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
|
||||
<TableBody>
|
||||
|
||||
<TableRow v-for="license in filteredLicenses" :key="license.id">
|
||||
<TableCell class="text-center">
|
||||
<!-- <Check class="text-success inline-block" /> -->
|
||||
<Badge v-if="license.isPerpetual" variant="secondary">
|
||||
Permanent
|
||||
</Badge>
|
||||
<Badge v-else-if="Math.random() > 0.5" variant="success">
|
||||
{{ toLocalDate(license.expirationDate || '') }}
|
||||
</Badge>
|
||||
<Badge v-else variant="destructive">
|
||||
{{ toLocalDate(license.expirationDate || '') }}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{{ license.product }}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{{ license.version }}
|
||||
</TableCell>
|
||||
|
||||
<TableCell>
|
||||
{{ license.name }}<br />
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<a :href="'mailto:' + license.email + '?subject=Ihre ' + license.product + '-Lizenz'"
|
||||
class="text-muted-foreground text-sm">{{ license.email
|
||||
}}</a>
|
||||
</TableCell>
|
||||
|
||||
<TableCell class="print:hidden">
|
||||
<ButtonGroup>
|
||||
<Button size="icon" variant="ghost" @click="downloadLicense(license.id)">
|
||||
<Download class="text-muted-foreground" />
|
||||
</Button>
|
||||
<Button size="icon" variant="ghost" @click="deleteLicense(license.id)">
|
||||
<Trash2 class="text-muted-foreground" />
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</AppLayout>
|
||||
</template>
|
||||
Reference in New Issue
Block a user