2
2
<div >
3
3
<div
4
4
v-if =" loading"
5
- v-loading =" loading"
6
- class =" app-page-spinner h-16 !relative !min-h-5"
7
- />
5
+ class =" h-16 !relative !min-h-5 flex justify-center items-center"
6
+ >
7
+ <div class =" animate-spin w-fit" >
8
+ <div class =" custom-spinner" />
9
+ </div >
10
+ </div >
8
11
<div v-else >
9
12
<!-- Empty State -->
10
13
<app-empty-state-cta
408
411
class =" block w-full"
409
412
>
410
413
<div class =" h-full flex items-center justify-center w-full" >
411
- <app-member-dropdown
412
- :member =" scope.row"
413
- @merge =" isMergeDialogOpen = scope.row"
414
- />
414
+ <button
415
+ :id =" `buttonRef-${scope.row.id}`"
416
+ :ref =" (el) => setActionBtnsRef(el, scope.row.id)"
417
+ class =" el-dropdown-link btn p-1.5 rounder-md hover:bg-gray-200 text-gray-600"
418
+ type =" button"
419
+ @click.prevent.stop =" () => onActionBtnClick(scope.row)"
420
+ >
421
+ <i
422
+ :id =" `buttonRefIcon-${scope.row.id}`"
423
+ class =" text-xl ri-more-fill"
424
+ />
425
+ </button >
415
426
</div >
416
427
</router-link >
417
428
</template >
432
443
</div >
433
444
</div >
434
445
</div >
446
+ <el-popover
447
+ ref =" memberDropdownPopover"
448
+ placement =" bottom-end"
449
+ popper-class =" popover-dropdown"
450
+ :virtual-ref =" actionBtnRefs[selectedActionMember?.id]"
451
+ trigger =" click"
452
+ :visible =" showMemberDropdownPopover"
453
+ virtual-triggering
454
+ @hide =" onHide"
455
+ >
456
+ <div v-click-outside =" onClickOutside" >
457
+ <app-member-dropdown-content
458
+ v-if =" selectedActionMember"
459
+ :member =" selectedActionMember"
460
+ @merge =" isMergeDialogOpen = selectedActionMember"
461
+ @close-dropdown =" closeDropdown"
462
+ />
463
+ </div >
464
+ </el-popover >
435
465
<app-member-merge-dialog v-model =" isMergeDialogOpen" />
436
466
<app-tag-popover v-model =" isEditTagsDialogOpen" :member =" editTagMember" @reload =" fetchMembers({ reload: true })" />
437
467
</div >
@@ -443,6 +473,7 @@ import { useRouter } from 'vue-router';
443
473
import {
444
474
computed , onMounted , onUnmounted , ref , defineProps , watch ,
445
475
} from ' vue' ;
476
+ import { ClickOutside as vClickOutside } from ' element-plus' ;
446
477
import { storeToRefs } from ' pinia' ;
447
478
import { i18n } from ' @/i18n' ;
448
479
import AppMemberListToolbar from ' @/modules/member/components/list/member-list-toolbar.vue' ;
@@ -456,7 +487,7 @@ import AppMemberMergeDialog from '@/modules/member/components/member-merge-dialo
456
487
import AppTagPopover from ' @/modules/tag/components/tag-popover.vue' ;
457
488
import AppPagination from ' @/shared/pagination/pagination.vue' ;
458
489
import AppMemberBadge from ' ../member-badge.vue' ;
459
- import AppMemberDropdown from ' ../member-dropdown.vue' ;
490
+ import AppMemberDropdownContent from ' ../member-dropdown-content .vue' ;
460
491
import AppMemberIdentities from ' ../member-identities.vue' ;
461
492
import AppMemberReach from ' ../member-reach.vue' ;
462
493
import AppMemberEngagementLevel from ' ../member-engagement-level.vue' ;
@@ -477,6 +508,11 @@ const isMergeDialogOpen = ref(null);
477
508
const isEditTagsDialogOpen = ref (false );
478
509
const editTagMember = ref (null );
479
510
511
+ const showMemberDropdownPopover = ref (false );
512
+ const memberDropdownPopover = ref (null );
513
+ const actionBtnRefs = ref ({});
514
+ const selectedActionMember = ref (null );
515
+
480
516
const props = defineProps ({
481
517
hasIntegrations: {
482
518
type: Boolean ,
@@ -578,6 +614,39 @@ document.onmouseup = () => {
578
614
isCursorDown .value = false ;
579
615
};
580
616
617
+ const setActionBtnsRef = (el , id ) => {
618
+ if (el) {
619
+ actionBtnRefs .value [id] = el;
620
+ }
621
+ };
622
+
623
+ const onActionBtnClick = (member ) => {
624
+ if (selectedActionMember .value ? .id === member .id ) {
625
+ showMemberDropdownPopover .value = false ;
626
+
627
+ setTimeout (() => {
628
+ selectedActionMember .value = null ;
629
+ }, 200 );
630
+ } else {
631
+ showMemberDropdownPopover .value = true ;
632
+ selectedActionMember .value = member;
633
+ }
634
+ };
635
+
636
+ const closeDropdown = () => {
637
+ showMemberDropdownPopover .value = false ;
638
+
639
+ setTimeout (() => {
640
+ selectedActionMember .value = null ;
641
+ }, 200 );
642
+ };
643
+
644
+ const onClickOutside = (el ) => {
645
+ if (! el .target ? .id .includes (' buttonRef' )) {
646
+ closeDropdown ();
647
+ }
648
+ };
649
+
581
650
function handleEditTagsDialog (member ) {
582
651
isEditTagsDialogOpen .value = true ;
583
652
editTagMember .value = member;
@@ -695,9 +764,9 @@ const doExport = () => MemberService.export({
695
764
offset: null ,
696
765
});
697
766
698
- onMounted (async () => {
767
+ onMounted (() => {
699
768
if (store .state .integration .count === 0 ) {
700
- await store .dispatch (' integration/doFetch' );
769
+ store .dispatch (' integration/doFetch' );
701
770
}
702
771
});
703
772
@@ -746,4 +815,9 @@ export default {
746
815
.el - table__body {
747
816
height: 1px ;
748
817
}
818
+
819
+ .popover - dropdown {
820
+ padding: 0 .5rem ! important;
821
+ width: fit- content ! important;
822
+ }
749
823
< / style>
0 commit comments