refactor: unify member dialogs into reusable BulkMembersDialog component

- Merge AdmitPendingMembersDialog and SetBulkVisibilityDialog into single BulkMembersDialog
- Add dynamic props for dialog type, title, description, button text, and empty state
- Support both 'admit' and 'visibility' modes with conditional behavior
- Rename setVisibilityForSelectedMembers to addContactWithVisibility for clarity
- Update success counting to track contacts added vs visibility set
- Improve error messages to reflect primary action of adding contacts
- Update MembersList to use unified dialog with role-based configuration
- Remove unused libsUtil import from MembersList
- Update comments and method names to reflect unified functionality
- Rename closeMemberSelectionDialogCallback to closeBulkMembersDialogCallback

This consolidation eliminates ~200 lines of duplicate code while maintaining
all existing functionality and improving maintainability through a single
source of truth for bulk member operations.
This commit is contained in:
Jose Olarte III
2025-10-29 18:21:32 +08:00
parent 7b87ab2a5c
commit b37051f25d
3 changed files with 114 additions and 368 deletions

View File

@@ -197,22 +197,25 @@
</div>
</div>
<!-- This Admit component is for the organizer to admit pending members to the meeting -->
<AdmitPendingMembersDialog
ref="admitPendingMembersDialog"
<!-- Bulk Members Dialog for both admitting and setting visibility -->
<BulkMembersDialog
ref="bulkMembersDialog"
:active-did="activeDid"
:api-server="apiServer"
@close="closeMemberSelectionDialogCallback"
/>
<!--
This Bulk Visibility component is for non-organizer members
to add other members to their contacts and set their visibility
-->
<SetBulkVisibilityDialog
ref="setBulkVisibilityDialog"
:active-did="activeDid"
:api-server="apiServer"
@close="closeMemberSelectionDialogCallback"
:dialog-type="isOrganizer ? 'admit' : 'visibility'"
:title="isOrganizer ? 'Admit Pending Members' : 'Add Members to Contacts'"
:description="
isOrganizer
? 'Would you like to admit these members to the meeting and add them to your contacts?'
: 'Would you like to add these members to your contacts?'
"
:button-text="isOrganizer ? 'Admit + Add to Contacts' : 'Add to Contacts'"
:empty-state-text="
isOrganizer
? 'No pending members to admit'
: 'No members are not in your contacts'
"
@close="closeBulkMembersDialogCallback"
/>
</div>
</template>
@@ -235,11 +238,9 @@ import {
import { decryptMessage } from "@/libs/crypto";
import { Contact } from "@/db/tables/contacts";
import { MemberData } from "@/interfaces";
import * as libsUtil from "@/libs/util";
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin";
import { createNotifyHelpers, TIMEOUTS } from "@/utils/notify";
import AdmitPendingMembersDialog from "./AdmitPendingMembersDialog.vue";
import SetBulkVisibilityDialog from "./SetBulkVisibilityDialog.vue";
import BulkMembersDialog from "./BulkMembersDialog.vue";
interface Member {
admitted: boolean;
@@ -256,8 +257,7 @@ interface DecryptedMember {
@Component({
components: {
AdmitPendingMembersDialog,
SetBulkVisibilityDialog,
BulkMembersDialog,
},
mixins: [PlatformServiceMixin],
})
@@ -265,7 +265,6 @@ export default class MembersList extends Vue {
$notify!: (notification: NotificationIface, timeout?: number) => void;
notify!: ReturnType<typeof createNotifyHelpers>;
libsUtil = libsUtil;
@Prop({ required: true }) password!: string;
@Prop({ default: false }) showOrganizerTools!: boolean;
@@ -532,7 +531,8 @@ export default class MembersList extends Vue {
}
/**
* Show the admit pending members dialog if conditions are met
* Show the bulk members dialog if conditions are met
* (admit pending members for organizers, add to contacts for non-organizers)
*/
async refreshData(bypassPromptIfAllWereIgnored = true) {
// Force refresh both contacts and members
@@ -547,7 +547,7 @@ export default class MembersList extends Vue {
return;
}
if (bypassPromptIfAllWereIgnored) {
// only show if there are pending members that have not been ignored
// only show if there are members that have not been ignored
const pendingMembersNotIgnored = pendingMembers.filter(
(member) => !this.previousMemberDidsIgnored.includes(member.did),
);
@@ -558,19 +558,11 @@ export default class MembersList extends Vue {
}
}
this.stopAutoRefresh();
if (this.isOrganizer) {
(this.$refs.admitPendingMembersDialog as AdmitPendingMembersDialog).open(
pendingMembers,
);
} else {
(this.$refs.setBulkVisibilityDialog as SetBulkVisibilityDialog).open(
pendingMembers,
);
}
(this.$refs.bulkMembersDialog as BulkMembersDialog).open(pendingMembers);
}
// Admit Pending Members Dialog methods
async closeMemberSelectionDialogCallback(
// Bulk Members Dialog methods
async closeBulkMembersDialogCallback(
result: { notSelectedMemberDids: string[] } | undefined,
) {
this.previousMemberDidsIgnored = result?.notSelectedMemberDids || [];