@agent-native/core 0.155.0 → 0.157.1
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/corpus/README.md +1 -1
- package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +19 -4
- package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +7 -2
- package/corpus/templates/assets/app/components/asset/AssetPreviewDialog.tsx +3 -1
- package/corpus/templates/assets/app/global.css +4 -0
- package/corpus/templates/assets/app/i18n-data.ts +21 -1
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +18 -15
- package/corpus/templates/brain/app/routes/sources.tsx +1 -2
- package/corpus/templates/calendar/app/hooks/use-bookings.ts +12 -2
- package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +64 -2
- package/corpus/templates/calendar/server/handlers/bookings.ts +219 -93
- package/corpus/templates/calendar/server/plugins/auth.ts +0 -2
- package/corpus/templates/clips/actions/create-folder.ts +7 -1
- package/corpus/templates/clips/actions/create-meeting.ts +6 -2
- package/corpus/templates/clips/actions/create-recording.ts +5 -3
- package/corpus/templates/clips/actions/finalize-recording.ts +97 -65
- package/corpus/templates/clips/actions/import-loom-recording.ts +5 -3
- package/corpus/templates/clips/actions/request-recording-access.ts +272 -0
- package/corpus/templates/clips/actions/stitch-recordings.ts +5 -3
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +38 -63
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +177 -134
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +3 -21
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +13 -30
- package/corpus/templates/clips/app/i18n/en-US.ts +10 -0
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +5 -5
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +24 -17
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +151 -20
- package/corpus/templates/clips/changelog/2026-08-14-long-resumable-uploads-now-abort-cleanly-and-show-errors.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-14-standardized-share-popovers.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +11 -3
- package/corpus/templates/clips/chrome-extension/src/github-preview-content.ts +37 -8
- package/corpus/templates/clips/chrome-extension/src/github-preview.ts +3 -3
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +8 -25
- package/corpus/templates/clips/desktop/src/app.tsx +24 -0
- package/corpus/templates/clips/desktop/src/lib/media-capture-constraints.ts +42 -13
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +11 -18
- package/corpus/templates/clips/desktop/src/overlays/onboarding.tsx +1 -0
- package/corpus/templates/clips/desktop/src/shared/config.ts +1 -0
- package/corpus/templates/clips/desktop/src/styles.css +24 -9
- package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +3 -0
- package/corpus/templates/clips/desktop/src-tauri/src/config.rs +8 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +154 -176
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +115 -31
- package/corpus/templates/clips/desktop/src-tauri/src/rewind_clip.rs +7 -0
- package/corpus/templates/clips/server/db/index.ts +1 -0
- package/corpus/templates/clips/server/db/schema.ts +1 -0
- package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +6 -1
- package/corpus/templates/clips/server/lib/emails.ts +23 -0
- package/corpus/templates/clips/server/lib/public-agent-context.ts +55 -0
- package/corpus/templates/clips/server/lib/recordings.ts +2 -1
- package/corpus/templates/clips/server/lib/resumable-upload-cleanup.ts +49 -0
- package/corpus/templates/clips/server/lib/s3-upload-provider.ts +34 -7
- package/corpus/templates/clips/server/lib/upload-interruption.ts +15 -1
- package/corpus/templates/clips/server/lib/upload-lease.ts +94 -9
- package/corpus/templates/clips/server/routes/api/agent-context.json.get.ts +82 -7
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +1 -0
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +71 -12
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/interrupt.post.ts +4 -3
- package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +19 -0
- package/corpus/templates/clips/server/routes/api/uploads/reap.post.ts +8 -1
- package/corpus/templates/clips/shared/recording-link.ts +4 -0
- package/corpus/templates/clips/shared/share-loader-response.ts +2 -1
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +7 -16
- package/corpus/templates/factory/AGENTS.md +5 -1
- package/corpus/templates/factory/README.md +6 -2
- package/corpus/templates/factory/actions/view-screen.ts +15 -0
- package/corpus/templates/factory/app/components/factory/FactoryAgentsView.tsx +58 -189
- package/corpus/templates/factory/app/components/layout/Header.tsx +1 -0
- package/corpus/templates/factory/app/components/layout/Layout.tsx +1 -1
- package/corpus/templates/factory/app/components/layout/Sidebar.tsx +7 -0
- package/corpus/templates/factory/app/hooks/use-navigation-state.ts +3 -0
- package/corpus/templates/factory/app/i18n/en-US.ts +3 -1
- package/corpus/templates/factory/app/routes/agents.tsx +9 -0
- package/corpus/templates/mail/server/plugins/auth.ts +0 -2
- package/corpus/templates/plan/app/components/plan/LocalCodebasePicker.tsx +50 -14
- package/corpus/templates/plan/app/pages/PlansPage.tsx +9 -19
- package/corpus/templates/slides/app/components/editor/AddSlidePopover.tsx +98 -29
- package/corpus/templates/slides/app/components/editor/EditorActionCluster.tsx +45 -91
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +94 -2
- package/corpus/templates/slides/app/components/editor/EditorToolbar.tsx +17 -29
- package/corpus/templates/slides/app/components/editor/HistoryPanel.tsx +7 -1
- package/corpus/templates/slides/app/components/editor/SlideContextToolbar.tsx +1 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +108 -19
- package/corpus/templates/slides/app/global.css +7 -40
- package/corpus/templates/slides/app/i18n/en-US.ts +4 -0
- package/corpus/templates/slides/app/lib/editor-shortcuts.ts +46 -0
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +143 -45
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/production-agent.d.ts +30 -0
- package/dist/agent/production-agent.js +100 -8
- package/dist/agent/types.d.ts +9 -0
- package/dist/client/AgentPanel.d.ts +13 -1
- package/dist/client/AgentPanel.js +22 -17
- package/dist/client/AssistantChat.d.ts +15 -1
- package/dist/client/AssistantChat.js +135 -48
- package/dist/client/HighlightedCodeBlock.js +12 -2
- package/dist/client/MultiTabAssistantChat.js +44 -27
- package/dist/client/agent-chat/index.d.ts +1 -0
- package/dist/client/agent-chat/index.js +1 -0
- package/dist/client/chat/markdown-renderer.js +20 -5
- package/dist/client/chat/message-components.d.ts +2 -2
- package/dist/client/chat/message-components.js +69 -35
- package/dist/client/chat/run-recovery.d.ts +4 -1
- package/dist/client/chat/run-recovery.js +62 -30
- package/dist/client/chat/tool-call-display.d.ts +12 -3
- package/dist/client/chat/tool-call-display.js +79 -40
- package/dist/client/chat/widgets/DataChartRenderer.js +3 -1
- package/dist/client/chat/widgets/DataChartWidget.js +8 -2
- package/dist/client/chat/widgets/DataInsightsWidget.js +3 -1
- package/dist/client/chat/widgets/DataTableWidget.js +23 -9
- package/dist/client/chat/widgets/builtin-tool-renderers.js +3 -1
- package/dist/client/chat-first/apps-rail.js +1 -1
- package/dist/client/components/ui/message-scroller.d.ts +1 -1
- package/dist/client/components/ui/message-scroller.js +7 -3
- package/dist/client/composer/runtime-adapters.js +3 -2
- package/dist/client/context-xray/ContextMeter.js +5 -1
- package/dist/client/context-xray/ContextXRayPanel.js +5 -5
- package/dist/client/error-format.d.ts +4 -0
- package/dist/client/error-format.js +93 -5
- package/dist/client/i18n.js +83 -17
- package/dist/client/observability/ThumbsFeedback.js +10 -8
- package/dist/client/settings/AccountSettingsCard.js +48 -19
- package/dist/client/sharing/ShareButton.d.ts +1 -2
- package/dist/client/sharing/ShareButton.js +151 -81
- package/dist/client/sharing/ShareDialog.js +5 -4
- package/dist/client/use-chat-threads.js +10 -14
- package/dist/coding-tools/run-code.js +2 -1
- package/dist/coding-tools/sandbox/background.d.ts +1 -0
- package/dist/coding-tools/sandbox/background.js +8 -1
- package/dist/coding-tools/sandbox/executions-store.d.ts +2 -0
- package/dist/coding-tools/sandbox/executions-store.js +41 -3
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/localization/core-messages/ar-SA.d.ts +3 -0
- package/dist/localization/core-messages/ar-SA.js +541 -0
- package/dist/localization/core-messages/de-DE.d.ts +3 -0
- package/dist/localization/core-messages/de-DE.js +513 -0
- package/dist/localization/core-messages/en-US.d.ts +513 -0
- package/dist/localization/core-messages/en-US.js +513 -0
- package/dist/localization/core-messages/es-ES.d.ts +3 -0
- package/dist/localization/core-messages/es-ES.js +520 -0
- package/dist/localization/core-messages/fr-FR.d.ts +3 -0
- package/dist/localization/core-messages/fr-FR.js +520 -0
- package/dist/localization/core-messages/hi-IN.d.ts +3 -0
- package/dist/localization/core-messages/hi-IN.js +513 -0
- package/dist/localization/core-messages/ja-JP.d.ts +3 -0
- package/dist/localization/core-messages/ja-JP.js +506 -0
- package/dist/localization/core-messages/ko-KR.d.ts +3 -0
- package/dist/localization/core-messages/ko-KR.js +506 -0
- package/dist/localization/core-messages/pt-BR.d.ts +3 -0
- package/dist/localization/core-messages/pt-BR.js +520 -0
- package/dist/localization/core-messages/zh-CN.d.ts +3 -0
- package/dist/localization/core-messages/zh-CN.js +506 -0
- package/dist/localization/core-messages/zh-TW.d.ts +3 -0
- package/dist/localization/core-messages/zh-TW.js +506 -0
- package/dist/localization/core-messages.d.ts +524 -0
- package/dist/localization/core-messages.js +124 -0
- package/dist/localization/default-messages.d.ts +3 -0
- package/dist/localization/default-messages.js +3 -0
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
- package/dist/provider-api/actions/provider-api.d.ts +15 -15
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat/plugin-options.d.ts +7 -2
- package/dist/server/agent-chat-plugin.d.ts +10 -0
- package/dist/server/agent-chat-plugin.js +144 -41
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-run-context.d.ts +7 -1
- package/dist/server/agent-run-context.js +9 -2
- package/dist/server/agent-teams-run-queue.d.ts +3 -0
- package/dist/server/agent-teams.js +38 -9
- package/dist/server/auth-marketing.d.ts +1 -0
- package/dist/server/auth-marketing.js +0 -2
- package/dist/server/auth.d.ts +1 -0
- package/dist/server/auth.js +18 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/onboarding-html.d.ts +1 -0
- package/dist/server/onboarding-html.js +2 -88
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/request-context.d.ts +7 -0
- package/dist/server/request-context.js +15 -0
- package/dist/shared/markdown-block-split.d.ts +16 -0
- package/dist/shared/markdown-block-split.js +81 -5
- package/dist/styles/agent-native.css +13 -0
- package/dist/voice/voice-cleanup-prompt.js +1 -0
- package/docs/content/agent-surfaces.mdx +30 -0
- package/package.json +2 -2
- package/corpus/templates/clips/shared/mic-audio-cleanup.ts +0 -350
package/corpus/README.md
CHANGED
|
@@ -265,7 +265,18 @@ export async function getFirstPartyAnalyticsBigQueryBackfillJob(
|
|
|
265
265
|
async function getNextFirstPartyAnalyticsBigQueryBackfillJob(
|
|
266
266
|
db: Executor,
|
|
267
267
|
now: string,
|
|
268
|
+
scope?: FirstPartyAnalyticsScope,
|
|
268
269
|
): Promise<BigQueryBackfillJob | null> {
|
|
270
|
+
const scopeClauses: string[] = [];
|
|
271
|
+
const args: unknown[] = [now, now];
|
|
272
|
+
if (scope?.orgId) {
|
|
273
|
+
scopeClauses.push("AND org_id = ?");
|
|
274
|
+
args.push(scope.orgId);
|
|
275
|
+
}
|
|
276
|
+
if (scope?.userEmail) {
|
|
277
|
+
scopeClauses.push("AND owner_email = ?");
|
|
278
|
+
args.push(scope.userEmail);
|
|
279
|
+
}
|
|
269
280
|
const result = await db.execute({
|
|
270
281
|
sql: `SELECT id, org_id, owner_email, table_ref, batch_size,
|
|
271
282
|
backfill_cursor, status, copied_count, lease_token,
|
|
@@ -278,9 +289,10 @@ async function getNextFirstPartyAnalyticsBigQueryBackfillJob(
|
|
|
278
289
|
OR (status = 'running' AND lease_expires_at IS NOT NULL
|
|
279
290
|
AND lease_expires_at <= ?)
|
|
280
291
|
)
|
|
292
|
+
${scopeClauses.join("\n ")}
|
|
281
293
|
ORDER BY updated_at ASC
|
|
282
294
|
LIMIT 1`,
|
|
283
|
-
args
|
|
295
|
+
args,
|
|
284
296
|
timeoutMs: 3_000,
|
|
285
297
|
maxAttempts: 1,
|
|
286
298
|
});
|
|
@@ -820,8 +832,8 @@ async function pressureSnapshot(
|
|
|
820
832
|
sql: `SELECT
|
|
821
833
|
COUNT(*) AS total_sessions,
|
|
822
834
|
SUM(CASE WHEN state = 'active' THEN 1 ELSE 0 END) AS active_sessions,
|
|
823
|
-
SUM(CASE WHEN wait_event_type IS NOT NULL THEN 1 ELSE 0 END) AS waiting_sessions,
|
|
824
|
-
SUM(CASE WHEN wait_event_type = 'Lock' THEN 1 ELSE 0 END) AS lock_waiters
|
|
835
|
+
SUM(CASE WHEN state = 'active' AND wait_event_type IS NOT NULL THEN 1 ELSE 0 END) AS waiting_sessions,
|
|
836
|
+
SUM(CASE WHEN state = 'active' AND wait_event_type = 'Lock' THEN 1 ELSE 0 END) AS lock_waiters
|
|
825
837
|
FROM pg_stat_activity
|
|
826
838
|
WHERE pid <> pg_backend_pid()`,
|
|
827
839
|
timeoutMs: 2_000,
|
|
@@ -870,7 +882,9 @@ async function recordPressurePause(
|
|
|
870
882
|
});
|
|
871
883
|
}
|
|
872
884
|
|
|
873
|
-
export async function runFirstPartyAnalyticsBigQueryBackfillOnce(
|
|
885
|
+
export async function runFirstPartyAnalyticsBigQueryBackfillOnce(
|
|
886
|
+
scope?: FirstPartyAnalyticsScope,
|
|
887
|
+
): Promise<BigQueryBackfillSweepResult> {
|
|
874
888
|
if (process.env.ANALYTICS_BIGQUERY_BACKFILL_JOBS?.trim() === "0") {
|
|
875
889
|
return { status: "disabled", batches: 0, copied: 0, remaining: 0 };
|
|
876
890
|
}
|
|
@@ -879,6 +893,7 @@ export async function runFirstPartyAnalyticsBigQueryBackfillOnce(): Promise<BigQ
|
|
|
879
893
|
const coordinator = await getNextFirstPartyAnalyticsBigQueryBackfillJob(
|
|
880
894
|
db,
|
|
881
895
|
new Date().toISOString(),
|
|
896
|
+
scope,
|
|
882
897
|
);
|
|
883
898
|
if (!coordinator) {
|
|
884
899
|
return { status: "idle", batches: 0, copied: 0, remaining: 0 };
|
|
@@ -913,7 +913,8 @@ function addPartitionPrunedEventDeduplication(
|
|
|
913
913
|
}
|
|
914
914
|
result +=
|
|
915
915
|
sql.slice(cursor, predicateEnd) +
|
|
916
|
-
" QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY received_at DESC) = 1"
|
|
916
|
+
" QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY received_at DESC) = 1" +
|
|
917
|
+
(predicateEnd < sql.length ? " " : "");
|
|
917
918
|
cursor = predicateEnd;
|
|
918
919
|
}
|
|
919
920
|
return result;
|
|
@@ -1405,7 +1406,11 @@ export async function backfillFirstPartyAnalyticsBatch(
|
|
|
1405
1406
|
const selectedRows = rows.slice(0, boundedLimit);
|
|
1406
1407
|
if (!selectedRows.length) {
|
|
1407
1408
|
return {
|
|
1408
|
-
|
|
1409
|
+
// An empty shard has no tuple cursor. Returning the sentinel empty
|
|
1410
|
+
// cursor makes the shard worker reject an otherwise successful drain.
|
|
1411
|
+
nextCursor: parsedCursor.receivedAt
|
|
1412
|
+
? serializeBackfillCursor(parsedCursor)
|
|
1413
|
+
: null,
|
|
1409
1414
|
copied: 0,
|
|
1410
1415
|
complete: true,
|
|
1411
1416
|
};
|
|
@@ -159,7 +159,9 @@ export function AssetPreviewDialog({
|
|
|
159
159
|
onClick={() => setShowDetails((value) => !value)}
|
|
160
160
|
>
|
|
161
161
|
<IconInfoCircle className="h-4 w-4" />
|
|
162
|
-
{
|
|
162
|
+
{showDetails
|
|
163
|
+
? t("library.hideDetails")
|
|
164
|
+
: t("library.viewDetails")}
|
|
163
165
|
</Button>
|
|
164
166
|
<DialogClose
|
|
165
167
|
aria-label={t("library.closePreview")}
|
|
@@ -844,10 +844,11 @@ const enUS = {
|
|
|
844
844
|
checking: "Checking",
|
|
845
845
|
checkingUpload: "Checking upload",
|
|
846
846
|
clearAll: "Clear all",
|
|
847
|
+
clearAllWithCount: "Clear all candidates ({{count}})",
|
|
847
848
|
clearCandidates: "Clear candidates",
|
|
848
849
|
clearCandidatesTitle: "Clear {{count}} candidates?",
|
|
849
850
|
clearCandidatesDescription:
|
|
850
|
-
"Clears the live stage and deletes unsaved draft
|
|
851
|
+
"Clears the live stage and deletes every unsaved draft candidate. Saved library assets stay untouched.",
|
|
851
852
|
clearGeneratedCandidatesTitle: "Clear generated candidates?",
|
|
852
853
|
clearGeneratedCandidatesDescription:
|
|
853
854
|
"This removes every unsaved candidate from the thread and deletes the generated asset rows behind them. Saved library assets are not touched.",
|
|
@@ -986,6 +987,7 @@ const enUS = {
|
|
|
986
987
|
open: "Open",
|
|
987
988
|
openAssets: "Open Assets",
|
|
988
989
|
openChat: "Open chat",
|
|
990
|
+
hideDetails: "Hide details",
|
|
989
991
|
openDetails: "Open details",
|
|
990
992
|
preparing: "Preparing...",
|
|
991
993
|
previousImage: "Previous image",
|
|
@@ -3728,7 +3730,9 @@ export const messagesByLocale = {
|
|
|
3728
3730
|
checkingUpload: "正在检查上传",
|
|
3729
3731
|
clear: "清除",
|
|
3730
3732
|
clearAll: "全部清除",
|
|
3733
|
+
clearAllWithCount: "清除所有候选项({{count}})",
|
|
3731
3734
|
clearCandidates: "清除候选项",
|
|
3735
|
+
hideDetails: "隐藏详情",
|
|
3732
3736
|
clearCandidatesDescription: "清除实时阶段并删除未保存的草稿候选项。",
|
|
3733
3737
|
clearCandidatesTitle: "清除 {{count}} 个候选项?",
|
|
3734
3738
|
clearGeneratedCandidatesDescription:
|
|
@@ -4552,7 +4556,9 @@ export const messagesByLocale = {
|
|
|
4552
4556
|
checkingImageLibraries: "Comprobando bibliotecas de imágenes...",
|
|
4553
4557
|
checkingUpload: "Comprobando carga",
|
|
4554
4558
|
clearAll: "Borrar todo",
|
|
4559
|
+
clearAllWithCount: "Borrar todos los candidatos ({{count}})",
|
|
4555
4560
|
clearCandidates: "Limpiar candidatos",
|
|
4561
|
+
hideDetails: "Ocultar detalles",
|
|
4556
4562
|
clearCandidatesDescription:
|
|
4557
4563
|
"Limpia la etapa en vivo y elimina los candidatos de borrador no guardados.",
|
|
4558
4564
|
clearGeneratedCandidatesDescription:
|
|
@@ -5026,7 +5032,9 @@ export const messagesByLocale = {
|
|
|
5026
5032
|
checkingImageLibraries: "Vérification des bibliothèques d'images...",
|
|
5027
5033
|
checkingUpload: "Vérification du téléchargement",
|
|
5028
5034
|
clearAll: "Tout effacer",
|
|
5035
|
+
clearAllWithCount: "Effacer tous les candidats ({{count}})",
|
|
5029
5036
|
clearCandidates: "Effacer les candidats",
|
|
5037
|
+
hideDetails: "Masquer les détails",
|
|
5030
5038
|
clearCandidatesDescription:
|
|
5031
5039
|
"Efface l'étape en direct et supprime les candidats de brouillon non enregistrés.",
|
|
5032
5040
|
clearGeneratedCandidatesDescription:
|
|
@@ -5479,7 +5487,9 @@ export const messagesByLocale = {
|
|
|
5479
5487
|
checkingImageLibraries: "Bildbibliotheken werden geprüft...",
|
|
5480
5488
|
checkingUpload: "Upload wird überprüft",
|
|
5481
5489
|
clearAll: "Alles löschen",
|
|
5490
|
+
clearAllWithCount: "Alle Kandidaten löschen ({{count}})",
|
|
5482
5491
|
clearCandidates: "Kandidaten löschen",
|
|
5492
|
+
hideDetails: "Details ausblenden",
|
|
5483
5493
|
clearCandidatesDescription:
|
|
5484
5494
|
"Löscht die Live-Phase und entfernt nicht gespeicherte Entwurfskandidaten.",
|
|
5485
5495
|
clearGeneratedCandidatesDescription:
|
|
@@ -5837,7 +5847,9 @@ export const messagesByLocale = {
|
|
|
5837
5847
|
checkingImageLibraries: "画像ライブラリを確認中...",
|
|
5838
5848
|
checkingUpload: "アップロードを確認しています",
|
|
5839
5849
|
clearAll: "すべてクリア",
|
|
5850
|
+
clearAllWithCount: "候補をすべてクリア({{count}})",
|
|
5840
5851
|
clearCandidates: "候補をクリアする",
|
|
5852
|
+
hideDetails: "詳細を非表示",
|
|
5841
5853
|
clearCandidatesDescription:
|
|
5842
5854
|
"ライブ ステージをクリアし、保存されていないドラフト候補を削除します。",
|
|
5843
5855
|
clearGeneratedCandidatesDescription:
|
|
@@ -6186,7 +6198,9 @@ export const messagesByLocale = {
|
|
|
6186
6198
|
checkingImageLibraries: "이미지 라이브러리 확인 중...",
|
|
6187
6199
|
checkingUpload: "업로드 확인 중",
|
|
6188
6200
|
clearAll: "모두 지우기",
|
|
6201
|
+
clearAllWithCount: "후보 모두 지우기({{count}})",
|
|
6189
6202
|
clearCandidates: "후보 제거",
|
|
6203
|
+
hideDetails: "세부정보 숨기기",
|
|
6190
6204
|
clearCandidatesDescription:
|
|
6191
6205
|
"라이브 단계를 지우고 저장되지 않은 초안 후보를 삭제합니다.",
|
|
6192
6206
|
clearGeneratedCandidatesDescription:
|
|
@@ -6534,7 +6548,9 @@ export const messagesByLocale = {
|
|
|
6534
6548
|
checkingImageLibraries: "Verificando bibliotecas de imagens...",
|
|
6535
6549
|
checkingUpload: "Verificando upload",
|
|
6536
6550
|
clearAll: "Limpar tudo",
|
|
6551
|
+
clearAllWithCount: "Limpar todos os candidatos ({{count}})",
|
|
6537
6552
|
clearCandidates: "Limpar candidatos",
|
|
6553
|
+
hideDetails: "Ocultar detalhes",
|
|
6538
6554
|
clearCandidatesDescription:
|
|
6539
6555
|
"Limpa o estágio ao vivo e exclui candidatos de rascunho não salvos.",
|
|
6540
6556
|
clearGeneratedCandidatesDescription:
|
|
@@ -6985,7 +7001,9 @@ export const messagesByLocale = {
|
|
|
6985
7001
|
checkingImageLibraries: "Image libraries जांची जा रही हैं...",
|
|
6986
7002
|
checkingUpload: "अपलोड की जाँच की जा रही है",
|
|
6987
7003
|
clearAll: "सभी साफ करें",
|
|
7004
|
+
clearAllWithCount: "सभी उम्मीदवार साफ करें ({{count}})",
|
|
6988
7005
|
clearCandidates: "उम्मीदवारों को साफ करें",
|
|
7006
|
+
hideDetails: "विवरण छिपाएं",
|
|
6989
7007
|
clearCandidatesDescription:
|
|
6990
7008
|
"लाइव चरण को साफ करता है और अ सहेजे गए ड्राफ्ट उम्मीदवारों को हटाता है।",
|
|
6991
7009
|
clearGeneratedCandidatesDescription:
|
|
@@ -7331,7 +7349,9 @@ export const messagesByLocale = {
|
|
|
7331
7349
|
checkingImageLibraries: "جارٍ فحص مكتبات الصور...",
|
|
7332
7350
|
checkingUpload: "التحقق من التحميل",
|
|
7333
7351
|
clearAll: "مسح الكل",
|
|
7352
|
+
clearAllWithCount: "مسح كل المرشحين ({{count}})",
|
|
7334
7353
|
clearCandidates: "امسح المرشحين",
|
|
7354
|
+
hideDetails: "إخفاء التفاصيل",
|
|
7335
7355
|
clearCandidatesDescription:
|
|
7336
7356
|
"مسح مرحلة المرشح وحذف المرشحين الذين تم إنشاؤهم غير المحفوظة. أصول المكتبة المحفوظة تبقى دون تغيير.",
|
|
7337
7357
|
clearGeneratedCandidatesDescription:
|
|
@@ -1217,12 +1217,11 @@ export function BrandKitDetailRoute({
|
|
|
1217
1217
|
);
|
|
1218
1218
|
const shareAction = (
|
|
1219
1219
|
<ShareButton
|
|
1220
|
-
trigger="label-icon"
|
|
1221
1220
|
resourceType="asset-library"
|
|
1222
1221
|
resourceId={library.id}
|
|
1223
1222
|
allowedRoles={["viewer", "editor", "admin"]}
|
|
1224
1223
|
resourceTitle={library.title}
|
|
1225
|
-
triggerClassName="h-10
|
|
1224
|
+
triggerClassName="h-10 px-4 border-input bg-background hover:bg-accent hover:text-accent-foreground"
|
|
1226
1225
|
/>
|
|
1227
1226
|
);
|
|
1228
1227
|
const headerActions = (
|
|
@@ -4533,7 +4532,9 @@ function LiveCandidatesActions({
|
|
|
4533
4532
|
const hasFailed = failedCount > 0;
|
|
4534
4533
|
const isClearing = dismissSlots.isPending || deleteAssets.isPending;
|
|
4535
4534
|
const actionLabel =
|
|
4536
|
-
pending === "failed"
|
|
4535
|
+
pending === "failed"
|
|
4536
|
+
? t("library.dismissFailed")
|
|
4537
|
+
: t("library.clearAllWithCount", { count: totalCount });
|
|
4537
4538
|
const busyLabel =
|
|
4538
4539
|
pending === "failed" ? t("library.dismissing") : t("library.clearing");
|
|
4539
4540
|
|
|
@@ -4645,26 +4646,28 @@ function LiveCandidatesActions({
|
|
|
4645
4646
|
</Button>
|
|
4646
4647
|
</DropdownMenuTrigger>
|
|
4647
4648
|
<DropdownMenuContent align="end">
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
event
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4649
|
+
{hasFailed ? (
|
|
4650
|
+
<DropdownMenuItem
|
|
4651
|
+
disabled={isClearing}
|
|
4652
|
+
onSelect={(event) => {
|
|
4653
|
+
event.preventDefault();
|
|
4654
|
+
setPending("failed");
|
|
4655
|
+
}}
|
|
4656
|
+
>
|
|
4657
|
+
<IconTrash className="mr-2 h-4 w-4 shrink-0" />
|
|
4658
|
+
{t("library.dismissFailedWithCount", { count: failedCount })}
|
|
4659
|
+
</DropdownMenuItem>
|
|
4660
|
+
) : null}
|
|
4658
4661
|
<DropdownMenuItem
|
|
4659
4662
|
className="text-destructive focus:bg-destructive/10 focus:text-destructive"
|
|
4660
|
-
disabled={isClearing}
|
|
4663
|
+
disabled={isClearing || totalCount === 0}
|
|
4661
4664
|
onSelect={(event) => {
|
|
4662
4665
|
event.preventDefault();
|
|
4663
4666
|
setPending("all");
|
|
4664
4667
|
}}
|
|
4665
4668
|
>
|
|
4666
4669
|
<IconTrash className="mr-2 h-4 w-4 shrink-0" />
|
|
4667
|
-
{t("library.
|
|
4670
|
+
{t("library.clearAllWithCount", { count: totalCount })}
|
|
4668
4671
|
</DropdownMenuItem>
|
|
4669
4672
|
</DropdownMenuContent>
|
|
4670
4673
|
</DropdownMenu>
|
|
@@ -1875,8 +1875,7 @@ function SourceListItem({
|
|
|
1875
1875
|
resourceId={source.id}
|
|
1876
1876
|
allowedRoles={["viewer", "editor", "admin"]}
|
|
1877
1877
|
resourceTitle={sourceName(source)}
|
|
1878
|
-
|
|
1879
|
-
triggerClassName="size-8"
|
|
1878
|
+
triggerClassName="h-8 px-2"
|
|
1880
1879
|
/>
|
|
1881
1880
|
|
|
1882
1881
|
<DropdownMenu>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useActionQuery } from "@agent-native/core/client/hooks";
|
|
2
|
-
import type { Booking } from "@shared/api";
|
|
2
|
+
import type { Booking, BookingHost } from "@shared/api";
|
|
3
3
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
|
4
4
|
|
|
5
5
|
import { appApiPath } from "@/lib/api-path";
|
|
@@ -17,16 +17,26 @@ export function useBookings() {
|
|
|
17
17
|
return useActionQuery<Booking[]>("list-bookings");
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
export type BookingAvailabilityPreview = {
|
|
21
|
+
slug: string;
|
|
22
|
+
durations: number[];
|
|
23
|
+
hosts: BookingHost[];
|
|
24
|
+
};
|
|
25
|
+
|
|
20
26
|
export function useAvailableSlots(
|
|
21
27
|
date: string,
|
|
22
28
|
duration: number,
|
|
23
29
|
slug?: string,
|
|
30
|
+
draft?: BookingAvailabilityPreview,
|
|
24
31
|
) {
|
|
32
|
+
const draftParam = draft ? JSON.stringify(draft) : undefined;
|
|
33
|
+
|
|
25
34
|
return useQuery<{ start: string; end: string }[]>({
|
|
26
|
-
queryKey: ["available-slots", date, duration, slug],
|
|
35
|
+
queryKey: ["available-slots", date, duration, slug, draftParam],
|
|
27
36
|
queryFn: async () => {
|
|
28
37
|
const params = new URLSearchParams({ date, duration: String(duration) });
|
|
29
38
|
if (slug) params.set("slug", slug);
|
|
39
|
+
if (draftParam) params.set("draft", draftParam);
|
|
30
40
|
const res = await fetch(
|
|
31
41
|
appApiPath(`/api/bookings/available-slots?${params}`),
|
|
32
42
|
);
|
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
addMonths,
|
|
47
47
|
subMonths,
|
|
48
48
|
format,
|
|
49
|
+
parseISO,
|
|
49
50
|
startOfDay,
|
|
50
51
|
getDay,
|
|
51
52
|
} from "date-fns";
|
|
@@ -113,6 +114,10 @@ import {
|
|
|
113
114
|
useUpdateBookingLink,
|
|
114
115
|
OPTIMISTIC_PREFIX,
|
|
115
116
|
} from "@/hooks/use-booking-links";
|
|
117
|
+
import {
|
|
118
|
+
useAvailableSlots,
|
|
119
|
+
type BookingAvailabilityPreview,
|
|
120
|
+
} from "@/hooks/use-bookings";
|
|
116
121
|
import { useGoogleAuthStatus } from "@/hooks/use-google-auth";
|
|
117
122
|
import { useSettings } from "@/hooks/use-settings";
|
|
118
123
|
import { useZoomStatus, useConnectZoom } from "@/hooks/use-zoom-auth";
|
|
@@ -826,6 +831,14 @@ export default function BookingLinksPage({
|
|
|
826
831
|
!!selectedLink &&
|
|
827
832
|
savedDraftSignature !== null &&
|
|
828
833
|
draftSignature !== savedDraftSignature;
|
|
834
|
+
const availabilityPreview =
|
|
835
|
+
selectedLink && !selectedLink.id.startsWith(OPTIMISTIC_PREFIX)
|
|
836
|
+
? ({
|
|
837
|
+
slug: slugify(draft.slug),
|
|
838
|
+
durations: draft.durations,
|
|
839
|
+
hosts: draft.hosts,
|
|
840
|
+
} satisfies BookingAvailabilityPreview)
|
|
841
|
+
: undefined;
|
|
829
842
|
|
|
830
843
|
function handleCreate() {
|
|
831
844
|
setCreateDialogOpen(true);
|
|
@@ -1535,6 +1548,13 @@ export default function BookingLinksPage({
|
|
|
1535
1548
|
customFields={draft.customFields}
|
|
1536
1549
|
isActive={draft.isActive}
|
|
1537
1550
|
availability={availability ?? undefined}
|
|
1551
|
+
bookingSourceSlug={
|
|
1552
|
+
selectedLink.id?.startsWith(OPTIMISTIC_PREFIX) ||
|
|
1553
|
+
!availabilityPreview
|
|
1554
|
+
? undefined
|
|
1555
|
+
: selectedLink.slug
|
|
1556
|
+
}
|
|
1557
|
+
availabilityPreview={availabilityPreview}
|
|
1538
1558
|
bookingUrl={previewUrl}
|
|
1539
1559
|
onCopy={() => void copyPreviewUrl(draft.slug)}
|
|
1540
1560
|
openHref={bookingPreviewPath(draft.slug)}
|
|
@@ -2022,6 +2042,8 @@ function BookingPreview({
|
|
|
2022
2042
|
customFields = [],
|
|
2023
2043
|
isActive,
|
|
2024
2044
|
availability,
|
|
2045
|
+
bookingSourceSlug,
|
|
2046
|
+
availabilityPreview,
|
|
2025
2047
|
bookingUrl,
|
|
2026
2048
|
onCopy,
|
|
2027
2049
|
openHref,
|
|
@@ -2034,6 +2056,8 @@ function BookingPreview({
|
|
|
2034
2056
|
customFields?: CustomField[];
|
|
2035
2057
|
isActive: boolean;
|
|
2036
2058
|
availability?: AvailabilityConfig;
|
|
2059
|
+
bookingSourceSlug?: string;
|
|
2060
|
+
availabilityPreview?: BookingAvailabilityPreview;
|
|
2037
2061
|
bookingUrl?: string;
|
|
2038
2062
|
onCopy?: () => void;
|
|
2039
2063
|
openHref?: string;
|
|
@@ -2062,6 +2086,24 @@ function BookingPreview({
|
|
|
2062
2086
|
fieldResponses: {},
|
|
2063
2087
|
});
|
|
2064
2088
|
|
|
2089
|
+
const liveAvailabilityDate =
|
|
2090
|
+
bookingSourceSlug && selectedDate ? format(selectedDate, "yyyy-MM-dd") : "";
|
|
2091
|
+
const liveAvailabilityDuration =
|
|
2092
|
+
selectedDuration !== null && durations.includes(selectedDuration)
|
|
2093
|
+
? selectedDuration
|
|
2094
|
+
: primaryDuration;
|
|
2095
|
+
const {
|
|
2096
|
+
data: liveSlots = [],
|
|
2097
|
+
isLoading: liveSlotsLoading,
|
|
2098
|
+
isError: liveSlotsError,
|
|
2099
|
+
} = useAvailableSlots(
|
|
2100
|
+
liveAvailabilityDate,
|
|
2101
|
+
liveAvailabilityDuration,
|
|
2102
|
+
bookingSourceSlug,
|
|
2103
|
+
availabilityPreview,
|
|
2104
|
+
);
|
|
2105
|
+
const hasLiveAvailability = Boolean(bookingSourceSlug && selectedDate);
|
|
2106
|
+
|
|
2065
2107
|
// Reset selections when durations change
|
|
2066
2108
|
useEffect(() => {
|
|
2067
2109
|
setSelectedDuration(null);
|
|
@@ -2092,6 +2134,9 @@ function BookingPreview({
|
|
|
2092
2134
|
|
|
2093
2135
|
// Generate realistic time slots based on availability
|
|
2094
2136
|
const timeSlots = useMemo(() => {
|
|
2137
|
+
if (hasLiveAvailability) {
|
|
2138
|
+
return liveSlots.map((slot) => format(parseISO(slot.start), "h:mm a"));
|
|
2139
|
+
}
|
|
2095
2140
|
if (!selectedDate || !availability) {
|
|
2096
2141
|
return ["9:00 AM", "9:30 AM", "10:00 AM", "10:30 AM", "11:00 AM"];
|
|
2097
2142
|
}
|
|
@@ -2122,7 +2167,14 @@ function BookingPreview({
|
|
|
2122
2167
|
}
|
|
2123
2168
|
}
|
|
2124
2169
|
return slots;
|
|
2125
|
-
}, [
|
|
2170
|
+
}, [
|
|
2171
|
+
selectedDate,
|
|
2172
|
+
selectedDuration,
|
|
2173
|
+
primaryDuration,
|
|
2174
|
+
availability,
|
|
2175
|
+
hasLiveAvailability,
|
|
2176
|
+
liveSlots,
|
|
2177
|
+
]);
|
|
2126
2178
|
|
|
2127
2179
|
// Determine which step to show
|
|
2128
2180
|
const [forcedStep, setForcedStep] = useState<BookingPreviewStep | null>(null);
|
|
@@ -2458,7 +2510,17 @@ function BookingPreview({
|
|
|
2458
2510
|
{t("bookingLinks.availableTimes")}
|
|
2459
2511
|
</p>
|
|
2460
2512
|
)}
|
|
2461
|
-
{
|
|
2513
|
+
{liveSlotsLoading ? (
|
|
2514
|
+
<div className="grid grid-cols-3 gap-1.5">
|
|
2515
|
+
{Array.from({ length: 6 }).map((_, index) => (
|
|
2516
|
+
<Skeleton key={index} className="h-8 rounded-md" />
|
|
2517
|
+
))}
|
|
2518
|
+
</div>
|
|
2519
|
+
) : liveSlotsError ? (
|
|
2520
|
+
<p className="rounded-md border border-destructive/30 bg-destructive/[0.06] px-2.5 py-2 text-center text-xs text-destructive">
|
|
2521
|
+
{t("bookingLinks.availabilityUnavailable")}
|
|
2522
|
+
</p>
|
|
2523
|
+
) : timeSlots.length > 0 ? (
|
|
2462
2524
|
<div className="grid grid-cols-3 gap-1.5">
|
|
2463
2525
|
{timeSlots.map((slot) => (
|
|
2464
2526
|
<button
|