feat(communication): federate tenant collaboration with signed delivery
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
const { $api } = useNuxtApp()
|
||||
const route = useRoute()
|
||||
const state = ref({ rooms: [], invitations: [], managedRooms: [], projects: [], canManage: false, contact: '' })
|
||||
const contacts = ref([]), selected = ref(''), error = ref(''), busy = ref(false), creating = ref(false), showCreate = ref(false), showManagement = ref(false)
|
||||
const contacts = ref([]), selected = ref(''), error = ref(''), busy = ref(false), showCreate = ref(false), showManagement = ref(false)
|
||||
const management = ref({ members: [], invitations: [] }), inviteResult = ref(null)
|
||||
const create = reactive({ name: '', topic: '', projectId: String(route.query.project || '') })
|
||||
const invite = reactive({ kind: 'user', userId: '', name: '', email: '', contact: '', role: 'participant', overviewAllowed: false, expiresAt: '', sendEmail: true })
|
||||
@@ -92,7 +92,8 @@ onBeforeUnmount(() => clearInterval(timer))
|
||||
<section v-if="federation" class="rounded-xl border border-gray-200 p-4 dark:border-gray-700">
|
||||
<div class="flex justify-between"><h2 class="font-semibold">Freigegebene Partnerinstanzen</h2><button @click="federation = null">Schließen</button></div>
|
||||
<p class="my-2 text-sm text-gray-500">Beide Firmen geben die jeweils andere Instanz frei. Einzelne Personen erhalten anschließend eine eigene Einladung.</p>
|
||||
<form class="flex flex-wrap gap-2" @submit.prevent="savePartner(partnerUrl)"><label class="flex-1"><span class="sr-only">Adresse der Partnerinstanz</span><input v-model="partnerUrl" type="url" required placeholder="https://partner.example/backend" class="field" /></label><UButton type="submit" :loading="busy">Partner freigeben</UButton></form>
|
||||
<p v-if="!federation.enabled" class="my-2 text-sm text-amber-700">Die Föderation muss zuerst vom Betreiber aktiviert werden.</p>
|
||||
<form v-if="federation.enabled" class="flex flex-wrap gap-2" @submit.prevent="savePartner(partnerUrl)"><label class="flex-1"><span class="sr-only">Adresse der Partnerinstanz</span><input v-model="partnerUrl" type="url" required placeholder="https://partner.example/backend" class="field" /></label><UButton type="submit" :loading="busy">Partner freigeben</UButton></form>
|
||||
<div v-for="partner in federation.partners" :key="partner.origin" class="mt-3 flex items-center justify-between gap-3 text-sm"><span>{{ partner.origin }} · {{ partner.active ? 'Freigegeben' : 'Gesperrt' }}</span><UButton variant="outline" size="xs" :disabled="busy" @click="savePartner(partner.origin, !partner.active)">{{ partner.active ? 'Sperren' : 'Freigeben' }}</UButton></div>
|
||||
</section>
|
||||
<form v-if="showCreate" class="grid gap-3 rounded-xl border border-gray-200 p-4 sm:grid-cols-2 dark:border-gray-700" @submit.prevent="createRoom">
|
||||
@@ -144,7 +145,7 @@ onBeforeUnmount(() => clearInterval(timer))
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="management.invitations.some(i => i.status === 'pending')" class="space-y-2"><h3 class="font-semibold">Offene Einladungen</h3><div v-for="item in management.invitations.filter(i => i.status === 'pending')" :key="item.id" class="flex items-center justify-between gap-2 text-sm"><span>{{ item.name }} · bis {{ new Date(item.expiresAt).toLocaleDateString('de-DE') }}</span><UButton variant="outline" size="xs" :disabled="busy" @click="revoke(item.id, true)">Widerrufen</UButton></div></div>
|
||||
<div v-if="management.invitations.some(i => i.status === 'pending')" class="space-y-2"><h3 class="font-semibold">Offene Einladungen</h3><div v-for="item in management.invitations.filter(i => i.status === 'pending')" :key="item.id" class="flex items-center justify-between gap-2 text-sm"><span>{{ item.name }} · bis {{ new Date(item.expiresAt).toLocaleDateString('de-DE') }}<span v-if="item.delivery" class="block text-xs">{{ item.delivery.status === 'sent' ? 'Bei Partnerinstanz zugestellt' : item.delivery.status === 'failed' ? 'Zustellung fehlgeschlagen' : 'Wartet auf Zustellung' }}</span></span><UButton v-if="item.delivery?.status === 'failed'" variant="outline" size="xs" :disabled="busy" @click="run(async () => { await $api(`/api/collaboration/rooms/${selected}/invitations/${item.id}/retry`, { method: 'POST' }); await loadManagement() })">Erneut zustellen</UButton><UButton variant="outline" size="xs" :disabled="busy" @click="revoke(item.id, true)">Widerrufen</UButton></div></div>
|
||||
<form class="space-y-3 border-t border-gray-200 pt-4 dark:border-gray-700" @submit.prevent="saveRoom">
|
||||
<h3 class="font-semibold">Unterraum und freigegebene Informationen</h3>
|
||||
<label class="block text-sm">Raumname<input v-model="details.name" required maxlength="160" class="field" /></label>
|
||||
|
||||
Reference in New Issue
Block a user