forked from jsnbuchanan/crowd-funder-for-time-pwa
refactor: simplify logic for opening onboarding dialogs
This commit is contained in:
@@ -12,7 +12,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- Custom table area - you can customize this -->
|
<!-- Custom table area - you can customize this -->
|
||||||
<div v-if="shouldInitializeSelection" class="mb-4">
|
<div class="mb-4">
|
||||||
<table
|
<table
|
||||||
class="w-full border-collapse border border-slate-300 text-sm text-start"
|
class="w-full border-collapse border border-slate-300 text-sm text-start"
|
||||||
>
|
>
|
||||||
@@ -93,22 +93,9 @@
|
|||||||
? 'bg-green-600 text-white cursor-pointer'
|
? 'bg-green-600 text-white cursor-pointer'
|
||||||
: 'bg-slate-400 text-slate-200 cursor-not-allowed',
|
: 'bg-slate-400 text-slate-200 cursor-not-allowed',
|
||||||
]"
|
]"
|
||||||
@click="admitAndSetVisibility"
|
@click="admitWithVisibility"
|
||||||
>
|
>
|
||||||
Admit + Add Contacts
|
Admit + Add Contact
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
v-if="pendingMembersData && pendingMembersData.length > 0"
|
|
||||||
:disabled="!hasSelectedMembers"
|
|
||||||
:class="[
|
|
||||||
'block w-full text-center text-md font-bold uppercase px-2 py-2 rounded-md',
|
|
||||||
hasSelectedMembers
|
|
||||||
? 'bg-blue-600 text-white cursor-pointer'
|
|
||||||
: 'bg-slate-400 text-slate-200 cursor-not-allowed',
|
|
||||||
]"
|
|
||||||
@click="admitOnly"
|
|
||||||
>
|
|
||||||
Admit Only
|
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="block w-full text-center text-md font-bold uppercase bg-slate-600 text-white px-2 py-2 rounded-md"
|
class="block w-full text-center text-md font-bold uppercase bg-slate-600 text-white px-2 py-2 rounded-md"
|
||||||
@@ -143,7 +130,6 @@ interface PendingMemberData {
|
|||||||
mixins: [PlatformServiceMixin],
|
mixins: [PlatformServiceMixin],
|
||||||
})
|
})
|
||||||
export default class AdmitPendingMembersDialog extends Vue {
|
export default class AdmitPendingMembersDialog extends Vue {
|
||||||
@Prop({ default: false }) visible!: boolean;
|
|
||||||
@Prop({ default: () => [] }) pendingMembersData!: PendingMemberData[];
|
@Prop({ default: () => [] }) pendingMembersData!: PendingMemberData[];
|
||||||
@Prop({ default: "" }) activeDid!: string;
|
@Prop({ default: "" }) activeDid!: string;
|
||||||
@Prop({ default: "" }) apiServer!: string;
|
@Prop({ default: "" }) apiServer!: string;
|
||||||
@@ -159,7 +145,7 @@ export default class AdmitPendingMembersDialog extends Vue {
|
|||||||
|
|
||||||
// Component state
|
// Component state
|
||||||
selectedMembers: string[] = [];
|
selectedMembers: string[] = [];
|
||||||
selectionInitialized = false;
|
visible = false;
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
// In Vue templates, imported constants need to be explicitly made available to the template
|
// In Vue templates, imported constants need to be explicitly made available to the template
|
||||||
@@ -186,29 +172,23 @@ export default class AdmitPendingMembersDialog extends Vue {
|
|||||||
return selectedCount > 0 && selectedCount < this.pendingMembersData.length;
|
return selectedCount > 0 && selectedCount < this.pendingMembersData.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
get shouldInitializeSelection() {
|
|
||||||
// This method will initialize selection when the dialog opens
|
|
||||||
if (!this.selectionInitialized) {
|
|
||||||
this.initializeSelection();
|
|
||||||
this.selectionInitialized = true;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.notify = createNotifyHelpers(this.$notify);
|
this.notify = createNotifyHelpers(this.$notify);
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeSelection() {
|
open() {
|
||||||
// Reset selection when dialog opens
|
this.visible = true;
|
||||||
this.selectedMembers = [];
|
|
||||||
// Select all by default
|
// Select all by default
|
||||||
this.selectedMembers = this.pendingMembersData.map((member) => member.did);
|
this.selectedMembers = this.pendingMembersData.map((member) => member.did);
|
||||||
}
|
}
|
||||||
|
|
||||||
resetSelection() {
|
close(notSelectedMemberDids: string[]) {
|
||||||
this.selectedMembers = [];
|
this.visible = false;
|
||||||
this.selectionInitialized = false;
|
this.$emit("close", { notSelectedMemberDids: notSelectedMemberDids });
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
this.close(this.pendingMembersData.map((member) => member.did));
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSelectAll() {
|
toggleSelectAll() {
|
||||||
@@ -239,11 +219,14 @@ export default class AdmitPendingMembersDialog extends Vue {
|
|||||||
return this.selectedMembers.includes(memberDid);
|
return this.selectedMembers.includes(memberDid);
|
||||||
}
|
}
|
||||||
|
|
||||||
async admitAndSetVisibility() {
|
async admitWithVisibility() {
|
||||||
try {
|
try {
|
||||||
const selectedMembers = this.pendingMembersData.filter((member) =>
|
const selectedMembers = this.pendingMembersData.filter((member) =>
|
||||||
this.selectedMembers.includes(member.did),
|
this.selectedMembers.includes(member.did),
|
||||||
);
|
);
|
||||||
|
const notSelectedMembers = this.pendingMembersData.filter((member) =>
|
||||||
|
!this.selectedMembers.includes(member.did),
|
||||||
|
);
|
||||||
|
|
||||||
let admittedCount = 0;
|
let admittedCount = 0;
|
||||||
let contactAddedCount = 0;
|
let contactAddedCount = 0;
|
||||||
@@ -279,69 +262,10 @@ export default class AdmitPendingMembersDialog extends Vue {
|
|||||||
title: "Members Admitted Successfully",
|
title: "Members Admitted Successfully",
|
||||||
text: `Admitted ${admittedCount} member${admittedCount === 1 ? "" : "s"}, added ${contactAddedCount} as contact${contactAddedCount === 1 ? "" : "s"}, and set visibility for ${visibilitySetCount} member${visibilitySetCount === 1 ? "" : "s"}.`,
|
text: `Admitted ${admittedCount} member${admittedCount === 1 ? "" : "s"}, added ${contactAddedCount} as contact${contactAddedCount === 1 ? "" : "s"}, and set visibility for ${visibilitySetCount} member${visibilitySetCount === 1 ? "" : "s"}.`,
|
||||||
},
|
},
|
||||||
5000,
|
10000,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Emit success event
|
this.close(notSelectedMembers.map((member) => member.did));
|
||||||
this.$emit("success", {
|
|
||||||
admittedCount,
|
|
||||||
contactAddedCount,
|
|
||||||
visibilitySetCount,
|
|
||||||
});
|
|
||||||
this.close();
|
|
||||||
} catch (error) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error("Error admitting members:", error);
|
|
||||||
this.$notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "danger",
|
|
||||||
title: "Error",
|
|
||||||
text: "Failed to admit some members. Please try again.",
|
|
||||||
},
|
|
||||||
5000,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async admitOnly() {
|
|
||||||
try {
|
|
||||||
const selectedMembers = this.pendingMembersData.filter((member) =>
|
|
||||||
this.selectedMembers.includes(member.did),
|
|
||||||
);
|
|
||||||
|
|
||||||
let admittedCount = 0;
|
|
||||||
|
|
||||||
for (const member of selectedMembers) {
|
|
||||||
try {
|
|
||||||
// Just admit the member
|
|
||||||
await this.admitMember(member);
|
|
||||||
admittedCount++;
|
|
||||||
} catch (error) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.error(`Error admitting member ${member.did}:`, error);
|
|
||||||
// Continue with other members even if one fails
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show success notification
|
|
||||||
this.$notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "success",
|
|
||||||
title: "Members Admitted Successfully",
|
|
||||||
text: `Admitted ${admittedCount} member${admittedCount === 1 ? "" : "s"} to the meeting.`,
|
|
||||||
},
|
|
||||||
5000,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Emit success event
|
|
||||||
this.$emit("success", {
|
|
||||||
admittedCount,
|
|
||||||
contactAddedCount: 0,
|
|
||||||
visibilitySetCount: 0,
|
|
||||||
});
|
|
||||||
this.close();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error("Error admitting members:", error);
|
console.error("Error admitting members:", error);
|
||||||
@@ -433,15 +357,6 @@ export default class AdmitPendingMembersDialog extends Vue {
|
|||||||
5000,
|
5000,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
|
||||||
this.resetSelection();
|
|
||||||
this.$emit("close");
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel() {
|
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -179,21 +179,18 @@
|
|||||||
|
|
||||||
<!-- Admit Pending Members Dialog Component -->
|
<!-- Admit Pending Members Dialog Component -->
|
||||||
<AdmitPendingMembersDialog
|
<AdmitPendingMembersDialog
|
||||||
:visible="showAdmitPendingDialog"
|
ref="admitPendingMembersDialog"
|
||||||
|
:active-did="activeDid"
|
||||||
|
:api-server="apiServer"
|
||||||
:pending-members-data="pendingMembersData"
|
:pending-members-data="pendingMembersData"
|
||||||
:active-did="activeDid"
|
|
||||||
:api-server="apiServer"
|
|
||||||
@close="closeAdmitPendingDialog"
|
@close="closeAdmitPendingDialog"
|
||||||
@success="onAdmitPendingSuccess"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- Set Visibility Dialog Component -->
|
|
||||||
<SetBulkVisibilityDialog
|
<SetBulkVisibilityDialog
|
||||||
:visible="showSetVisibilityDialog"
|
:visible="visibleBulkVisibilityDialog"
|
||||||
:members-data="visibilityDialogMembers"
|
|
||||||
:active-did="activeDid"
|
:active-did="activeDid"
|
||||||
:api-server="apiServer"
|
:api-server="apiServer"
|
||||||
@close="closeSetVisibilityDialog"
|
:members-data="pendingMembersData"
|
||||||
|
@close="closeSetBulkVisibilityDialog"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -217,8 +214,8 @@ import {
|
|||||||
NOTIFY_CONTINUE_WITHOUT_ADDING,
|
NOTIFY_CONTINUE_WITHOUT_ADDING,
|
||||||
} from "@/constants/notifications";
|
} from "@/constants/notifications";
|
||||||
import { SOMEONE_UNNAMED } from "@/constants/entities";
|
import { SOMEONE_UNNAMED } from "@/constants/entities";
|
||||||
import SetBulkVisibilityDialog from "./SetBulkVisibilityDialog.vue";
|
|
||||||
import AdmitPendingMembersDialog from "./AdmitPendingMembersDialog.vue";
|
import AdmitPendingMembersDialog from "./AdmitPendingMembersDialog.vue";
|
||||||
|
import SetBulkVisibilityDialog from "./SetBulkVisibilityDialog.vue";
|
||||||
|
|
||||||
interface Member {
|
interface Member {
|
||||||
admitted: boolean;
|
admitted: boolean;
|
||||||
@@ -235,8 +232,8 @@ interface DecryptedMember {
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
SetBulkVisibilityDialog,
|
|
||||||
AdmitPendingMembersDialog,
|
AdmitPendingMembersDialog,
|
||||||
|
SetBulkVisibilityDialog,
|
||||||
},
|
},
|
||||||
mixins: [PlatformServiceMixin],
|
mixins: [PlatformServiceMixin],
|
||||||
})
|
})
|
||||||
@@ -255,6 +252,7 @@ export default class MembersList extends Vue {
|
|||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contacts: Array<Contact> = [];
|
||||||
decryptedMembers: DecryptedMember[] = [];
|
decryptedMembers: DecryptedMember[] = [];
|
||||||
firstName = "";
|
firstName = "";
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
@@ -266,32 +264,20 @@ export default class MembersList extends Vue {
|
|||||||
apiServer = "";
|
apiServer = "";
|
||||||
|
|
||||||
// Admit Pending Members Dialog state
|
// Admit Pending Members Dialog state
|
||||||
showAdmitPendingDialog = false;
|
|
||||||
pendingMembersData: Array<{
|
pendingMembersData: Array<{
|
||||||
did: string;
|
did: string;
|
||||||
name: string;
|
name: string;
|
||||||
isContact: boolean;
|
isContact: boolean;
|
||||||
member: { memberId: string };
|
member: { memberId: string };
|
||||||
}> = [];
|
}> = [];
|
||||||
admitDialogDismissed = false;
|
|
||||||
isManualRefresh = false;
|
|
||||||
|
|
||||||
// Set Visibility Dialog state
|
visibleBulkVisibilityDialog = false;
|
||||||
showSetVisibilityDialog = false;
|
|
||||||
visibilityDialogMembers: Array<{
|
|
||||||
did: string;
|
|
||||||
name: string;
|
|
||||||
isContact: boolean;
|
|
||||||
member: { memberId: string };
|
|
||||||
}> = [];
|
|
||||||
contacts: Array<Contact> = [];
|
|
||||||
|
|
||||||
// Auto-refresh functionality
|
// Auto-refresh functionality
|
||||||
countdownTimer = 10;
|
countdownTimer = 10;
|
||||||
autoRefreshInterval: NodeJS.Timeout | null = null;
|
autoRefreshInterval: NodeJS.Timeout | null = null;
|
||||||
|
lastRefreshTime = 0;
|
||||||
// Track previous visibility members to detect changes
|
previousMemberDidsIgnored: string[] = [];
|
||||||
previousVisibilityMembers: string[] = [];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the unnamed member constant
|
* Get the unnamed member constant
|
||||||
@@ -312,33 +298,18 @@ export default class MembersList extends Vue {
|
|||||||
|
|
||||||
this.apiServer = settings.apiServer || "";
|
this.apiServer = settings.apiServer || "";
|
||||||
this.firstName = settings.firstName || "";
|
this.firstName = settings.firstName || "";
|
||||||
await this.fetchMembers();
|
|
||||||
await this.loadContacts();
|
|
||||||
|
|
||||||
// Start auto-refresh
|
this.refreshData();
|
||||||
this.startAutoRefresh();
|
|
||||||
|
|
||||||
// Check if we should show the admit pending members dialog first
|
|
||||||
this.checkAndShowAdmitPendingDialog();
|
|
||||||
|
|
||||||
// If no pending members, check for visibility dialog
|
|
||||||
if (!this.showAdmitPendingDialog) {
|
|
||||||
this.checkAndShowVisibilityDialog();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async refreshData() {
|
async refreshData(showPendingEvenIfAllWereIgnored = false) {
|
||||||
// Force refresh both contacts and members
|
// Force refresh both contacts and members
|
||||||
await this.loadContacts();
|
this.contacts = await this.$getAllContacts()
|
||||||
|
|
||||||
await this.fetchMembers();
|
await this.fetchMembers();
|
||||||
|
|
||||||
// Check if we should show the admit pending members dialog first
|
// Check if we should show the admit pending members dialog first
|
||||||
this.checkAndShowAdmitPendingDialog();
|
this.checkAndShowAdmitPendingDialog(showPendingEvenIfAllWereIgnored);
|
||||||
|
|
||||||
// If no pending members, check for visibility dialog
|
|
||||||
if (!this.showAdmitPendingDialog) {
|
|
||||||
this.checkAndShowVisibilityDialog();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchMembers() {
|
async fetchMembers() {
|
||||||
@@ -487,15 +458,11 @@ export default class MembersList extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadContacts() {
|
|
||||||
this.contacts = await this.$getAllContacts();
|
|
||||||
}
|
|
||||||
|
|
||||||
getContactFor(did: string): Contact | undefined {
|
getContactFor(did: string): Contact | undefined {
|
||||||
return this.contacts.find((contact) => contact.did === did);
|
return this.contacts.find((contact) => contact.did === did);
|
||||||
}
|
}
|
||||||
|
|
||||||
getPendingMembers() {
|
getPendingMembers(): { did: string; name: string; isContact: boolean; member: { memberId: string; }; }[] {
|
||||||
return this.decryptedMembers
|
return this.decryptedMembers
|
||||||
.filter((member) => {
|
.filter((member) => {
|
||||||
// Exclude the current user
|
// Exclude the current user
|
||||||
@@ -515,132 +482,64 @@ export default class MembersList extends Vue {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
getMembersForVisibility() {
|
getNonContactMembers(): { did: string; name: string; isContact: boolean; member: { memberId: string; }; }[] {
|
||||||
const membersForVisibility = this.decryptedMembers
|
return this.decryptedMembers
|
||||||
.filter((member) => {
|
.filter((member) => !this.getContactFor(member.did))
|
||||||
// Exclude the current user
|
|
||||||
if (member.did === this.activeDid) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const contact = this.getContactFor(member.did);
|
|
||||||
|
|
||||||
// Include members who:
|
|
||||||
// 1. Haven't been added as contacts yet, OR
|
|
||||||
// 2. Are contacts but don't have visibility set (seesMe property)
|
|
||||||
return !contact || !contact.seesMe;
|
|
||||||
})
|
|
||||||
.map((member) => ({
|
.map((member) => ({
|
||||||
did: member.did,
|
did: member.did,
|
||||||
name: member.name,
|
name: member.name,
|
||||||
isContact: !!this.getContactFor(member.did),
|
isContact: false,
|
||||||
member: {
|
member: {
|
||||||
memberId: member.member.memberId.toString(),
|
memberId: member.member.memberId.toString(),
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Deduplicate members by DID to prevent duplicate entries
|
|
||||||
const uniqueMembers = membersForVisibility.filter(
|
|
||||||
(member, index, self) =>
|
|
||||||
index === self.findIndex((m) => m.did === member.did),
|
|
||||||
);
|
|
||||||
|
|
||||||
return uniqueMembers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if we should show the visibility dialog
|
|
||||||
* Returns true if there are members for visibility and either:
|
|
||||||
* - This is the first time (no previous members tracked), OR
|
|
||||||
* - New members have been added since last check (not removed), OR
|
|
||||||
* - This is a manual refresh (isManualRefresh flag is set)
|
|
||||||
*/
|
|
||||||
shouldShowVisibilityDialog(): boolean {
|
|
||||||
// Only show for members who can see other members (i.e., they are in the decrypted members list)
|
|
||||||
const currentUserMember = this.decryptedMembers.find(
|
|
||||||
(member) => member.did === this.activeDid,
|
|
||||||
);
|
|
||||||
|
|
||||||
// If the current user is not in the decrypted members list, they can't see anyone
|
|
||||||
if (!currentUserMember) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentMembers = this.getMembersForVisibility();
|
|
||||||
|
|
||||||
if (currentMembers.length === 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If no previous members tracked, show dialog
|
|
||||||
if (this.previousVisibilityMembers.length === 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is a manual refresh, always show dialog if there are members
|
|
||||||
if (this.isManualRefresh) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if new members have been added (not just any change)
|
|
||||||
const currentMemberIds = currentMembers.map((m) => m.did);
|
|
||||||
const previousMemberIds = this.previousVisibilityMembers;
|
|
||||||
|
|
||||||
// Find new members (members in current but not in previous)
|
|
||||||
const newMembers = currentMemberIds.filter(
|
|
||||||
(id) => !previousMemberIds.includes(id),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Only show dialog if there are new members added
|
|
||||||
return newMembers.length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the tracking of previous visibility members
|
|
||||||
*/
|
|
||||||
updatePreviousVisibilityMembers() {
|
|
||||||
const currentMembers = this.getMembersForVisibility();
|
|
||||||
this.previousVisibilityMembers = currentMembers.map((m) => m.did);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if we should show the admit pending members dialog
|
|
||||||
*/
|
|
||||||
shouldShowAdmitPendingDialog(): boolean {
|
|
||||||
// Don't show if already dismissed
|
|
||||||
if (this.admitDialogDismissed) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only show for the organizer of the meeting
|
|
||||||
if (!this.isOrganizer) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const pendingMembers = this.getPendingMembers();
|
|
||||||
return pendingMembers.length > 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the admit pending members dialog if conditions are met
|
* Show the admit pending members dialog if conditions are met
|
||||||
*/
|
*/
|
||||||
checkAndShowAdmitPendingDialog() {
|
checkAndShowAdmitPendingDialog(showPendingEvenIfAllWereIgnored = false) {
|
||||||
if (this.shouldShowAdmitPendingDialog()) {
|
const pendingMembers =
|
||||||
this.showAdmitPendingDialogMethod();
|
this.isOrganizer ? this.getPendingMembers() : this.getNonContactMembers();
|
||||||
|
if (pendingMembers.length === 0) {
|
||||||
|
this.startAutoRefresh();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!showPendingEvenIfAllWereIgnored) {
|
||||||
|
// only show if there are pending members that have not been ignored
|
||||||
|
const pendingMembersNotIgnored =
|
||||||
|
pendingMembers.filter(
|
||||||
|
(member) => !this.previousMemberDidsIgnored.includes(member.did)
|
||||||
|
);
|
||||||
|
if (pendingMembersNotIgnored.length === 0) {
|
||||||
|
this.startAutoRefresh();
|
||||||
|
// everyone waiting has been ignored
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.stopAutoRefresh();
|
||||||
|
this.pendingMembersData = pendingMembers;
|
||||||
|
if (this.isOrganizer) {
|
||||||
|
(this.$refs.admitPendingMembersDialog as AdmitPendingMembersDialog).open();
|
||||||
} else {
|
} else {
|
||||||
// Ensure dialog state is false when no pending members
|
this.visibleBulkVisibilityDialog = true;
|
||||||
this.showAdmitPendingDialog = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Admit Pending Members Dialog methods
|
||||||
* Show the visibility dialog if conditions are met
|
async closeAdmitPendingDialog(result: { notSelectedMemberDids: string[] } | undefined) {
|
||||||
*/
|
this.pendingMembersData = [];
|
||||||
checkAndShowVisibilityDialog() {
|
this.previousMemberDidsIgnored = result?.notSelectedMemberDids || [];
|
||||||
if (this.shouldShowVisibilityDialog()) {
|
|
||||||
this.showSetBulkVisibilityDialog();
|
await this.refreshData();
|
||||||
}
|
}
|
||||||
this.updatePreviousVisibilityMembers();
|
|
||||||
|
async closeSetBulkVisibilityDialog(result: { notSelectedMemberDids: string[] } | undefined) {
|
||||||
|
this.visibleBulkVisibilityDialog = false;
|
||||||
|
this.pendingMembersData = [];
|
||||||
|
this.previousMemberDidsIgnored = result?.notSelectedMemberDids || [];
|
||||||
|
|
||||||
|
await this.refreshData();
|
||||||
}
|
}
|
||||||
|
|
||||||
checkWhetherContactBeforeAdmitting(decrMember: DecryptedMember) {
|
checkWhetherContactBeforeAdmitting(decrMember: DecryptedMember) {
|
||||||
@@ -781,51 +680,19 @@ export default class MembersList extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showAdmitPendingDialogMethod() {
|
|
||||||
// Filter members to show only pending (non-admitted) members
|
|
||||||
const pendingMembers = this.getPendingMembers();
|
|
||||||
|
|
||||||
// Only show dialog if there are pending members
|
|
||||||
if (pendingMembers.length === 0) {
|
|
||||||
this.showAdmitPendingDialog = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pause auto-refresh when dialog opens
|
|
||||||
this.stopAutoRefresh();
|
|
||||||
|
|
||||||
// Open the dialog directly
|
|
||||||
this.pendingMembersData = pendingMembers;
|
|
||||||
this.showAdmitPendingDialog = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
showSetBulkVisibilityDialog() {
|
|
||||||
// Filter members to show only those who need visibility set
|
|
||||||
const membersForVisibility = this.getMembersForVisibility();
|
|
||||||
|
|
||||||
// Pause auto-refresh when dialog opens
|
|
||||||
this.stopAutoRefresh();
|
|
||||||
|
|
||||||
// Open the dialog directly
|
|
||||||
this.visibilityDialogMembers = membersForVisibility;
|
|
||||||
this.showSetVisibilityDialog = true;
|
|
||||||
|
|
||||||
// Reset manual refresh flag after dialog is shown
|
|
||||||
this.isManualRefresh = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
startAutoRefresh() {
|
startAutoRefresh() {
|
||||||
let lastRefreshTime = Date.now();
|
this.lastRefreshTime = Date.now();
|
||||||
this.countdownTimer = 10;
|
this.countdownTimer = 10;
|
||||||
|
|
||||||
this.autoRefreshInterval = setInterval(() => {
|
this.autoRefreshInterval = setInterval(() => {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const timeSinceLastRefresh = (now - lastRefreshTime) / 1000;
|
const timeSinceLastRefresh = (now - this.lastRefreshTime) / 1000;
|
||||||
|
|
||||||
if (timeSinceLastRefresh >= 10) {
|
if (timeSinceLastRefresh >= 10) {
|
||||||
// Time to refresh
|
// Time to refresh
|
||||||
this.refreshData();
|
this.refreshData();
|
||||||
lastRefreshTime = now;
|
this.lastRefreshTime = now;
|
||||||
this.countdownTimer = 10;
|
this.countdownTimer = 10;
|
||||||
} else {
|
} else {
|
||||||
// Update countdown
|
// Update countdown
|
||||||
@@ -851,68 +718,8 @@ export default class MembersList extends Vue {
|
|||||||
this.autoRefreshInterval = null;
|
this.autoRefreshInterval = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set manual refresh flag
|
|
||||||
this.isManualRefresh = true;
|
|
||||||
// Reset the dismissed flag on manual refresh
|
|
||||||
this.admitDialogDismissed = false;
|
|
||||||
|
|
||||||
// Trigger immediate refresh
|
// Trigger immediate refresh
|
||||||
await this.refreshData();
|
await this.refreshData(true);
|
||||||
|
|
||||||
// Only start auto-refresh if no dialogs are showing
|
|
||||||
if (!this.showAdmitPendingDialog && !this.showSetVisibilityDialog) {
|
|
||||||
this.startAutoRefresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Admit Pending Members Dialog methods
|
|
||||||
async closeAdmitPendingDialog() {
|
|
||||||
this.showAdmitPendingDialog = false;
|
|
||||||
this.pendingMembersData = [];
|
|
||||||
this.admitDialogDismissed = true;
|
|
||||||
|
|
||||||
// Handle manual refresh flow
|
|
||||||
if (this.isManualRefresh) {
|
|
||||||
await this.handleManualRefreshFlow();
|
|
||||||
this.isManualRefresh = false;
|
|
||||||
} else {
|
|
||||||
// Normal flow: refresh data and resume auto-refresh
|
|
||||||
this.refreshData();
|
|
||||||
this.startAutoRefresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async handleManualRefreshFlow() {
|
|
||||||
// Refresh data to reflect any changes made in the admit dialog
|
|
||||||
await this.refreshData();
|
|
||||||
|
|
||||||
// Use the same logic as normal flow to check for visibility dialog
|
|
||||||
this.checkAndShowVisibilityDialog();
|
|
||||||
|
|
||||||
// If no visibility dialog was shown, resume auto-refresh
|
|
||||||
if (!this.showSetVisibilityDialog) {
|
|
||||||
this.startAutoRefresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async onAdmitPendingSuccess(_result: {
|
|
||||||
admittedCount: number;
|
|
||||||
contactAddedCount: number;
|
|
||||||
visibilitySetCount: number;
|
|
||||||
}) {
|
|
||||||
// After admitting pending members, close the admit dialog
|
|
||||||
// The visibility dialog will be handled by the closeAdmitPendingDialog flow
|
|
||||||
await this.closeAdmitPendingDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Visibility Dialog methods
|
|
||||||
closeSetVisibilityDialog() {
|
|
||||||
this.showSetVisibilityDialog = false;
|
|
||||||
this.visibilityDialogMembers = [];
|
|
||||||
// Refresh data when dialog is closed to reflect any changes made
|
|
||||||
this.refreshData();
|
|
||||||
// Resume auto-refresh when dialog is closed
|
|
||||||
this.startAutoRefresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
|
|||||||
@@ -213,6 +213,9 @@ export default class SetBulkVisibilityDialog extends Vue {
|
|||||||
const selectedMembers = this.membersData.filter((member) =>
|
const selectedMembers = this.membersData.filter((member) =>
|
||||||
this.selectedMembers.includes(member.did),
|
this.selectedMembers.includes(member.did),
|
||||||
);
|
);
|
||||||
|
const notSelectedMembers = this.membersData.filter((member) =>
|
||||||
|
!this.selectedMembers.includes(member.did),
|
||||||
|
);
|
||||||
|
|
||||||
let successCount = 0;
|
let successCount = 0;
|
||||||
|
|
||||||
@@ -246,7 +249,7 @@ export default class SetBulkVisibilityDialog extends Vue {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Emit success event
|
// Emit success event
|
||||||
this.$emit("success", successCount);
|
this.$emit("close", { notSelectedMemberDids: notSelectedMembers.map((member) => member.did) });
|
||||||
this.close();
|
this.close();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
@@ -323,7 +326,7 @@ export default class SetBulkVisibilityDialog extends Vue {
|
|||||||
|
|
||||||
close() {
|
close() {
|
||||||
this.resetSelection();
|
this.resetSelection();
|
||||||
this.$emit("close");
|
this.$emit("close", { notSelectedMemberDids: this.membersData.map((member) => member.did) });
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
|
|||||||
@@ -77,7 +77,7 @@
|
|||||||
v-if="meetings.length === 0 && !isRegistered"
|
v-if="meetings.length === 0 && !isRegistered"
|
||||||
class="text-center text-gray-500 py-8"
|
class="text-center text-gray-500 py-8"
|
||||||
>
|
>
|
||||||
No onboarding meetings available
|
No onboarding meetings are available
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user