split out group-meeting member list into a separate component, and fix some edit/create mode titles

This commit is contained in:
2025-02-03 14:30:49 -07:00
parent 40765feea1
commit 31d573684a
4 changed files with 175 additions and 110 deletions

View File

@@ -0,0 +1,107 @@
<template>
<div class="space-y-4">
<!-- Loading State -->
<div v-if="isLoading" class="flex justify-center items-center py-8">
<fa icon="spinner" class="fa-spin-pulse" />
</div>
<!-- Members List -->
<div v-else class="space-y-4">
<div v-for="member in decryptedMembers" :key="member.memberId"
class="p-4 bg-gray-50 rounded-lg">
<h3 class="text-lg font-medium">{{ member.name }}</h3>
<p class="text-sm text-gray-600">{{ member.did }}</p>
</div>
<p v-if="members.length === 0" class="text-center text-gray-500 py-4">
No members have joined this meeting yet
</p>
<p v-if="decryptedMembers.length < members.length" class="text-center text-red-600 py-4">
{{ decryptFailureMessage || "Your password failed. Please go back and try again." }}
</p>
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue, Prop } from 'vue-facing-decorator';
import { logConsoleAndDb, retrieveSettingsForActiveAccount } from '@/db/index';
import { errorStringForLog, getHeaders, serverMessageForUser } from '@/libs/endorserServer';
import { decryptMessage } from '@/libs/crypto';
interface Member {
memberId: number;
content: string;
}
interface DecryptedMember {
memberId: number;
name: string;
did: string;
}
@Component
export default class MembersList extends Vue {
@Prop({ required: true }) password!: string;
@Prop({ default: 'Your password failed. Please go back and try again.' }) decryptFailureMessage!: string;
decryptedMembers: DecryptedMember[] = [];
missingPassword = false;
isLoading = false;
members: Member[] = [];
activeDid = '';
apiServer = '';
async created() {
const settings = await retrieveSettingsForActiveAccount();
this.activeDid = settings.activeDid || '';
this.apiServer = settings.apiServer || '';
await this.fetchMembers();
}
async fetchMembers() {
this.isLoading = true;
try {
const headers = await getHeaders(this.activeDid);
const response = await this.axios.get(
`${this.apiServer}/api/partner/groupOnboardMembers/`,
{ headers }
);
if (response.data && response.data.data) {
this.members = response.data.data;
await this.decryptMemberContents();
}
} catch (error) {
logConsoleAndDb('Error fetching members: ' + errorStringForLog(error), true);
this.$emit('error', serverMessageForUser(error) || 'Failed to fetch members.');
} finally {
this.isLoading = false;
}
}
async decryptMemberContents() {
this.decryptedMembers = [];
if (!this.password) {
this.missingPassword = true;
return;
}
for (const member of this.members) {
try {
const decryptedContent = await decryptMessage(member.content, this.password);
const content = JSON.parse(decryptedContent);
this.decryptedMembers.push({
memberId: member.memberId,
name: content.name,
did: content.did,
});
} catch (error) {
// do nothing, relying on the count of members to determine if there was an error
}
}
}
}
</script>