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 @@ - + +