Initial commit: Add logistics and order_detail message types
Some checks failed
Lock Threads / action (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Publish Chatwoot EE docker images / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Publish Chatwoot EE docker images / build (linux/arm64, ubuntu-22.04-arm) (push) Has been cancelled
Publish Chatwoot EE docker images / merge (push) Has been cancelled
Publish Chatwoot CE docker images / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Publish Chatwoot CE docker images / build (linux/arm64, ubuntu-22.04-arm) (push) Has been cancelled
Publish Chatwoot CE docker images / merge (push) Has been cancelled
Run Chatwoot CE spec / lint-backend (push) Has been cancelled
Run Chatwoot CE spec / lint-frontend (push) Has been cancelled
Run Chatwoot CE spec / frontend-tests (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (0, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (1, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (10, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (11, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (12, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (13, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (14, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (15, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (2, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (3, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (4, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (5, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (6, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (7, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (8, 16) (push) Has been cancelled
Run Chatwoot CE spec / backend-tests (9, 16) (push) Has been cancelled
Run Linux nightly installer / nightly (push) Has been cancelled

- Add Logistics component with progress tracking
- Add OrderDetail component for order information
- Support data-driven steps and actions
- Add blue color scale to widget SCSS
- Fix node overflow and progress bar rendering issues
- Add English translations for dashboard components

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Liang XJ
2026-01-26 11:16:56 +08:00
commit 092fb2e083
7646 changed files with 975643 additions and 0 deletions

View File

@@ -0,0 +1,166 @@
import { MESSAGE_TYPE } from 'shared/constants/messages';
import { applyPageFilters, applyRoleFilter, sortComparator } from './helpers';
import filterQueryGenerator from 'dashboard/helper/filterQueryGenerator';
import { matchesFilters } from './helpers/filterHelpers';
import {
getUserPermissions,
getUserRole,
} from '../../../helper/permissionsHelper';
import camelcaseKeys from 'camelcase-keys';
export const getSelectedChatConversation = ({
allConversations,
selectedChatId,
}) =>
allConversations.filter(conversation => conversation.id === selectedChatId);
const getters = {
getAllConversations: ({ allConversations, chatSortFilter: sortKey }) => {
return allConversations.sort((a, b) => sortComparator(a, b, sortKey));
},
getFilteredConversations: (
{ allConversations, chatSortFilter, appliedFilters },
_,
__,
rootGetters
) => {
const currentUser = rootGetters.getCurrentUser;
const currentUserId = rootGetters.getCurrentUser.id;
const currentAccountId = rootGetters.getCurrentAccountId;
const permissions = getUserPermissions(currentUser, currentAccountId);
const userRole = getUserRole(currentUser, currentAccountId);
return allConversations
.filter(conversation => {
const matchesFilterResult = matchesFilters(
conversation,
appliedFilters
);
const allowedForRole = applyRoleFilter(
conversation,
userRole,
permissions,
currentUserId
);
return matchesFilterResult && allowedForRole;
})
.sort((a, b) => sortComparator(a, b, chatSortFilter));
},
getSelectedChat: ({ selectedChatId, allConversations }) => {
const selectedChat = allConversations.find(
conversation => conversation.id === selectedChatId
);
return selectedChat || {};
},
getSelectedChatAttachments: ({ selectedChatId, attachments }) => {
return attachments[selectedChatId] || [];
},
getChatListFilters: ({ conversationFilters }) => conversationFilters,
getLastEmailInSelectedChat: (stage, _getters) => {
const selectedChat = _getters.getSelectedChat;
const { messages = [] } = selectedChat;
const lastEmail = [...messages].reverse().find(message => {
const { message_type: messageType } = message;
if (message.private) return false;
return [MESSAGE_TYPE.OUTGOING, MESSAGE_TYPE.INCOMING].includes(
messageType
);
});
return lastEmail;
},
getMineChats: (_state, _, __, rootGetters) => activeFilters => {
const currentUserID = rootGetters.getCurrentUser?.id;
return _state.allConversations.filter(conversation => {
const { assignee } = conversation.meta;
const isAssignedToMe = assignee && assignee.id === currentUserID;
const shouldFilter = applyPageFilters(conversation, activeFilters);
const isChatMine = isAssignedToMe && shouldFilter;
return isChatMine;
});
},
getAppliedConversationFiltersV2: _state => {
// TODO: Replace existing one with V2 after migrating the filters to use camelcase
return _state.appliedFilters.map(camelcaseKeys);
},
getAppliedConversationFilters: _state => {
return _state.appliedFilters;
},
getAppliedConversationFiltersQuery: _state => {
const hasAppliedFilters = _state.appliedFilters.length !== 0;
return hasAppliedFilters ? filterQueryGenerator(_state.appliedFilters) : [];
},
getUnAssignedChats: _state => activeFilters => {
return _state.allConversations.filter(conversation => {
const isUnAssigned = !conversation.meta.assignee;
const shouldFilter = applyPageFilters(conversation, activeFilters);
return isUnAssigned && shouldFilter;
});
},
getAllStatusChats: (_state, _, __, rootGetters) => activeFilters => {
const currentUser = rootGetters.getCurrentUser;
const currentUserId = rootGetters.getCurrentUser.id;
const currentAccountId = rootGetters.getCurrentAccountId;
const permissions = getUserPermissions(currentUser, currentAccountId);
const userRole = getUserRole(currentUser, currentAccountId);
return _state.allConversations.filter(conversation => {
const shouldFilter = applyPageFilters(conversation, activeFilters);
const allowedForRole = applyRoleFilter(
conversation,
userRole,
permissions,
currentUserId
);
return shouldFilter && allowedForRole;
});
},
getChatListLoadingStatus: ({ listLoadingStatus }) => listLoadingStatus,
getAllMessagesLoaded(_state) {
const [chat] = getSelectedChatConversation(_state);
return !chat || chat.allMessagesLoaded === undefined
? false
: chat.allMessagesLoaded;
},
getUnreadCount(_state) {
const [chat] = getSelectedChatConversation(_state);
if (!chat) return [];
return chat.messages.filter(
chatMessage =>
chatMessage.created_at * 1000 > chat.agent_last_seen_at * 1000 &&
chatMessage.message_type === 0 &&
chatMessage.private !== true
).length;
},
getChatStatusFilter: ({ chatStatusFilter }) => chatStatusFilter,
getChatSortFilter: ({ chatSortFilter }) => chatSortFilter,
getSelectedInbox: ({ currentInbox }) => currentInbox,
getConversationById: _state => conversationId => {
return _state.allConversations.find(
value => value.id === Number(conversationId)
);
},
getConversationParticipants: _state => {
return _state.conversationParticipants;
},
getConversationLastSeen: _state => {
return _state.conversationLastSeen;
},
getContextMenuChatId: _state => {
return _state.contextMenuChatId;
},
getCopilotAssistant: _state => {
return _state.copilotAssistant;
},
};
export default getters;