@tuturuuu/ui 0.2.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -0
- package/package.json +79 -67
- package/src/components/ui/__tests__/avatar.test.tsx +8 -5
- package/src/components/ui/calendar-app/components/calendar-connections-compact.tsx +414 -0
- package/src/components/ui/calendar-app/components/calendar-connections-manager.tsx +5 -1
- package/src/components/ui/calendar-app/components/calendar-connections-settings-content.tsx +529 -0
- package/src/components/ui/calendar-app/components/calendar-connections-unified.tsx +26 -1429
- package/src/components/ui/calendar-app/components/use-calendar-connections-manager.ts +711 -0
- package/src/components/ui/chart.test.tsx +29 -0
- package/src/components/ui/chart.tsx +12 -3
- package/src/components/ui/chat/chat-agent-details-operations-panel.test.tsx +396 -2
- package/src/components/ui/chat/chat-agent-details-operations-panel.tsx +36 -8
- package/src/components/ui/chat/chat-agent-details-setup-panel.tsx +14 -0
- package/src/components/ui/chat/chat-agent-details-sidebar.test.tsx +5 -0
- package/src/components/ui/chat/chat-agent-details-sidebar.tsx +21 -7
- package/src/components/ui/chat/chat-agent-details-utils.test.ts +73 -0
- package/src/components/ui/chat/chat-agent-details-utils.tsx +100 -26
- package/src/components/ui/chat/chat-agent-details-zalo-personal-panel.tsx +517 -0
- package/src/components/ui/chat/chat-workspace.tsx +31 -1
- package/src/components/ui/chat/hooks-messages.test.tsx +45 -1
- package/src/components/ui/chat/hooks-messages.ts +1 -1
- package/src/components/ui/chat/hooks-realtime.ts +13 -16
- package/src/components/ui/custom/__tests__/settings-dialog-shell.test.tsx +24 -1
- package/src/components/ui/custom/__tests__/tuturuuu-logo.test.ts +12 -3
- package/src/components/ui/custom/__tests__/workspace-select-helpers.test.ts +39 -0
- package/src/components/ui/custom/common-footer.tsx +16 -1
- package/src/components/ui/custom/production-indicator.tsx +1 -1
- package/src/components/ui/custom/settings/sidebar-settings.tsx +1 -1
- package/src/components/ui/custom/settings/task-settings.tsx +18 -0
- package/src/components/ui/custom/settings-dialog-shell.tsx +38 -23
- package/src/components/ui/custom/sidebar-context-compile-graph.test.ts +60 -0
- package/src/components/ui/custom/sidebar-context.tsx +61 -61
- package/src/components/ui/custom/sidebar-remote-behavior-bridge.tsx +123 -0
- package/src/components/ui/custom/tuturuuu-logo-urls.ts +6 -0
- package/src/components/ui/custom/tuturuuu-logo.tsx +25 -7
- package/src/components/ui/custom/workspace-select-helpers.ts +20 -0
- package/src/components/ui/custom/workspace-select.tsx +33 -12
- package/src/components/ui/finance/invoices/components/invoice-checkout-summary.tsx +7 -1
- package/src/components/ui/finance/invoices/components/invoice-payment-settings.tsx +3 -0
- package/src/components/ui/finance/invoices/components/invoice-products-permission-warning.tsx +58 -0
- package/src/components/ui/finance/invoices/components/subscription-group-selector.tsx +12 -20
- package/src/components/ui/finance/invoices/hooks/use-subscription-auto-selection.ts +10 -9
- package/src/components/ui/finance/invoices/hooks/use-subscription-invoice-content.ts +10 -5
- package/src/components/ui/finance/invoices/hooks.ts +75 -20
- package/src/components/ui/finance/invoices/new-invoice-page.test.tsx +137 -0
- package/src/components/ui/finance/invoices/new-invoice-page.tsx +86 -37
- package/src/components/ui/finance/invoices/product-selection.test.tsx +8 -26
- package/src/components/ui/finance/invoices/product-selection.tsx +2 -10
- package/src/components/ui/finance/invoices/standard-invoice.tsx +88 -26
- package/src/components/ui/finance/invoices/subscription-invoice.tsx +154 -46
- package/src/components/ui/finance/invoices/utils.test.ts +50 -0
- package/src/components/ui/finance/invoices/utils.ts +75 -17
- package/src/components/ui/finance/shared/finance-display-amount.tsx +3 -1
- package/src/components/ui/finance/shared/finance-permission-warning-dialog.test.tsx +34 -0
- package/src/components/ui/finance/shared/finance-permission-warning-dialog.tsx +157 -0
- package/src/components/ui/finance/transactions/form-basic-tab.tsx +8 -0
- package/src/components/ui/finance/transactions/form-more-tab.tsx +8 -0
- package/src/components/ui/finance/transactions/form-types.ts +2 -0
- package/src/components/ui/finance/transactions/form.test.tsx +43 -0
- package/src/components/ui/finance/transactions/form.tsx +60 -0
- package/src/components/ui/finance/transactions/infinite-transactions-list.tsx +27 -0
- package/src/components/ui/finance/transactions/transactions-create-summary.tsx +13 -1
- package/src/components/ui/finance/transactions/transactions-infinite-page.tsx +4 -0
- package/src/components/ui/finance/transactions/transactions-page.tsx +23 -1
- package/src/components/ui/finance/wallets/walletId/wallet-details-actions.tsx +4 -0
- package/src/components/ui/finance/wallets/walletId/wallet-details-page.tsx +5 -0
- package/src/components/ui/legacy/calendar/calendar-content.tsx +9 -1
- package/src/components/ui/legacy/calendar/event-modal.tsx +146 -2
- package/src/components/ui/legacy/calendar/event-preview-popover.tsx +200 -0
- package/src/components/ui/legacy/calendar/smart-calendar.test.tsx +76 -0
- package/src/components/ui/legacy/calendar/smart-calendar.tsx +13 -1
- package/src/components/ui/legacy/meet/page.test.ts +180 -0
- package/src/components/ui/legacy/meet/page.tsx +87 -39
- package/src/components/ui/tu-do/boards/boardId/board-column.tsx +79 -25
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/__tests__/bulk-mutations-external-workspaces.test.tsx +392 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-actions-island.test.tsx +57 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-actions-island.tsx +106 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-clear-delete.ts +106 -161
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-relations-assignees.ts +96 -150
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-relations-labels.ts +63 -79
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-relations-projects.ts +64 -83
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-mutations-updates.ts +115 -155
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-operation-utils.ts +319 -2
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-operations.ts +8 -1
- package/src/components/ui/tu-do/boards/boardId/kanban/dnd/use-kanban-dnd.ts +63 -37
- package/src/components/ui/tu-do/boards/boardId/kanban/kanban-column-collapse.ts +16 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-columns.test.tsx +46 -0
- package/src/components/ui/tu-do/boards/boardId/kanban/rendering/kanban-columns.tsx +5 -3
- package/src/components/ui/tu-do/boards/boardId/kanban.tsx +19 -7
- package/src/components/ui/tu-do/boards/boardId/menus/__tests__/task-menus.test.tsx +181 -2
- package/src/components/ui/tu-do/boards/boardId/menus/index.ts +1 -0
- package/src/components/ui/tu-do/boards/boardId/menus/task-scheduling-menu.tsx +463 -0
- package/src/components/ui/tu-do/boards/boardId/menus/task-scheduling-utils.ts +109 -0
- package/src/components/ui/tu-do/boards/boardId/task-board-server-page.tsx +4 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/TaskCardCheckbox.tsx +6 -3
- package/src/components/ui/tu-do/boards/boardId/task-card/TaskCardDates.tsx +26 -9
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-checkbox-style.ts +39 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-comparator.test.ts +43 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-comparator.ts +33 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-completion-checkbox-visibility.test.ts +31 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-completion-checkbox-visibility.ts +9 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-identifier-row.test.tsx +124 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card-identifier-row.tsx +88 -0
- package/src/components/ui/tu-do/boards/boardId/task-card/task-card.tsx +151 -76
- package/src/components/ui/tu-do/boards/boardId/task-card/task-scheduling-badge.tsx +174 -0
- package/src/components/ui/tu-do/providers/task-dialog-provider.tsx +34 -13
- package/src/components/ui/tu-do/shared/__tests__/board-client.test.tsx +54 -1
- package/src/components/ui/tu-do/shared/__tests__/board-views.test.tsx +158 -0
- package/src/components/ui/tu-do/shared/__tests__/task-dialog-manager.test.tsx +5 -2
- package/src/components/ui/tu-do/shared/board-client.tsx +12 -2
- package/src/components/ui/tu-do/shared/board-views.tsx +195 -328
- package/src/components/ui/tu-do/shared/list-view.tsx +18 -8
- package/src/components/ui/tu-do/shared/task-due-date-visibility.test.ts +72 -0
- package/src/components/ui/tu-do/shared/task-due-date-visibility.ts +38 -0
- package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-mutations.ts +6 -3
- package/src/components/ui/tu-do/shared/task-edit-dialog/hooks/use-task-save.ts +2 -2
- package/src/components/ui/tu-do/shared/task-row-actions-menu.tsx +33 -0
- package/src/hooks/__tests__/use-calendar-readonly.test.tsx +74 -3
- package/src/hooks/__tests__/use-task-actions.test.tsx +118 -0
- package/src/hooks/__tests__/use-user-config.test.tsx +65 -0
- package/src/hooks/__tests__/use-workspace-presence.test.tsx +1 -1
- package/src/hooks/use-calendar-sync.tsx +22 -277
- package/src/hooks/use-calendar.tsx +95 -525
- package/src/hooks/use-semantic-task-search.ts +10 -33
- package/src/hooks/use-task-actions.ts +43 -117
- package/src/hooks/use-user-config.ts +1 -1
- package/src/hooks/use-workspace-config.ts +6 -2
- package/src/hooks/use-workspace-presence.ts +1 -1
- package/src/components/ui/tu-do/boards/boardId/kanban/bulk/bulk-actions-bar.tsx +0 -94
|
@@ -155,7 +155,10 @@ export function ChatAgentDetailsSidebar({
|
|
|
155
155
|
if (!open) return null;
|
|
156
156
|
|
|
157
157
|
return (
|
|
158
|
-
<aside
|
|
158
|
+
<aside
|
|
159
|
+
className="hidden w-96 min-w-0 shrink-0 overflow-hidden border-l bg-background md:flex md:flex-col"
|
|
160
|
+
data-chat-agent-details-sidebar="true"
|
|
161
|
+
>
|
|
159
162
|
<Tabs
|
|
160
163
|
className="min-h-0 flex-1 gap-0"
|
|
161
164
|
defaultValue="setup"
|
|
@@ -192,7 +195,7 @@ export function ChatAgentDetailsSidebar({
|
|
|
192
195
|
</TabsList>
|
|
193
196
|
</div>
|
|
194
197
|
|
|
195
|
-
<ScrollArea className="min-h-0 flex-1">
|
|
198
|
+
<ScrollArea className="[&_[data-radix-scroll-area-viewport]>div]:!block [&_[data-radix-scroll-area-viewport]>div]:!min-w-0 min-h-0 min-w-0 flex-1 overflow-hidden [&_[data-radix-scroll-area-viewport]>div]:w-full [&_[data-radix-scroll-area-viewport]>div]:max-w-full">
|
|
196
199
|
{renderContent({
|
|
197
200
|
agentsError: agentsQuery.error,
|
|
198
201
|
agentsLoading: agentsQuery.isLoading,
|
|
@@ -263,7 +266,7 @@ function renderContent({
|
|
|
263
266
|
|
|
264
267
|
if (agentsLoading) {
|
|
265
268
|
return (
|
|
266
|
-
<div className="flex items-center justify-center p-6 text-muted-foreground text-sm">
|
|
269
|
+
<div className="flex min-w-0 items-center justify-center p-6 text-muted-foreground text-sm">
|
|
267
270
|
<LoaderCircle className="mr-2 size-4 animate-spin" />
|
|
268
271
|
{t('loading_ai_settings')}
|
|
269
272
|
</div>
|
|
@@ -285,7 +288,10 @@ function renderContent({
|
|
|
285
288
|
|
|
286
289
|
return (
|
|
287
290
|
<>
|
|
288
|
-
<TabsContent
|
|
291
|
+
<TabsContent
|
|
292
|
+
className="m-0 min-w-0 max-w-full overflow-hidden p-3"
|
|
293
|
+
value={'setup' satisfies AgentTab}
|
|
294
|
+
>
|
|
289
295
|
<AgentSetupForm
|
|
290
296
|
agent={agent}
|
|
291
297
|
channel={channel}
|
|
@@ -293,13 +299,18 @@ function renderContent({
|
|
|
293
299
|
onSubmit={onSave}
|
|
294
300
|
/>
|
|
295
301
|
</TabsContent>
|
|
296
|
-
<TabsContent
|
|
302
|
+
<TabsContent
|
|
303
|
+
className="m-0 min-w-0 max-w-full overflow-hidden p-3"
|
|
304
|
+
value={'operations' satisfies AgentTab}
|
|
305
|
+
>
|
|
297
306
|
<AgentOperationsPanel
|
|
307
|
+
agentId={agent.id}
|
|
298
308
|
channel={channel}
|
|
299
309
|
isPending={isPending}
|
|
300
310
|
onCopySecret={onCopySecret}
|
|
301
311
|
onDeploy={onDeploy}
|
|
302
312
|
onPause={onPause}
|
|
313
|
+
onRefresh={onRefresh}
|
|
303
314
|
onRotateSecret={onRotateSecret}
|
|
304
315
|
onTest={onTest}
|
|
305
316
|
secretPreview={secretPreview}
|
|
@@ -307,7 +318,10 @@ function renderContent({
|
|
|
307
318
|
/>
|
|
308
319
|
</TabsContent>
|
|
309
320
|
{tabs.includes('thread') ? (
|
|
310
|
-
<TabsContent
|
|
321
|
+
<TabsContent
|
|
322
|
+
className="m-0 min-w-0 max-w-full overflow-hidden p-3"
|
|
323
|
+
value={'thread' satisfies AgentTab}
|
|
324
|
+
>
|
|
311
325
|
<AgentExternalThreadPanel metadata={metadata} onRefresh={onRefresh} />
|
|
312
326
|
</TabsContent>
|
|
313
327
|
) : null}
|
|
@@ -323,7 +337,7 @@ function SidebarNotice({
|
|
|
323
337
|
secondary?: string | null;
|
|
324
338
|
}) {
|
|
325
339
|
return (
|
|
326
|
-
<div className="space-y-2 p-4 text-sm">
|
|
340
|
+
<div className="min-w-0 space-y-2 overflow-hidden p-4 text-sm">
|
|
327
341
|
<p className="text-muted-foreground">{message}</p>
|
|
328
342
|
{secondary ? (
|
|
329
343
|
<p className="break-words rounded-md border bg-muted/20 p-2 text-muted-foreground text-xs">
|
|
@@ -5,6 +5,7 @@ import { describe, expect, it } from 'vitest';
|
|
|
5
5
|
import {
|
|
6
6
|
buildAgentPayload,
|
|
7
7
|
readAgentConversationMetadata,
|
|
8
|
+
secretNamesForChannel,
|
|
8
9
|
} from './chat-agent-details-utils';
|
|
9
10
|
|
|
10
11
|
function conversation(metadata: Record<string, unknown>): ChatConversation {
|
|
@@ -158,4 +159,76 @@ describe('buildAgentPayload', () => {
|
|
|
158
159
|
name: 'Updated name',
|
|
159
160
|
});
|
|
160
161
|
});
|
|
162
|
+
|
|
163
|
+
it('preserves personal Zalo channel mode and credentials when saving setup edits', () => {
|
|
164
|
+
const agent: AiAgentDefinition = {
|
|
165
|
+
channels: [
|
|
166
|
+
{
|
|
167
|
+
adapter: 'zalo',
|
|
168
|
+
autoRespond: true,
|
|
169
|
+
displayName: 'Personal Zalo',
|
|
170
|
+
enabled: true,
|
|
171
|
+
externalChannelId: 'zalo-thread',
|
|
172
|
+
historySyncEnabled: true,
|
|
173
|
+
id: 'zalo-personal',
|
|
174
|
+
lastDeployedAt: null,
|
|
175
|
+
lastError: null,
|
|
176
|
+
lastEventAt: null,
|
|
177
|
+
mentionRoleIds: [],
|
|
178
|
+
secrets: [
|
|
179
|
+
{
|
|
180
|
+
configured: true,
|
|
181
|
+
lastFour: 'json',
|
|
182
|
+
name: 'personalCookieJson',
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
status: 'deployed',
|
|
186
|
+
webhookUrl: null,
|
|
187
|
+
workspaceId: 'workspace-1',
|
|
188
|
+
zaloAccountMode: 'personal',
|
|
189
|
+
zaloPersonalOwnId: 'own-1',
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
createdAt: null,
|
|
193
|
+
enabled: true,
|
|
194
|
+
id: 'agent-1',
|
|
195
|
+
instructions: 'Old instructions',
|
|
196
|
+
modelId: 'old-model',
|
|
197
|
+
name: 'Old name',
|
|
198
|
+
temperature: null,
|
|
199
|
+
tools: [],
|
|
200
|
+
updatedAt: null,
|
|
201
|
+
};
|
|
202
|
+
const formData = new FormData();
|
|
203
|
+
formData.set('agentEnabled', 'on');
|
|
204
|
+
formData.set('name', 'Updated name');
|
|
205
|
+
formData.set('modelId', 'updated-model');
|
|
206
|
+
formData.set('instructions', 'Updated instructions');
|
|
207
|
+
formData.set('channelDisplayName', 'Personal Zalo');
|
|
208
|
+
formData.set('channelEnabled', 'on');
|
|
209
|
+
formData.set('channelAutoRespond', 'on');
|
|
210
|
+
formData.set('channelHistorySyncEnabled', 'on');
|
|
211
|
+
formData.set('externalChannelId', 'zalo-thread');
|
|
212
|
+
formData.set('workspaceId', 'workspace-1');
|
|
213
|
+
formData.set('zaloPersonalOwnId', 'own-1');
|
|
214
|
+
|
|
215
|
+
expect(secretNamesForChannel(agent.channels[0]!)).toEqual([
|
|
216
|
+
'personalCookieJson',
|
|
217
|
+
'personalImei',
|
|
218
|
+
'personalUserAgent',
|
|
219
|
+
]);
|
|
220
|
+
expect(
|
|
221
|
+
buildAgentPayload(formData, agent, agent.channels[0]!)
|
|
222
|
+
).toMatchObject({
|
|
223
|
+
channels: [
|
|
224
|
+
{
|
|
225
|
+
adapter: 'zalo',
|
|
226
|
+
id: 'zalo-personal',
|
|
227
|
+
zaloAccountMode: 'personal',
|
|
228
|
+
zaloOfficialAccountId: null,
|
|
229
|
+
zaloPersonalOwnId: 'own-1',
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
});
|
|
233
|
+
});
|
|
161
234
|
});
|
|
@@ -78,10 +78,10 @@ export function PanelSection({
|
|
|
78
78
|
title: string;
|
|
79
79
|
}) {
|
|
80
80
|
return (
|
|
81
|
-
<section className="space-y-3 rounded-md border bg-muted/10 p-3">
|
|
82
|
-
<h3 className="flex items-center gap-2 font-medium text-sm">
|
|
83
|
-
{icon}
|
|
84
|
-
{title}
|
|
81
|
+
<section className="min-w-0 space-y-3 overflow-hidden rounded-md border bg-muted/10 p-3">
|
|
82
|
+
<h3 className="flex min-w-0 items-center gap-2 font-medium text-sm">
|
|
83
|
+
<span className="shrink-0">{icon}</span>
|
|
84
|
+
<span className="min-w-0 truncate">{title}</span>
|
|
85
85
|
</h3>
|
|
86
86
|
{children}
|
|
87
87
|
</section>
|
|
@@ -108,7 +108,7 @@ export function Field({
|
|
|
108
108
|
export function KeyValue({ label, value }: { label: string; value: string }) {
|
|
109
109
|
return (
|
|
110
110
|
<div className="flex min-w-0 items-center justify-between gap-3 text-sm">
|
|
111
|
-
<span className="text-muted-foreground">{label}</span>
|
|
111
|
+
<span className="shrink-0 text-muted-foreground">{label}</span>
|
|
112
112
|
<span className="min-w-0 truncate font-medium">{value}</span>
|
|
113
113
|
</div>
|
|
114
114
|
);
|
|
@@ -169,12 +169,61 @@ export function secretNamesForChannel(channel: AiAgentChannelConfig) {
|
|
|
169
169
|
const required =
|
|
170
170
|
channel.adapter === 'discord'
|
|
171
171
|
? ['applicationId', 'publicKey', 'botToken']
|
|
172
|
-
:
|
|
172
|
+
: isPersonalZaloChannel(channel)
|
|
173
|
+
? ['personalCookieJson', 'personalImei', 'personalUserAgent']
|
|
174
|
+
: ['botToken', 'webhookSecret'];
|
|
173
175
|
return [
|
|
174
176
|
...new Set([...required, ...channel.secrets.map((item) => item.name)]),
|
|
175
177
|
];
|
|
176
178
|
}
|
|
177
179
|
|
|
180
|
+
export function isPersonalZaloChannel(channel: AiAgentChannelConfig) {
|
|
181
|
+
return channel.adapter === 'zalo' && channel.zaloAccountMode === 'personal';
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const ZALO_PERSONAL_ERROR_KEYS = {
|
|
185
|
+
ai_agent_zalo_personal_channel_required:
|
|
186
|
+
'agent_zalo_personal_channel_required',
|
|
187
|
+
zalo_personal_cookie_json_invalid: 'agent_zalo_personal_cookie_json_invalid',
|
|
188
|
+
zalo_personal_credentials_missing: 'agent_zalo_personal_credentials_missing',
|
|
189
|
+
zalo_personal_feature_disabled: 'agent_zalo_personal_feature_disabled',
|
|
190
|
+
zalo_personal_phone_sync_timed_out: 'agent_zalo_personal_sync_phone_failed',
|
|
191
|
+
zalo_personal_phone_sync_no_payload:
|
|
192
|
+
'agent_zalo_personal_sync_phone_no_payload',
|
|
193
|
+
zalo_personal_phone_sync_waiting_for_phone:
|
|
194
|
+
'agent_zalo_personal_sync_phone_waiting',
|
|
195
|
+
zalo_personal_web_sync_browser_unavailable:
|
|
196
|
+
'agent_zalo_personal_sync_web_browser_unavailable',
|
|
197
|
+
zalo_personal_web_sync_failed: 'agent_zalo_personal_sync_web_failed',
|
|
198
|
+
zalo_personal_web_sync_login_required:
|
|
199
|
+
'agent_zalo_personal_sync_web_login_required',
|
|
200
|
+
zalo_personal_web_sync_timed_out: 'agent_zalo_personal_sync_web_timed_out',
|
|
201
|
+
zalo_personal_web_sync_waiting_for_phone:
|
|
202
|
+
'agent_zalo_personal_sync_phone_waiting',
|
|
203
|
+
zalo_personal_qr_aborted: 'agent_zalo_personal_qr_aborted',
|
|
204
|
+
zalo_personal_qr_credentials_missing:
|
|
205
|
+
'agent_zalo_personal_qr_credentials_missing',
|
|
206
|
+
zalo_personal_qr_declined: 'agent_zalo_personal_qr_declined',
|
|
207
|
+
zalo_personal_qr_expired: 'agent_zalo_personal_qr_expired',
|
|
208
|
+
} as const;
|
|
209
|
+
|
|
210
|
+
export function formatZaloPersonalError(
|
|
211
|
+
error: string | null | undefined,
|
|
212
|
+
t: ReturnType<typeof useTranslations>
|
|
213
|
+
) {
|
|
214
|
+
if (!error) return null;
|
|
215
|
+
|
|
216
|
+
const key =
|
|
217
|
+
ZALO_PERSONAL_ERROR_KEYS[error as keyof typeof ZALO_PERSONAL_ERROR_KEYS];
|
|
218
|
+
if (key) return t(key);
|
|
219
|
+
|
|
220
|
+
if (error.startsWith('zalo_personal_qr_')) {
|
|
221
|
+
return t('agent_zalo_personal_qr_failed');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return error;
|
|
225
|
+
}
|
|
226
|
+
|
|
178
227
|
export async function copyToClipboard(
|
|
179
228
|
value: string,
|
|
180
229
|
labels: { error: string; success: string }
|
|
@@ -212,17 +261,30 @@ function buildSelectedChannelPayload(
|
|
|
212
261
|
String(formData.get('workspaceId') ?? '').trim() || channel.workspaceId,
|
|
213
262
|
};
|
|
214
263
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
264
|
+
if (channel.adapter === 'discord') {
|
|
265
|
+
return {
|
|
266
|
+
...base,
|
|
267
|
+
discordGuildId:
|
|
268
|
+
String(formData.get('discordGuildId') ?? '').trim() || null,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const zaloAccountMode = channel.zaloAccountMode ?? 'official';
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
...base,
|
|
276
|
+
zaloAccountMode,
|
|
277
|
+
zaloOfficialAccountId:
|
|
278
|
+
zaloAccountMode === 'official'
|
|
279
|
+
? String(formData.get('zaloOfficialAccountId') ?? '').trim() || null
|
|
280
|
+
: null,
|
|
281
|
+
zaloPersonalOwnId:
|
|
282
|
+
zaloAccountMode === 'personal'
|
|
283
|
+
? String(formData.get('zaloPersonalOwnId') ?? '').trim() ||
|
|
284
|
+
channel.zaloPersonalOwnId ||
|
|
285
|
+
null
|
|
286
|
+
: null,
|
|
287
|
+
};
|
|
226
288
|
}
|
|
227
289
|
|
|
228
290
|
function buildExistingChannelPayload(
|
|
@@ -241,15 +303,27 @@ function buildExistingChannelPayload(
|
|
|
241
303
|
workspaceId: channel.workspaceId,
|
|
242
304
|
};
|
|
243
305
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
306
|
+
if (channel.adapter === 'discord') {
|
|
307
|
+
return {
|
|
308
|
+
...base,
|
|
309
|
+
discordGuildId: channel.discordGuildId ?? null,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const zaloAccountMode = channel.zaloAccountMode ?? 'official';
|
|
314
|
+
|
|
315
|
+
return {
|
|
316
|
+
...base,
|
|
317
|
+
zaloAccountMode,
|
|
318
|
+
zaloOfficialAccountId:
|
|
319
|
+
zaloAccountMode === 'official'
|
|
320
|
+
? (channel.zaloOfficialAccountId ?? null)
|
|
321
|
+
: null,
|
|
322
|
+
zaloPersonalOwnId:
|
|
323
|
+
zaloAccountMode === 'personal'
|
|
324
|
+
? (channel.zaloPersonalOwnId ?? null)
|
|
325
|
+
: null,
|
|
326
|
+
};
|
|
253
327
|
}
|
|
254
328
|
|
|
255
329
|
function readSecretPayload(formData: FormData) {
|