From 577cdff11cbc3eed17409d44bef92c037fa5ce55 Mon Sep 17 00:00:00 2001 From: joanagmaia Date: Tue, 24 Oct 2023 15:14:05 +0100 Subject: [PATCH] Improve lists page performance (#1734) --- frontend/src/assets/scss/layout.scss | 8 + .../activity/components/activity-list.vue | 9 +- .../components/conversation-list.vue | 9 +- .../components/list/member-list-table.vue | 94 ++++- .../components/member-dropdown-content.vue | 396 ++++++++++++++++++ .../member/components/member-dropdown.vue | 391 ++--------------- .../modules/member/pages/member-list-page.vue | 1 + .../list/organization-list-table.vue | 90 +++- .../organization-dropdown-content.vue | 298 +++++++++++++ .../components/organization-dropdown.vue | 261 +----------- .../src/shared/avatar-image/avatar-image.vue | 2 +- frontend/vite.config.js | 3 +- 12 files changed, 924 insertions(+), 638 deletions(-) create mode 100644 frontend/src/modules/member/components/member-dropdown-content.vue create mode 100644 frontend/src/modules/organization/components/organization-dropdown-content.vue diff --git a/frontend/src/assets/scss/layout.scss b/frontend/src/assets/scss/layout.scss index 040d16d4ca..4e5fc3f217 100644 --- a/frontend/src/assets/scss/layout.scss +++ b/frontend/src/assets/scss/layout.scss @@ -72,6 +72,14 @@ hr { } } +.custom-spinner::before { + @apply border-2 border-gray-100 border-b-gray-900 border-x-gray-900 rounded-full h-8 w-8 absolute; + top: 10%; + left: 10%; + transform: translate3d(-50%, -50%, 0); + content: ""; +} + .el-loading-spinner .path { stroke: #e94f2e; } diff --git a/frontend/src/modules/activity/components/activity-list.vue b/frontend/src/modules/activity/components/activity-list.vue index 58234f0f78..217c7a4949 100644 --- a/frontend/src/modules/activity/components/activity-list.vue +++ b/frontend/src/modules/activity/components/activity-list.vue @@ -9,9 +9,12 @@ />
+ class="h-16 !relative !min-h-5 flex justify-center items-center" + > +
+
+
+
+ class="h-16 !relative !min-h-5 flex justify-center items-center" + > +
+
+
+
+ class="h-16 !relative !min-h-5 flex justify-center items-center" + > +
+
+
+
- +
@@ -432,6 +443,25 @@
+ +
+ +
+
@@ -443,6 +473,7 @@ import { useRouter } from 'vue-router'; import { computed, onMounted, onUnmounted, ref, defineProps, watch, } from 'vue'; +import { ClickOutside as vClickOutside } from 'element-plus'; import { storeToRefs } from 'pinia'; import { i18n } from '@/i18n'; import AppMemberListToolbar from '@/modules/member/components/list/member-list-toolbar.vue'; @@ -456,7 +487,7 @@ import AppMemberMergeDialog from '@/modules/member/components/member-merge-dialo import AppTagPopover from '@/modules/tag/components/tag-popover.vue'; import AppPagination from '@/shared/pagination/pagination.vue'; import AppMemberBadge from '../member-badge.vue'; -import AppMemberDropdown from '../member-dropdown.vue'; +import AppMemberDropdownContent from '../member-dropdown-content.vue'; import AppMemberIdentities from '../member-identities.vue'; import AppMemberReach from '../member-reach.vue'; import AppMemberEngagementLevel from '../member-engagement-level.vue'; @@ -477,6 +508,11 @@ const isMergeDialogOpen = ref(null); const isEditTagsDialogOpen = ref(false); const editTagMember = ref(null); +const showMemberDropdownPopover = ref(false); +const memberDropdownPopover = ref(null); +const actionBtnRefs = ref({}); +const selectedActionMember = ref(null); + const props = defineProps({ hasIntegrations: { type: Boolean, @@ -578,6 +614,39 @@ document.onmouseup = () => { isCursorDown.value = false; }; +const setActionBtnsRef = (el, id) => { + if (el) { + actionBtnRefs.value[id] = el; + } +}; + +const onActionBtnClick = (member) => { + if (selectedActionMember.value?.id === member.id) { + showMemberDropdownPopover.value = false; + + setTimeout(() => { + selectedActionMember.value = null; + }, 200); + } else { + showMemberDropdownPopover.value = true; + selectedActionMember.value = member; + } +}; + +const closeDropdown = () => { + showMemberDropdownPopover.value = false; + + setTimeout(() => { + selectedActionMember.value = null; + }, 200); +}; + +const onClickOutside = (el) => { + if (!el.target?.id.includes('buttonRef')) { + closeDropdown(); + } +}; + function handleEditTagsDialog(member) { isEditTagsDialogOpen.value = true; editTagMember.value = member; @@ -695,9 +764,9 @@ const doExport = () => MemberService.export({ offset: null, }); -onMounted(async () => { +onMounted(() => { if (store.state.integration.count === 0) { - await store.dispatch('integration/doFetch'); + store.dispatch('integration/doFetch'); } }); @@ -746,4 +815,9 @@ export default { .el-table__body { height: 1px; } + +.popover-dropdown { + padding: 0.5rem !important; + width: fit-content !important; +} diff --git a/frontend/src/modules/member/components/member-dropdown-content.vue b/frontend/src/modules/member/components/member-dropdown-content.vue new file mode 100644 index 0000000000..4d6d5665bc --- /dev/null +++ b/frontend/src/modules/member/components/member-dropdown-content.vue @@ -0,0 +1,396 @@ + + + + + diff --git a/frontend/src/modules/member/components/member-dropdown.vue b/frontend/src/modules/member/components/member-dropdown.vue index fb98c7ea72..6ff1ee8dcd 100644 --- a/frontend/src/modules/member/components/member-dropdown.vue +++ b/frontend/src/modules/member/components/member-dropdown.vue @@ -2,9 +2,9 @@
- diff --git a/frontend/src/modules/member/pages/member-list-page.vue b/frontend/src/modules/member/pages/member-list-page.vue index d3d118e8b3..e2a4e97606 100644 --- a/frontend/src/modules/member/pages/member-list-page.vue +++ b/frontend/src/modules/member/pages/member-list-page.vue @@ -107,6 +107,7 @@ const membersToMergeCount = ref(0); const { listByPlatform } = mapGetters('integration'); const { currentUser, currentTenant } = mapGetters('auth'); + const { doRefreshCurrentUser } = mapActions('auth'); const memberFilter = ref(null); diff --git a/frontend/src/modules/organization/components/list/organization-list-table.vue b/frontend/src/modules/organization/components/list/organization-list-table.vue index e55e68dd0c..043cd2fe93 100644 --- a/frontend/src/modules/organization/components/list/organization-list-table.vue +++ b/frontend/src/modules/organization/components/list/organization-list-table.vue @@ -3,9 +3,12 @@
+ class="h-16 !relative !min-h-5 flex justify-center items-center" + > +
+
+
+
- + @@ -660,6 +671,25 @@
+ +
+ +
+
@@ -682,10 +712,11 @@ import employeeChurnRate from '@/modules/organization/config/enrichment/employee import employeeGrowthRate from '@/modules/organization/config/enrichment/employeeGrowthRate'; import revenueRange from '@/modules/organization/config/enrichment/revenueRange'; import AppTagList from '@/modules/tag/components/tag-list.vue'; +import { ClickOutside as vClickOutside } from 'element-plus'; import AppOrganizationIdentities from '../organization-identities.vue'; import AppOrganizationListToolbar from './organization-list-toolbar.vue'; import AppOrganizationName from '../organization-name.vue'; -import AppOrganizationDropdown from '../organization-dropdown.vue'; +import AppOrganizationDropdownContent from '../organization-dropdown-content.vue'; const router = useRouter(); @@ -723,6 +754,11 @@ const isScrollbarVisible = ref(false); const isTableHovered = ref(false); const isCursorDown = ref(false); +const showOrganizationDropdownPopover = ref(false); +const OrganizationDropdownPopover = ref(null); +const actionBtnRefs = ref({}); +const selectedActionOrganization = ref(null); + const pagination = computed({ get() { return props.pagination; @@ -770,6 +806,39 @@ document.onmouseup = () => { isCursorDown.value = false; }; +const setActionBtnsRef = (el, id) => { + if (el) { + actionBtnRefs.value[id] = el; + } +}; + +const onActionBtnClick = (organization) => { + if (selectedActionOrganization.value?.id === organization.id) { + showOrganizationDropdownPopover.value = false; + + setTimeout(() => { + selectedActionOrganization.value = null; + }, 200); + } else { + showOrganizationDropdownPopover.value = true; + selectedActionOrganization.value = organization; + } +}; + +const closeDropdown = () => { + showOrganizationDropdownPopover.value = false; + + setTimeout(() => { + selectedActionOrganization.value = null; + }, 200); +}; + +const onClickOutside = (el) => { + if (!el.target?.id.includes('buttonRef')) { + closeDropdown(); + } +}; + function doChangeSort(sorter) { filters.value.order = { prop: sorter.prop, @@ -936,4 +1005,9 @@ export default { .el-table__body { height: 1px; } + +.popover-dropdown { + padding: 0.5rem !important; + width: fit-content !important; +} diff --git a/frontend/src/modules/organization/components/organization-dropdown-content.vue b/frontend/src/modules/organization/components/organization-dropdown-content.vue new file mode 100644 index 0000000000..6a7145632b --- /dev/null +++ b/frontend/src/modules/organization/components/organization-dropdown-content.vue @@ -0,0 +1,298 @@ + + + + + diff --git a/frontend/src/modules/organization/components/organization-dropdown.vue b/frontend/src/modules/organization/components/organization-dropdown.vue index 6be7a3b40a..873c3d08d4 100644 --- a/frontend/src/modules/organization/components/organization-dropdown.vue +++ b/frontend/src/modules/organization/components/organization-dropdown.vue @@ -2,9 +2,9 @@
diff --git a/frontend/src/shared/avatar-image/avatar-image.vue b/frontend/src/shared/avatar-image/avatar-image.vue index f07717c170..1bb891f716 100644 --- a/frontend/src/shared/avatar-image/avatar-image.vue +++ b/frontend/src/shared/avatar-image/avatar-image.vue @@ -1,7 +1,7 @@