Add new vue-based frontend

This commit is contained in:
2025-07-05 16:00:29 +02:00
parent c7ecc3f365
commit 3ef659be61
73 changed files with 14431 additions and 0 deletions

View File

@ -0,0 +1,139 @@
<template>
<div class="flex justify-end px-4">
<sl-dropdown>
<div slot="trigger">
<sl-icon-button name="three-dots"></sl-icon-button>
</div>
<sl-menu>
<sl-menu-item value="edit" @click="updateDrawerOpen = true"> Edit client </sl-menu-item>
<sl-menu-item value="delete">
<span class="text-red-600" @click="showConfirm = true">Delete client</span>
</sl-menu-item>
</sl-menu>
</sl-dropdown>
</div>
<sl-tab-group>
<sl-tab slot="nav" panel="client_data">Client Data</sl-tab>
<sl-tab slot="nav" panel="events">Events</sl-tab>
<sl-tab-panel name="client_data">
<div id="client_details">
<div class="w-full p-2">
<div class="px-4 sm:px-0">
<h3 class="text-base/7 font-semibold text-gray-900 dark:text-gray-50">
{{ localClient.name }}
</h3>
<p
class="mt-1 max-w-2xl text-sm/6 text-gray-500 dark:text-gray-100"
v-if="localClient.description"
>
{{ localClient.description }}
</p>
</div>
<div class="mt-6 border-t border-gray-100">
<dl class="divide-y divide-gray-100">
<div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm/6 font-medium text-gray-900 dark:text-gray-200">Client ID</dt>
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300">
{{ localClient.id }}
</dd>
</div>
<div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm/6 font-medium text-gray-900 dark:text-gray-200">
Client Description
</dt>
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300">
{{ localClient.description }}
</dd>
</div>
<div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm/6 font-medium text-gray-900 dark:text-gray-200">
Client Version
</dt>
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300">
{{ localClient.version }}
</dd>
</div>
<div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm/6 font-medium text-gray-900 dark:text-gray-200">Public Key</dt>
<dd
class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300 truncate"
>
{{ localClient.public_key }}
</dd>
</div>
<div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm/6 font-medium text-gray-900 dark:text-gray-200">
Assigned Secrets
</dt>
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300">
{{ clientSecretCount }}
</dd>
</div>
<div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm/6 font-medium text-gray-900 dark:text-gray-200">
Allowed sources
</dt>
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300">
{{ clientPolicies }}
</dd>
</div>
</dl>
</div>
</div>
</div>
</sl-tab-panel>
<sl-tab-panel name="events"> </sl-tab-panel>
</sl-tab-group>
<sl-drawer label="Edit Client" :open="updateDrawerOpen" @sl-hide="updateDrawerOpen = false">
<ClientForm @submit="updateClient" @cancel="updateDrawerOpen = false" :client="client" />
</sl-drawer>
<sl-dialog label="Are you sure?" :open="showConfirm">
Are you sure you want to delete this client?
<div slot="footer">
<sl-button variant="default" @click="showConfirm = false" class="mr-2">Cancel</sl-button>
<sl-button variant="danger" @click="deleteClient">Delete</sl-button>
</div>
</sl-dialog>
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import type { Client, ClientCreate } from '@/client/types.gen'
import '@shoelace-style/shoelace/dist/components/button/button.js'
import '@shoelace-style/shoelace/dist/components/dialog/dialog.js'
import '@shoelace-style/shoelace/dist/components/divider/divider.js'
import '@shoelace-style/shoelace/dist/components/drawer/drawer.js'
import '@shoelace-style/shoelace/dist/components/dropdown/dropdown.js'
import '@shoelace-style/shoelace/dist/components/icon-button/icon-button.js'
import '@shoelace-style/shoelace/dist/components/menu/menu.js'
import '@shoelace-style/shoelace/dist/components/menu-item/menu-item.js'
import '@shoelace-style/shoelace/dist/components/menu-label/menu-label.js'
import '@shoelace-style/shoelace/dist/components/tab-panel/tab-panel.js'
import '@shoelace-style/shoelace/dist/components/tab-group/tab-group.js'
import '@shoelace-style/shoelace/dist/components/tab/tab.js'
import ClientForm from '@/components/clients/ClientForm.vue'
const props = defineProps<{ client: Client }>()
const emit = defineEmits<{
(e: 'update', data: ClientCreate): void
(e: 'deleted', data: string): void
}>()
const localClient = ref({ ...props.client })
const updateDrawerOpen = ref<boolean>(false)
const showConfirm = ref<boolean>(false)
const clientSecretCount = computed(() => localClient.value.secrets.length)
const clientPolicies = computed(() => localClient.value.policies.join(', '))
async function updateClient(data: ClientCreate) {
emit('update', data)
updateDrawerOpen.value = false
}
async function deleteClient() {
showConfirm.value = false
emit('deleted', localClient.value.id)
}
</script>