From 2c75ccb00407cae0924032cb309bd80589a640df Mon Sep 17 00:00:00 2001 From: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Date: Thu, 30 Jan 2025 15:24:02 +0530 Subject: [PATCH 1/3] feat: Ability to rearrange attributes in sidebar (#10784) --- .../ContactCustomAttributes.vue | 36 ++- .../conversation/ConversationInfo.vue | 59 ++--- .../customAttributes/CustomAttributes.vue | 220 +++++++++++++----- 3 files changed, 233 insertions(+), 82 deletions(-) diff --git a/app/javascript/dashboard/components-next/Contacts/ContactsSidebar/ContactCustomAttributes.vue b/app/javascript/dashboard/components-next/Contacts/ContactsSidebar/ContactCustomAttributes.vue index f2a5c1ee8..4964668df 100644 --- a/app/javascript/dashboard/components-next/Contacts/ContactsSidebar/ContactCustomAttributes.vue +++ b/app/javascript/dashboard/components-next/Contacts/ContactsSidebar/ContactCustomAttributes.vue @@ -2,6 +2,7 @@ import { ref, computed } from 'vue'; import { useI18n } from 'vue-i18n'; import { useMapGetter } from 'dashboard/composables/store'; +import { useUISettings } from 'dashboard/composables/useUISettings'; import ContactCustomAttributeItem from 'dashboard/components-next/Contacts/ContactsSidebar/ContactCustomAttributeItem.vue'; @@ -14,6 +15,8 @@ const props = defineProps({ const { t } = useI18n(); +const { uiSettings } = useUISettings(); + const searchQuery = ref(''); const contactAttributes = useMapGetter('attributes/getContactAttributes') || []; @@ -46,20 +49,49 @@ const processContactAttributes = ( }, []); }; +const sortAttributesOrder = computed( + () => + uiSettings.value.conversation_elements_order_conversation_contact_panel ?? + [] +); + +const sortByUISettings = attributes => { + // Get saved order from UI settings + // Same as conversation panel contact attribute order + const order = sortAttributesOrder.value; + + // If no order defined, return original array + if (!order?.length) return attributes; + + const orderMap = new Map(order.map((key, index) => [key, index])); + + // Sort attributes based on their position in saved order + return [...attributes].sort((a, b) => { + // Get positions, use Infinity if not found in order (pushes to end) + const aPos = orderMap.get(a.attributeKey) ?? Infinity; + const bPos = orderMap.get(b.attributeKey) ?? Infinity; + return aPos - bPos; + }); +}; + const usedAttributes = computed(() => { - return processContactAttributes( + const attributes = processContactAttributes( contactAttributes.value, props.selectedContact?.customAttributes, (key, custom) => key in custom ); + + return sortByUISettings(attributes); }); const unusedAttributes = computed(() => { - return processContactAttributes( + const attributes = processContactAttributes( contactAttributes.value, props.selectedContact?.customAttributes, (key, custom) => !(key in custom) ); + + return sortByUISettings(attributes); }); const filteredUnusedAttributes = computed(() => { diff --git a/app/javascript/dashboard/routes/dashboard/conversation/ConversationInfo.vue b/app/javascript/dashboard/routes/dashboard/conversation/ConversationInfo.vue index ec44d5a3f..621d13e5c 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/ConversationInfo.vue +++ b/app/javascript/dashboard/routes/dashboard/conversation/ConversationInfo.vue @@ -47,63 +47,68 @@ const staticElements = computed(() => { content: initiatedAt, title: 'CONTACT_PANEL.INITIATED_AT', + key: 'static-initiated-at', + type: 'static_attribute', }, { content: browserLanguage, title: 'CONTACT_PANEL.BROWSER_LANGUAGE', + key: 'static-browser-language', + type: 'static_attribute', }, { content: referer, title: 'CONTACT_PANEL.INITIATED_FROM', - type: 'link', + key: 'static-referer', + type: 'static_attribute', }, { content: browserName, title: 'CONTACT_PANEL.BROWSER', + key: 'static-browser', + type: 'static_attribute', }, { content: platformName, title: 'CONTACT_PANEL.OS', + key: 'static-platform', + type: 'static_attribute', }, { content: createdAtIp, title: 'CONTACT_PANEL.IP_ADDRESS', + key: 'static-ip-address', + type: 'static_attribute', }, ].filter(attribute => !!attribute.content.value) ); - -const evenClass = [ - '[&>*:nth-child(odd)]:!bg-white [&>*:nth-child(even)]:!bg-slate-25', - 'dark:[&>*:nth-child(odd)]:!bg-slate-900 dark:[&>*:nth-child(even)]:!bg-slate-800/50', -]; diff --git a/app/javascript/dashboard/routes/dashboard/conversation/customAttributes/CustomAttributes.vue b/app/javascript/dashboard/routes/dashboard/conversation/customAttributes/CustomAttributes.vue index 251d876a9..01fbe9b71 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/customAttributes/CustomAttributes.vue +++ b/app/javascript/dashboard/routes/dashboard/conversation/customAttributes/CustomAttributes.vue @@ -1,5 +1,6 @@ - + + From 55f1690d9e74fd1f2a58f7d0fde3d3abfb447ee0 Mon Sep 17 00:00:00 2001 From: Vishnu Narayanan Date: Thu, 30 Jan 2025 15:52:01 +0530 Subject: [PATCH 2/3] fix: docker github action for ce images (#10800) - Fix the docker tag issue during push stage for ce image build --- .github/workflows/publish_foss_docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_foss_docker.yml b/.github/workflows/publish_foss_docker.yml index 8149ee290..3075a7f3d 100644 --- a/.github/workflows/publish_foss_docker.yml +++ b/.github/workflows/publish_foss_docker.yml @@ -79,7 +79,7 @@ jobs: file: docker/Dockerfile platforms: ${{ matrix.platform }} push: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' }} - outputs: type=image,name=${{ env.DOCKER_TAG }},push-by-digest=true,name-canonical=true,push=true + outputs: type=image,name=${{ env.DOCKER_REPO }},push-by-digest=true,name-canonical=true,push=true - name: Export digest run: | From b811c27ab5955413667bc48f9283403e6b792e99 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Fri, 31 Jan 2025 06:33:12 +0530 Subject: [PATCH 3/3] feat: Hide empty folders from sidebar (#10786) This PR updates the sidebar to hide empty folders. So, in case the user has not created any folders, or teams, the section in the sidebar will be hidden --- .../sidebar/SidebarSubGroup.vue | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/app/javascript/dashboard/components-next/sidebar/SidebarSubGroup.vue b/app/javascript/dashboard/components-next/sidebar/SidebarSubGroup.vue index a938a202e..8e3c3009e 100644 --- a/app/javascript/dashboard/components-next/sidebar/SidebarSubGroup.vue +++ b/app/javascript/dashboard/components-next/sidebar/SidebarSubGroup.vue @@ -2,7 +2,6 @@ import { computed, ref } from 'vue'; import SidebarGroupLeaf from './SidebarGroupLeaf.vue'; import SidebarGroupSeparator from './SidebarGroupSeparator.vue'; -import SidebarGroupEmptyLeaf from './SidebarGroupEmptyLeaf.vue'; import { useSidebarContext } from './provider'; import { useEventListener } from '@vueuse/core'; @@ -26,11 +25,6 @@ const accessibleItems = computed(() => ); const hasAccessibleItems = computed(() => { - if (props.children.length === 0) { - // cases like segment, folder and labels where users can create new items - return true; - } - return accessibleItems.value.length > 0; }); @@ -55,7 +49,7 @@ useEventListener(scrollableContainer, 'scroll', () => { :icon class="my-1" /> -