@agent-native/core 0.154.5 → 0.157.0
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/.agents/skills/account-health/SKILL.md +76 -0
- package/corpus/templates/analytics/.agents/skills/bigquery/SKILL.md +3 -0
- package/corpus/templates/analytics/.agents/skills/cross-source-analysis/SKILL.md +2 -1
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +6 -5
- package/corpus/templates/analytics/AGENTS.md +3 -0
- package/corpus/templates/analytics/actions/account-deep-dive.ts +3 -2
- package/corpus/templates/analytics/actions/bigquery.ts +1 -1
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +4 -1
- package/corpus/templates/analytics/app/components/layout/NewDashboardDialog.tsx +1 -0
- package/corpus/templates/analytics/app/pages/adhoc/explorer/components/PropertyCombobox.tsx +12 -4
- package/corpus/templates/analytics/app/pages/adhoc/explorer/components/PropertyValueCombobox.tsx +5 -2
- package/corpus/templates/analytics/app/pages/adhoc/explorer/property-label.ts +32 -0
- package/corpus/templates/analytics/changelog/2026-08-13-account-health-readouts-verify-customer-scope-and-contract-metrics.md +7 -0
- package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +43 -17
- package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +17 -0
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +4 -0
- package/corpus/templates/assets/app/components/asset/AssetPreviewDialog.tsx +3 -1
- package/corpus/templates/assets/app/i18n-data.ts +21 -1
- package/corpus/templates/assets/app/routes/brand-kits.$id.tsx +17 -13
- package/corpus/templates/calendar/AGENTS.md +2 -0
- package/corpus/templates/calendar/DEVELOPING.md +4 -4
- package/corpus/templates/calendar/actions/get-settings.ts +4 -11
- package/corpus/templates/calendar/actions/update-availability.ts +15 -4
- package/corpus/templates/calendar/actions/update-settings.ts +15 -4
- package/corpus/templates/calendar/app/components/booking/DatePicker.tsx +9 -3
- package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +21 -19
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +9 -6
- package/corpus/templates/calendar/app/components/calendar/FindTimePanel.tsx +25 -3
- package/corpus/templates/calendar/app/components/calendar/InlineEventPickers.tsx +10 -3
- package/corpus/templates/calendar/app/components/calendar/MonthView.tsx +9 -9
- package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +11 -3
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +10 -4
- package/corpus/templates/calendar/app/i18n-data.ts +30 -0
- package/corpus/templates/calendar/app/lib/availability-schedule.ts +53 -0
- package/corpus/templates/calendar/app/lib/event-form-utils.ts +5 -0
- package/corpus/templates/calendar/app/pages/AvailabilitySettings.tsx +90 -28
- package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +135 -61
- package/corpus/templates/calendar/app/pages/BookingPage.tsx +2 -0
- package/corpus/templates/calendar/app/pages/CalendarView.tsx +30 -15
- package/corpus/templates/calendar/app/pages/Settings.tsx +60 -1
- package/corpus/templates/calendar/changelog/2026-08-13-find-a-time-now-closes-from-a-clear-header-action.md +6 -0
- package/corpus/templates/calendar/server/handlers/bookings.ts +2 -1
- package/corpus/templates/calendar/server/handlers/settings.ts +12 -16
- package/corpus/templates/calendar/shared/api.ts +1 -0
- package/corpus/templates/calendar/shared/availability-schedule.ts +64 -0
- package/corpus/templates/calendar/shared/calendar-week.ts +21 -0
- package/corpus/templates/calendar/shared/settings.ts +44 -0
- package/corpus/templates/clips/AGENTS.md +2 -0
- package/corpus/templates/clips/actions/add-comment.ts +5 -2
- package/corpus/templates/clips/actions/finalize-recording.ts +31 -1
- package/corpus/templates/clips/actions/get-recording-player-data.ts +9 -0
- package/corpus/templates/clips/actions/lib/ensure-seekable-video.ts +21 -1
- package/corpus/templates/clips/actions/reply-to-comment.ts +5 -2
- package/corpus/templates/clips/actions/update-comment.ts +9 -2
- package/corpus/templates/clips/app/components/library/search-bar.tsx +26 -13
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +135 -3
- package/corpus/templates/clips/app/components/player/comments-panel.tsx +5 -99
- package/corpus/templates/clips/app/components/player/playback-comment-overlay.tsx +7 -3
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +102 -59
- package/corpus/templates/clips/app/components/player/video-player.tsx +84 -24
- package/corpus/templates/clips/app/components/workspace/notifications-list.tsx +11 -3
- package/corpus/templates/clips/app/i18n/en-US.ts +12 -0
- package/corpus/templates/clips/app/lib/public-meeting.ts +11 -3
- package/corpus/templates/clips/app/lib/search-focus.ts +15 -0
- package/corpus/templates/clips/app/root.tsx +2 -1
- package/corpus/templates/clips/app/routes/_app.meetings._index.tsx +94 -26
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +24 -7
- package/corpus/templates/clips/app/routes/embed.$shareId.tsx +8 -4
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +29 -8
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +24 -6
- package/corpus/templates/clips/app/routes/share.meeting.$meetingId.tsx +72 -26
- package/corpus/templates/clips/changelog/2026-08-13-inline-markdown-comments.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-13-private-meeting-agent-links.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +116 -19
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +13 -29
- package/corpus/templates/clips/desktop/src/lib/recording-request.ts +39 -0
- package/corpus/templates/clips/desktop/src/lib/settings-navigation.ts +11 -0
- package/corpus/templates/clips/desktop/src/lib/whisper-model-picker.ts +7 -0
- package/corpus/templates/clips/desktop/src/styles.css +117 -0
- package/corpus/templates/clips/server/db/index.ts +10 -0
- package/corpus/templates/clips/server/db/schema.ts +1 -0
- package/corpus/templates/clips/server/lib/recordings.ts +3 -1
- package/corpus/templates/clips/server/lib/seekable-media-state.ts +90 -0
- package/corpus/templates/clips/server/plugins/db.ts +5 -0
- package/corpus/templates/clips/server/routes/api/public-meeting.get.ts +37 -4
- package/corpus/templates/clips/server/routes/api/public-recording.get.ts +16 -5
- package/corpus/templates/clips/shared/clips-ai-prefs.ts +3 -0
- package/corpus/templates/clips/shared/meeting-agent-access.ts +5 -0
- package/corpus/templates/content/actions/add-comment.ts +2 -1
- package/corpus/templates/content/actions/update-comment.ts +1 -1
- package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +24 -15
- package/corpus/templates/design/actions/generate-design.ts +10 -7
- package/corpus/templates/design/actions/present-design-variants.ts +35 -6
- package/corpus/templates/design/actions/run-design-audit.ts +33 -0
- package/corpus/templates/design/changelog/2026-08-13-the-design-audit-now-catches-a-screen-that-renders-behind-an.md +6 -0
- package/corpus/templates/design/shared/design-review.ts +1 -0
- package/corpus/templates/design/shared/html-integrity.ts +66 -0
- package/corpus/templates/dispatch/.env.example +5 -0
- package/corpus/templates/dispatch/AGENTS.md +24 -19
- package/corpus/templates/dispatch/app/i18n-data.ts +20 -0
- package/corpus/templates/dispatch/server/lib/identity-sso.ts +21 -90
- package/corpus/templates/dispatch/server/plugins/identity-sso.ts +3 -12
- package/corpus/templates/dispatch/shared/feature-flags.ts +4 -0
- package/corpus/templates/factory/AGENTS.md +5 -1
- package/corpus/templates/factory/README.md +23 -0
- package/corpus/templates/factory/actions/view-screen.ts +17 -0
- package/corpus/templates/factory/app/components/factory/FactoryAgentsView.tsx +239 -0
- package/corpus/templates/factory/app/components/factory/FactoryCanvas.tsx +2 -0
- package/corpus/templates/factory/app/components/factory/FactoryInspector.tsx +130 -7
- package/corpus/templates/factory/app/i18n/en-US.ts +20 -0
- package/corpus/templates/factory/app/routes/factory.tsx +41 -0
- package/corpus/templates/factory/package.json +1 -0
- package/corpus/templates/factory/server/factory-graph/contracts.ts +2 -0
- package/corpus/templates/factory/server/plugins/agent-chat.ts +9 -0
- package/corpus/templates/factory/server/plugins/dispatch-db.ts +1 -0
- package/corpus/templates/factory/server/plugins/setup-dispatch.ts +3 -0
- package/corpus/templates/mail/app/lib/native-mcp-exclusions.ts +3 -0
- package/corpus/templates/mail/vite.config.ts +7 -0
- package/corpus/templates/plan/actions/reply-to-plan-comment.ts +7 -2
- package/corpus/templates/plan/actions/resolve-plan-comment.ts +2 -2
- package/corpus/templates/plan/actions/update-visual-plan.ts +1 -1
- package/corpus/templates/plan/app/pages/PlansPage.tsx +29 -20
- package/corpus/templates/slides/actions/add-slide-comment.ts +1 -1
- package/corpus/templates/slides/actions/update-slide-comment.ts +1 -1
- package/corpus/templates/slides/app/components/comments/SlideCommentsPanel.tsx +9 -6
- 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/SlideContextToolbar.tsx +1 -1
- package/corpus/templates/slides/app/context/DeckContext.tsx +42 -2
- 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/pages/DeckEditor.tsx +130 -45
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/production-agent.d.ts +30 -0
- package/dist/agent/production-agent.js +105 -9
- package/dist/agent/thread-data-builder.js +17 -1
- package/dist/agent/types.d.ts +9 -0
- package/dist/cli/skills-content/help.js +6 -4
- package/dist/cli/skills.js +17 -2
- package/dist/cli/workspacify.d.ts +5 -0
- package/dist/cli/workspacify.js +65 -8
- package/dist/client/AgentPanel.d.ts +5 -0
- package/dist/client/AgentPanel.js +32 -13
- package/dist/client/AssistantChat.d.ts +36 -1
- package/dist/client/AssistantChat.js +175 -110
- package/dist/client/MultiTabAssistantChat.js +44 -27
- package/dist/client/active-run-state.d.ts +14 -1
- package/dist/client/active-run-state.js +0 -0
- package/dist/client/agent-chat-adapter.js +107 -5
- package/dist/client/analytics.js +9 -2
- package/dist/client/chat/markdown-renderer.js +4 -2
- 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 +9 -4
- package/dist/client/chat-first/primary-nav.d.ts +2 -1
- package/dist/client/chat-first/primary-nav.js +3 -3
- package/dist/client/chat-first/types.d.ts +5 -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/markdown/InlineMarkdown.d.ts +23 -0
- package/dist/client/markdown/InlineMarkdown.js +65 -0
- package/dist/client/markdown/index.d.ts +1 -0
- package/dist/client/markdown/index.js +1 -0
- package/dist/client/observability/ThumbsFeedback.js +10 -8
- package/dist/client/review/ReviewThreadPanel.js +2 -1
- package/dist/client/run-stream-ownership.d.ts +39 -0
- package/dist/client/run-stream-ownership.js +65 -0
- package/dist/client/sharing/ShareButton.js +160 -54
- 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/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/feature-flags/index.d.ts +1 -1
- package/dist/feature-flags/index.js +1 -1
- package/dist/feature-flags/store.d.ts +10 -0
- package/dist/feature-flags/store.js +112 -1
- package/dist/guards/no-env-credentials.js +4 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/integrations/adapters/slack.js +5 -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 +2 -2
- 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/agents.js +40 -5
- package/dist/resources/metadata.d.ts +10 -0
- package/dist/resources/metadata.js +7 -3
- package/dist/review/actions/create-review-comment.js +1 -1
- package/dist/review/actions/reply-review-comment.js +1 -1
- package/dist/review/actions/resolve-review-thread.js +1 -1
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/action-routes.js +32 -6
- 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-discovery.js +14 -3
- 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/core-routes-plugin.js +1 -1
- package/dist/server/identity-sso-migrations.d.ts +7 -0
- package/dist/server/identity-sso-migrations.js +36 -0
- package/dist/server/identity-sso-store.d.ts +3 -2
- package/dist/server/identity-sso-store.js +8 -3
- package/dist/server/index.d.ts +1 -1
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/release-migrations.js +4 -0
- package/dist/server/request-context.d.ts +7 -0
- package/dist/server/request-context.js +15 -0
- package/dist/tracking/providers.js +13 -3
- package/dist/workspace-files/tool.js +1 -1
- package/docs/content/agent-surfaces.mdx +30 -0
- package/package.json +3 -2
|
@@ -107,6 +107,7 @@ interface WeekViewProps {
|
|
|
107
107
|
) => void;
|
|
108
108
|
onDraftDiscard?: (eventId: string) => void;
|
|
109
109
|
isLoading?: boolean;
|
|
110
|
+
weekStartsOn?: 0 | 1;
|
|
110
111
|
}
|
|
111
112
|
|
|
112
113
|
// [startHour, startMin, durationMin, widthPct] per day column (Sun–Sat)
|
|
@@ -559,6 +560,7 @@ export const WeekView = memo(function WeekView({
|
|
|
559
560
|
onDraftCreate,
|
|
560
561
|
onDraftDiscard,
|
|
561
562
|
isLoading = false,
|
|
563
|
+
weekStartsOn = 0,
|
|
562
564
|
}: WeekViewProps) {
|
|
563
565
|
const t = useT();
|
|
564
566
|
const workingLocationLabels = useMemo(
|
|
@@ -606,8 +608,14 @@ export const WeekView = memo(function WeekView({
|
|
|
606
608
|
}, []);
|
|
607
609
|
|
|
608
610
|
const { prefs } = useViewPreferences();
|
|
609
|
-
const weekStart = useMemo(
|
|
610
|
-
|
|
611
|
+
const weekStart = useMemo(
|
|
612
|
+
() => startOfWeek(selectedDate, { weekStartsOn }),
|
|
613
|
+
[selectedDate, weekStartsOn],
|
|
614
|
+
);
|
|
615
|
+
const weekEnd = useMemo(
|
|
616
|
+
() => endOfWeek(selectedDate, { weekStartsOn }),
|
|
617
|
+
[selectedDate, weekStartsOn],
|
|
618
|
+
);
|
|
611
619
|
// Stable day/hour arrays — recomputed only when the week or weekend
|
|
612
620
|
// visibility actually changes, so memoized children (event buttons) don't
|
|
613
621
|
// see a new array identity on every drag/focus re-render.
|
|
@@ -1408,7 +1416,7 @@ export const WeekView = memo(function WeekView({
|
|
|
1408
1416
|
|
|
1409
1417
|
{/* Skeleton events when loading */}
|
|
1410
1418
|
{isLoading &&
|
|
1411
|
-
WEEK_SKELETONS[
|
|
1419
|
+
WEEK_SKELETONS[day.getDay()]?.map(
|
|
1412
1420
|
([startHour, startMin, duration, widthPct], i) => {
|
|
1413
1421
|
const topPx =
|
|
1414
1422
|
((startHour - START_HOUR) * 60 + startMin) *
|
|
@@ -5,6 +5,7 @@ import { openCommandMenu } from "@agent-native/core/client/navigation";
|
|
|
5
5
|
import { OrgSwitcher } from "@agent-native/core/client/org";
|
|
6
6
|
import { FeedbackButton } from "@agent-native/core/client/ui";
|
|
7
7
|
import { SidebarFooterActions } from "@agent-native/toolkit/app-shell";
|
|
8
|
+
import { getWeekdayOrder, getWeekStartsOn } from "@shared/calendar-week";
|
|
8
9
|
import {
|
|
9
10
|
IconCalendar,
|
|
10
11
|
IconSettings,
|
|
@@ -77,6 +78,7 @@ import {
|
|
|
77
78
|
useRemoveOverlayPerson,
|
|
78
79
|
useUpdateOverlayPersonColor,
|
|
79
80
|
} from "@/hooks/use-overlay-people";
|
|
81
|
+
import { useSettings } from "@/hooks/use-settings";
|
|
80
82
|
import { useViewPreferences } from "@/hooks/use-view-preferences";
|
|
81
83
|
import {
|
|
82
84
|
CALENDAR_COLORS,
|
|
@@ -200,6 +202,8 @@ function MiniCalendar({
|
|
|
200
202
|
}) {
|
|
201
203
|
const [viewMonth, setViewMonth] = useState(() => startOfMonth(selectedDate));
|
|
202
204
|
const [pickerOpen, setPickerOpen] = useState(false);
|
|
205
|
+
const { data: settings } = useSettings();
|
|
206
|
+
const weekStartsOn = getWeekStartsOn(settings?.weekStart);
|
|
203
207
|
|
|
204
208
|
// Sync viewMonth when selectedDate changes to a different month
|
|
205
209
|
useEffect(() => {
|
|
@@ -211,8 +215,8 @@ function MiniCalendar({
|
|
|
211
215
|
const days = useMemo(() => {
|
|
212
216
|
const monthStart = startOfMonth(viewMonth);
|
|
213
217
|
const monthEnd = endOfMonth(viewMonth);
|
|
214
|
-
const calStart = startOfWeek(monthStart);
|
|
215
|
-
const calEnd = endOfWeek(monthEnd);
|
|
218
|
+
const calStart = startOfWeek(monthStart, { weekStartsOn });
|
|
219
|
+
const calEnd = endOfWeek(monthEnd, { weekStartsOn });
|
|
216
220
|
|
|
217
221
|
const result: Date[] = [];
|
|
218
222
|
let current = calStart;
|
|
@@ -221,9 +225,11 @@ function MiniCalendar({
|
|
|
221
225
|
current = addDays(current, 1);
|
|
222
226
|
}
|
|
223
227
|
return result;
|
|
224
|
-
}, [viewMonth]);
|
|
228
|
+
}, [viewMonth, weekStartsOn]);
|
|
225
229
|
|
|
226
|
-
const weekdays =
|
|
230
|
+
const weekdays = getWeekdayOrder(weekStartsOn).map(
|
|
231
|
+
(day) => ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"][day],
|
|
232
|
+
);
|
|
227
233
|
|
|
228
234
|
return (
|
|
229
235
|
<div className="px-3 py-3">
|
|
@@ -265,6 +265,9 @@ const enUS = {
|
|
|
265
265
|
defaultDurationLabel: "Default event duration (minutes)",
|
|
266
266
|
defaultDurationHelp:
|
|
267
267
|
"Default length for new calendar events and booking slots. Booking links can override this per link.",
|
|
268
|
+
weekStartLabel: "Week starts on",
|
|
269
|
+
weekStartSunday: "Sunday - Saturday",
|
|
270
|
+
weekStartMonday: "Monday - Sunday",
|
|
268
271
|
},
|
|
269
272
|
eventDialog: {
|
|
270
273
|
eventUpdated: "Event updated",
|
|
@@ -4303,6 +4306,9 @@ const translatedCalendarExtras = {
|
|
|
4303
4306
|
defaultDurationLabel: "默认事件时长(分钟)",
|
|
4304
4307
|
defaultDurationHelp:
|
|
4305
4308
|
"新日历事件和预约时段的默认长度。预约链接可按链接覆盖此设置。",
|
|
4309
|
+
weekStartLabel: "每周从哪天开始",
|
|
4310
|
+
weekStartSunday: "周日 - 周六",
|
|
4311
|
+
weekStartMonday: "周一 - 周日",
|
|
4306
4312
|
},
|
|
4307
4313
|
eventDialog: {
|
|
4308
4314
|
eventUpdated: "事件已更新",
|
|
@@ -4372,6 +4378,9 @@ const translatedCalendarExtras = {
|
|
|
4372
4378
|
defaultDurationLabel: "Duración predeterminada del evento (minutos)",
|
|
4373
4379
|
defaultDurationHelp:
|
|
4374
4380
|
"Duración predeterminada para eventos nuevos y franjas de reserva. Cada enlace de reserva puede anularla.",
|
|
4381
|
+
weekStartLabel: "La semana empieza el",
|
|
4382
|
+
weekStartSunday: "Domingo - sábado",
|
|
4383
|
+
weekStartMonday: "Lunes - domingo",
|
|
4375
4384
|
},
|
|
4376
4385
|
eventDialog: {
|
|
4377
4386
|
eventUpdated: "Evento actualizado",
|
|
@@ -4442,6 +4451,9 @@ const translatedCalendarExtras = {
|
|
|
4442
4451
|
defaultDurationLabel: "Durée d'événement par défaut (minutes)",
|
|
4443
4452
|
defaultDurationHelp:
|
|
4444
4453
|
"Durée par défaut des nouveaux événements et créneaux de réservation. Chaque lien de réservation peut la remplacer.",
|
|
4454
|
+
weekStartLabel: "La semaine commence le",
|
|
4455
|
+
weekStartSunday: "Dimanche - samedi",
|
|
4456
|
+
weekStartMonday: "Lundi - dimanche",
|
|
4445
4457
|
},
|
|
4446
4458
|
eventDialog: {
|
|
4447
4459
|
eventUpdated: "Événement mis à jour",
|
|
@@ -4512,6 +4524,9 @@ const translatedCalendarExtras = {
|
|
|
4512
4524
|
defaultDurationLabel: "Standarddauer für Ereignisse (Minuten)",
|
|
4513
4525
|
defaultDurationHelp:
|
|
4514
4526
|
"Standardlänge für neue Kalenderereignisse und Buchungsslots. Buchungslinks können sie pro Link überschreiben.",
|
|
4527
|
+
weekStartLabel: "Wochenbeginn",
|
|
4528
|
+
weekStartSunday: "Sonntag - Samstag",
|
|
4529
|
+
weekStartMonday: "Montag - Sonntag",
|
|
4515
4530
|
},
|
|
4516
4531
|
eventDialog: {
|
|
4517
4532
|
eventUpdated: "Ereignis aktualisiert",
|
|
@@ -4581,6 +4596,9 @@ const translatedCalendarExtras = {
|
|
|
4581
4596
|
defaultDurationLabel: "デフォルトのイベント時間(分)",
|
|
4582
4597
|
defaultDurationHelp:
|
|
4583
4598
|
"新しいカレンダーイベントと予約枠のデフォルト時間です。予約リンクごとに上書きできます。",
|
|
4599
|
+
weekStartLabel: "週の開始日",
|
|
4600
|
+
weekStartSunday: "日曜日 - 土曜日",
|
|
4601
|
+
weekStartMonday: "月曜日 - 日曜日",
|
|
4584
4602
|
},
|
|
4585
4603
|
eventDialog: {
|
|
4586
4604
|
eventUpdated: "イベントを更新しました",
|
|
@@ -4647,6 +4665,9 @@ const translatedCalendarExtras = {
|
|
|
4647
4665
|
defaultDurationLabel: "기본 이벤트 시간(분)",
|
|
4648
4666
|
defaultDurationHelp:
|
|
4649
4667
|
"새 캘린더 이벤트와 예약 슬롯의 기본 길이입니다. 예약 링크별로 재정의할 수 있습니다.",
|
|
4668
|
+
weekStartLabel: "주 시작일",
|
|
4669
|
+
weekStartSunday: "일요일 - 토요일",
|
|
4670
|
+
weekStartMonday: "월요일 - 일요일",
|
|
4650
4671
|
},
|
|
4651
4672
|
eventDialog: {
|
|
4652
4673
|
eventUpdated: "이벤트가 업데이트되었습니다",
|
|
@@ -4716,6 +4737,9 @@ const translatedCalendarExtras = {
|
|
|
4716
4737
|
defaultDurationLabel: "Duração padrão do evento (minutos)",
|
|
4717
4738
|
defaultDurationHelp:
|
|
4718
4739
|
"Duração padrão para novos eventos e horários de agendamento. Links de agendamento podem substituir isso por link.",
|
|
4740
|
+
weekStartLabel: "A semana começa no",
|
|
4741
|
+
weekStartSunday: "Domingo - sábado",
|
|
4742
|
+
weekStartMonday: "Segunda-feira - domingo",
|
|
4719
4743
|
},
|
|
4720
4744
|
eventDialog: {
|
|
4721
4745
|
eventUpdated: "Evento atualizado",
|
|
@@ -4784,6 +4808,9 @@ const translatedCalendarExtras = {
|
|
|
4784
4808
|
defaultDurationLabel: "डिफ़ॉल्ट इवेंट अवधि (मिनट)",
|
|
4785
4809
|
defaultDurationHelp:
|
|
4786
4810
|
"नए कैलेंडर इवेंट और बुकिंग स्लॉट की डिफ़ॉल्ट लंबाई। बुकिंग लिंक इसे प्रति लिंक बदल सकते हैं।",
|
|
4811
|
+
weekStartLabel: "सप्ताह की शुरुआत",
|
|
4812
|
+
weekStartSunday: "रविवार - शनिवार",
|
|
4813
|
+
weekStartMonday: "सोमवार - रविवार",
|
|
4787
4814
|
},
|
|
4788
4815
|
eventDialog: {
|
|
4789
4816
|
eventUpdated: "इवेंट अपडेट हो गया",
|
|
@@ -4851,6 +4878,9 @@ const translatedCalendarExtras = {
|
|
|
4851
4878
|
defaultDurationLabel: "مدة الحدث الافتراضية (بالدقائق)",
|
|
4852
4879
|
defaultDurationHelp:
|
|
4853
4880
|
"المدة الافتراضية لأحداث التقويم الجديدة وفتحات الحجز. يمكن لروابط الحجز تجاوزها لكل رابط.",
|
|
4881
|
+
weekStartLabel: "يبدأ الأسبوع يوم",
|
|
4882
|
+
weekStartSunday: "الأحد - السبت",
|
|
4883
|
+
weekStartMonday: "الاثنين - الأحد",
|
|
4854
4884
|
},
|
|
4855
4885
|
eventDialog: {
|
|
4856
4886
|
eventUpdated: "تم تحديث الحدث",
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { DaySchedule, TimeSlot } from "../../shared/api";
|
|
2
|
+
|
|
3
|
+
export const DEFAULT_TIME_SLOT: TimeSlot = {
|
|
4
|
+
start: "09:00",
|
|
5
|
+
end: "17:00",
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export function getEditableTimeSlots(day: DaySchedule): TimeSlot[] {
|
|
9
|
+
return day.slots.length > 0 ? day.slots : [{ ...DEFAULT_TIME_SLOT }];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function setDayEnabled(day: DaySchedule, enabled: boolean): DaySchedule {
|
|
13
|
+
return {
|
|
14
|
+
...day,
|
|
15
|
+
enabled,
|
|
16
|
+
slots: enabled ? getEditableTimeSlots(day) : day.slots,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function updateTimeSlot(
|
|
21
|
+
day: DaySchedule,
|
|
22
|
+
slotIndex: number,
|
|
23
|
+
field: "start" | "end",
|
|
24
|
+
value: string,
|
|
25
|
+
): DaySchedule {
|
|
26
|
+
return {
|
|
27
|
+
...day,
|
|
28
|
+
slots: getEditableTimeSlots(day).map((slot, index) =>
|
|
29
|
+
index === slotIndex ? { ...slot, [field]: value } : slot,
|
|
30
|
+
),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function addTimeSlot(day: DaySchedule): DaySchedule {
|
|
35
|
+
return {
|
|
36
|
+
...day,
|
|
37
|
+
slots: [...getEditableTimeSlots(day), { ...DEFAULT_TIME_SLOT }],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function removeTimeSlot(
|
|
42
|
+
day: DaySchedule,
|
|
43
|
+
slotIndex: number,
|
|
44
|
+
): DaySchedule {
|
|
45
|
+
const slots = getEditableTimeSlots(day).filter(
|
|
46
|
+
(_, index) => index !== slotIndex,
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
...day,
|
|
51
|
+
slots: slots.length > 0 ? slots : [{ ...DEFAULT_TIME_SLOT }],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -230,6 +230,11 @@ export function getLocalTimezone() {
|
|
|
230
230
|
return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
+
/** New event drafts follow the viewer's browser zone unless they name one. */
|
|
234
|
+
export function resolveEventTimezone(timezone?: string | null) {
|
|
235
|
+
return timezone?.trim() || getLocalTimezone();
|
|
236
|
+
}
|
|
237
|
+
|
|
233
238
|
function getTimezoneOffsetMs(date: Date, timezone: string) {
|
|
234
239
|
const parts = new Intl.DateTimeFormat("en-US", {
|
|
235
240
|
timeZone: timezone,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useT } from "@agent-native/core/client/i18n";
|
|
2
2
|
import type { AvailabilityConfig, DaySchedule } from "@shared/api";
|
|
3
|
+
import { IconPlus, IconTrash } from "@tabler/icons-react";
|
|
3
4
|
import { useState, useEffect } from "react";
|
|
4
5
|
import { toast } from "sonner";
|
|
5
6
|
|
|
@@ -21,6 +22,14 @@ import {
|
|
|
21
22
|
useUpdateAvailability,
|
|
22
23
|
} from "@/hooks/use-availability";
|
|
23
24
|
import { useDbStatus } from "@/hooks/use-db-status";
|
|
25
|
+
import {
|
|
26
|
+
DEFAULT_TIME_SLOT,
|
|
27
|
+
addTimeSlot,
|
|
28
|
+
getEditableTimeSlots,
|
|
29
|
+
removeTimeSlot,
|
|
30
|
+
setDayEnabled,
|
|
31
|
+
updateTimeSlot,
|
|
32
|
+
} from "@/lib/availability-schedule";
|
|
24
33
|
import { copyTextToClipboard } from "@/lib/clipboard";
|
|
25
34
|
|
|
26
35
|
type DayName = keyof AvailabilityConfig["weeklySchedule"];
|
|
@@ -37,7 +46,7 @@ const DAYS: { key: DayName }[] = [
|
|
|
37
46
|
|
|
38
47
|
const DEFAULT_SCHEDULE: DaySchedule = {
|
|
39
48
|
enabled: false,
|
|
40
|
-
slots: [{
|
|
49
|
+
slots: [{ ...DEFAULT_TIME_SLOT }],
|
|
41
50
|
};
|
|
42
51
|
|
|
43
52
|
export default function AvailabilitySettings() {
|
|
@@ -93,17 +102,36 @@ export default function AvailabilitySettings() {
|
|
|
93
102
|
function updateDay(day: DayName, updates: Partial<DaySchedule>) {
|
|
94
103
|
setSchedule((prev) => ({
|
|
95
104
|
...prev,
|
|
96
|
-
[day]:
|
|
105
|
+
[day]:
|
|
106
|
+
typeof updates.enabled === "boolean"
|
|
107
|
+
? setDayEnabled(prev[day], updates.enabled)
|
|
108
|
+
: { ...prev[day], ...updates },
|
|
97
109
|
}));
|
|
98
110
|
}
|
|
99
111
|
|
|
100
|
-
function updateDaySlot(
|
|
112
|
+
function updateDaySlot(
|
|
113
|
+
day: DayName,
|
|
114
|
+
slotIndex: number,
|
|
115
|
+
field: "start" | "end",
|
|
116
|
+
value: string,
|
|
117
|
+
) {
|
|
101
118
|
setSchedule((prev) => ({
|
|
102
119
|
...prev,
|
|
103
|
-
[day]:
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
120
|
+
[day]: updateTimeSlot(prev[day], slotIndex, field, value),
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function addDaySlot(day: DayName) {
|
|
125
|
+
setSchedule((prev) => ({
|
|
126
|
+
...prev,
|
|
127
|
+
[day]: addTimeSlot(prev[day]),
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function removeDaySlot(day: DayName, slotIndex: number) {
|
|
132
|
+
setSchedule((prev) => ({
|
|
133
|
+
...prev,
|
|
134
|
+
[day]: removeTimeSlot(prev[day], slotIndex),
|
|
107
135
|
}));
|
|
108
136
|
}
|
|
109
137
|
|
|
@@ -181,7 +209,7 @@ export default function AvailabilitySettings() {
|
|
|
181
209
|
</div>
|
|
182
210
|
{DAYS.map(({ key }) => {
|
|
183
211
|
const day = schedule[key];
|
|
184
|
-
const
|
|
212
|
+
const slots = getEditableTimeSlots(day);
|
|
185
213
|
return (
|
|
186
214
|
<div
|
|
187
215
|
key={key}
|
|
@@ -198,26 +226,60 @@ export default function AvailabilitySettings() {
|
|
|
198
226
|
</div>
|
|
199
227
|
|
|
200
228
|
{day.enabled ? (
|
|
201
|
-
<div className="flex
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
229
|
+
<div className="min-w-0 flex-1 space-y-2">
|
|
230
|
+
{slots.map((slot, slotIndex) => (
|
|
231
|
+
<div
|
|
232
|
+
key={`${key}-${slotIndex}`}
|
|
233
|
+
className="flex flex-wrap items-center gap-2"
|
|
234
|
+
>
|
|
235
|
+
<Input
|
|
236
|
+
type="time"
|
|
237
|
+
value={slot.start}
|
|
238
|
+
onChange={(e) =>
|
|
239
|
+
updateDaySlot(
|
|
240
|
+
key,
|
|
241
|
+
slotIndex,
|
|
242
|
+
"start",
|
|
243
|
+
e.target.value,
|
|
244
|
+
)
|
|
245
|
+
}
|
|
246
|
+
className="w-28 sm:w-32"
|
|
247
|
+
/>
|
|
248
|
+
<span className="text-muted-foreground">
|
|
249
|
+
{t("bookingLinks.to")}
|
|
250
|
+
</span>
|
|
251
|
+
<Input
|
|
252
|
+
type="time"
|
|
253
|
+
value={slot.end}
|
|
254
|
+
onChange={(e) =>
|
|
255
|
+
updateDaySlot(key, slotIndex, "end", e.target.value)
|
|
256
|
+
}
|
|
257
|
+
className="w-28 sm:w-32"
|
|
258
|
+
/>
|
|
259
|
+
{slots.length > 1 && (
|
|
260
|
+
<Button
|
|
261
|
+
type="button"
|
|
262
|
+
variant="ghost"
|
|
263
|
+
size="sm"
|
|
264
|
+
className="h-8 px-2 text-muted-foreground hover:text-destructive"
|
|
265
|
+
onClick={() => removeDaySlot(key, slotIndex)}
|
|
266
|
+
>
|
|
267
|
+
<IconTrash className="mr-1.5 h-3.5 w-3.5" />
|
|
268
|
+
{t("eventForm.delete")}
|
|
269
|
+
</Button>
|
|
270
|
+
)}
|
|
271
|
+
</div>
|
|
272
|
+
))}
|
|
273
|
+
<Button
|
|
274
|
+
type="button"
|
|
275
|
+
variant="ghost"
|
|
276
|
+
size="sm"
|
|
277
|
+
className="h-8 px-2"
|
|
278
|
+
onClick={() => addDaySlot(key)}
|
|
279
|
+
>
|
|
280
|
+
<IconPlus className="mr-1.5 h-3.5 w-3.5" />
|
|
281
|
+
{t("bookingLinks.add")}
|
|
282
|
+
</Button>
|
|
221
283
|
</div>
|
|
222
284
|
) : (
|
|
223
285
|
<span className="text-sm text-muted-foreground">
|