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 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ emptyStateMessage }}
-
-
+
+