@agent-native/core 0.101.6 → 0.101.10
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/core/CHANGELOG.md +28 -0
- package/corpus/core/docs/content/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/ar-SA/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/de-DE/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/es-ES/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/fr-FR/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/hi-IN/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/ja-JP/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/ko-KR/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/pt-BR/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/zh-CN/deployment.mdx +9 -7
- package/corpus/core/docs/content/locales/zh-TW/deployment.mdx +9 -7
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/a2a/artifact-response.ts +255 -12
- package/corpus/core/src/agent/thread-data-builder.ts +84 -11
- package/corpus/core/src/client/review/ReviewCommentComposer.tsx +9 -1
- package/corpus/core/src/client/review/ReviewThreadPanel.tsx +17 -2
- package/corpus/core/src/client/settings/SettingsPanel.tsx +41 -21
- package/corpus/core/src/client/settings/useBuilderStatus.ts +28 -9
- package/corpus/core/src/client/setup-connections/BuilderConnectCard.tsx +2 -7
- package/corpus/core/src/integrations/a2a-continuation-processor.ts +99 -7
- package/corpus/core/src/integrations/adapters/discord.ts +3 -1
- package/corpus/core/src/integrations/adapters/email.ts +4 -1
- package/corpus/core/src/integrations/adapters/google-docs.ts +4 -1
- package/corpus/core/src/integrations/adapters/microsoft-teams.ts +3 -1
- package/corpus/core/src/integrations/adapters/slack.ts +38 -9
- package/corpus/core/src/integrations/adapters/telegram.ts +32 -10
- package/corpus/core/src/integrations/adapters/whatsapp.ts +5 -1
- package/corpus/core/src/integrations/index.ts +1 -0
- package/corpus/core/src/integrations/types.ts +9 -2
- package/corpus/core/src/integrations/webhook-handler.ts +69 -45
- package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +1 -0
- package/corpus/core/src/server/auth.ts +25 -1
- package/corpus/core/src/server/builder-browser.ts +353 -1
- package/corpus/core/src/server/core-routes-plugin.ts +601 -223
- package/corpus/templates/calendar/app/components/calendar/DayView.tsx +80 -1
- package/corpus/templates/calendar/app/components/calendar/EventCard.tsx +28 -3
- package/corpus/templates/calendar/app/components/calendar/EventDetailPanel.tsx +5 -1
- package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +30 -3
- package/corpus/templates/calendar/app/components/calendar/OutOfOfficeEvent.tsx +196 -0
- package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +115 -1
- package/corpus/templates/calendar/app/lib/out-of-office.ts +45 -0
- package/corpus/templates/calendar/changelog/2026-07-14-out-of-office-blocks-now-sit-behind-meetings-and-event-stack.md +6 -0
- package/corpus/templates/content/.agents/skills/content/SKILL.md +31 -0
- package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +35 -21
- package/corpus/templates/content/AGENTS.md +32 -9
- package/corpus/templates/content/actions/_builder-cms-intent-lookup.ts +87 -0
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +173 -25
- package/corpus/templates/content/actions/_builder-cms-source-adapter.ts +1 -0
- package/corpus/templates/content/actions/_builder-cms-write-adapter.ts +427 -18
- package/corpus/templates/content/actions/_builder-cms-write-client.ts +17 -73
- package/corpus/templates/content/actions/_builder-cms-write-settings.ts +27 -7
- package/corpus/templates/content/actions/_builder-source-execution-claim.ts +124 -0
- package/corpus/templates/content/actions/_builder-source-execution-preservation.ts +21 -0
- package/corpus/templates/content/actions/_builder-source-timings.ts +57 -0
- package/corpus/templates/content/actions/_database-source-utils.ts +1071 -170
- package/corpus/templates/content/actions/_database-utils.ts +104 -13
- package/corpus/templates/content/actions/_local-file-documents.ts +53 -1
- package/corpus/templates/content/actions/_preview-document-draft.ts +31 -0
- package/corpus/templates/content/actions/_property-utils.ts +7 -1
- package/corpus/templates/content/actions/cancel-prepared-builder-source-update.ts +309 -0
- package/corpus/templates/content/actions/configure-document-property.ts +11 -0
- package/corpus/templates/content/actions/create-content-database.ts +11 -0
- package/corpus/templates/content/actions/create-document.ts +9 -0
- package/corpus/templates/content/actions/create-inline-content-database.ts +3 -0
- package/corpus/templates/content/actions/execute-builder-source-batch.ts +120 -49
- package/corpus/templates/content/actions/execute-builder-source-execution.ts +608 -264
- package/corpus/templates/content/actions/export-content-source.ts +1 -0
- package/corpus/templates/content/actions/get-content-database.ts +13 -1
- package/corpus/templates/content/actions/get-document.ts +12 -2
- package/corpus/templates/content/actions/get-preview-document-draft.ts +26 -0
- package/corpus/templates/content/actions/import-content-source.ts +6 -0
- package/corpus/templates/content/actions/list-documents.ts +3 -0
- package/corpus/templates/content/actions/materialize-builder-required-fields.ts +550 -0
- package/corpus/templates/content/actions/prepare-builder-source-execution.ts +112 -65
- package/corpus/templates/content/actions/prepare-builder-source-review.ts +463 -170
- package/corpus/templates/content/actions/preview-builder-source-review.ts +99 -0
- package/corpus/templates/content/actions/pull-document.ts +2 -0
- package/corpus/templates/content/actions/search-documents.ts +5 -1
- package/corpus/templates/content/actions/set-content-database-source-write-mode.ts +2 -2
- package/corpus/templates/content/actions/update-document.ts +16 -1
- package/corpus/templates/content/actions/update-preview-document-draft.ts +153 -0
- package/corpus/templates/content/actions/view-screen.ts +15 -2
- package/corpus/templates/content/app/components/editor/DescriptionField.tsx +121 -0
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +14 -0
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +250 -49
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +57 -5
- package/corpus/templates/content/app/components/editor/body-hydration.ts +27 -0
- package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +2414 -589
- package/corpus/templates/content/app/components/editor/database/settings.tsx +13 -10
- package/corpus/templates/content/app/components/editor/database-sources/BuilderSourceReviewDialog.tsx +358 -75
- package/corpus/templates/content/app/components/editor/previewDocumentSaveController.ts +124 -29
- package/corpus/templates/content/app/components/editor/previewDocumentSaveRegistry.ts +2 -0
- package/corpus/templates/content/app/global.css +18 -1
- package/corpus/templates/content/app/hooks/use-content-database.ts +68 -0
- package/corpus/templates/content/app/hooks/use-documents.ts +53 -4
- package/corpus/templates/content/app/i18n/zh-TW.ts +30 -0
- package/corpus/templates/content/app/i18n-data.ts +339 -0
- package/corpus/templates/content/changelog/2026-07-10-builder-backed-preview-edits-are-preserved-when-article-bodi.md +6 -0
- package/corpus/templates/content/changelog/2026-07-10-builder-cms-sources-can-now-be-enabled-for-guarded-staged-or.md +6 -0
- package/corpus/templates/content/changelog/2026-07-13-builder-connection-setup-is-now-available-directly-from-conn.md +6 -0
- package/corpus/templates/content/changelog/2026-07-13-builder-reviews-now-hide-already-applied-writes-detect-nativ.md +6 -0
- package/corpus/templates/content/changelog/2026-07-13-required-builder-publishing-fields-can-now-be-added-directly.md +6 -0
- package/corpus/templates/content/changelog/2026-07-13-you-can-now-cancel-a-prepared-builder-update-safely-before-i.md +6 -0
- package/corpus/templates/content/changelog/2026-07-14-builder-account-connection-now-remains-available-when-branch.md +6 -0
- package/corpus/templates/content/changelog/2026-07-14-builder-backed-articles-now-preserve-fifth-and-sixth-level-h.md +6 -0
- package/corpus/templates/content/changelog/2026-07-14-builder-sources-now-review-and-publish-rich-article-updates-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-14-builder-writes-now-stop-retries-when-reconciliation-is-needed.md +6 -0
- package/corpus/templates/content/changelog/2026-07-14-file-and-media-links-now-validate-before-saving.md +6 -0
- package/corpus/templates/content/changelog/2026-07-14-pages-and-databases-can-describe-themselves-with-guidance-fo.md +6 -0
- package/corpus/templates/content/changelog/2026-07-14-slack-follow-ups-now-retain-created-content-identity-and-per.md +6 -0
- package/corpus/templates/content/parity/matrix.md +27 -25
- package/corpus/templates/content/parity/matrix.ts +50 -2
- package/corpus/templates/content/server/db/schema.ts +51 -0
- package/corpus/templates/content/server/lib/document-context.ts +76 -0
- package/corpus/templates/content/server/lib/public-documents.ts +3 -0
- package/corpus/templates/content/server/plugins/auth.ts +1 -0
- package/corpus/templates/content/server/plugins/db.ts +59 -0
- package/corpus/templates/content/server/routes/api/document-agent-context.json.get.ts +5 -0
- package/corpus/templates/content/shared/api.ts +87 -1
- package/corpus/templates/content/shared/builder-mdx.ts +705 -15
- package/corpus/templates/content/shared/content-source.ts +7 -0
- package/corpus/templates/content/shared/nfm.ts +3 -3
- package/corpus/templates/content/shared/properties.ts +2 -0
- package/corpus/templates/design/app/components/design/ReadOnlyDesignBanner.tsx +52 -7
- package/corpus/templates/design/app/components/design/ReviewCommentsPanel.tsx +36 -4
- package/corpus/templates/design/app/components/visual-editor/ReviewCanvasPins.tsx +4 -1
- package/corpus/templates/design/app/i18n/ar-SA.ts +1 -0
- package/corpus/templates/design/app/i18n/de-DE.ts +1 -0
- package/corpus/templates/design/app/i18n/en-US.ts +1 -0
- package/corpus/templates/design/app/i18n/es-ES.ts +1 -0
- package/corpus/templates/design/app/i18n/fr-FR.ts +1 -0
- package/corpus/templates/design/app/i18n/hi-IN.ts +1 -0
- package/corpus/templates/design/app/i18n/ja-JP.ts +1 -0
- package/corpus/templates/design/app/i18n/ko-KR.ts +1 -0
- package/corpus/templates/design/app/i18n/pt-BR.ts +1 -0
- package/corpus/templates/design/app/i18n/zh-CN.ts +1 -0
- package/corpus/templates/design/app/i18n/zh-TW.ts +1 -0
- package/corpus/templates/design/app/pages/design-editor/selection-state.ts +8 -0
- package/corpus/templates/design/app/pages/design-editor/tool-state.ts +11 -0
- package/corpus/templates/design/changelog/2026-07-14-reviewers-can-now-pin-comments-from-the-canvas-toolbar-targe.md +6 -0
- package/corpus/templates/design/changelog/2026-07-15-viewer-comment-controls-now-sit-inside-the-read-only-notice-.md +6 -0
- package/corpus/templates/design/shared/review-anchor.ts +48 -0
- package/corpus/templates/plan/server/plan-mdx.ts +53 -7
- package/dist/a2a/artifact-response.d.ts +15 -0
- package/dist/a2a/artifact-response.d.ts.map +1 -1
- package/dist/a2a/artifact-response.js +204 -5
- package/dist/a2a/artifact-response.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +6 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +71 -8
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/client/review/ReviewCommentComposer.d.ts +2 -1
- package/dist/client/review/ReviewCommentComposer.d.ts.map +1 -1
- package/dist/client/review/ReviewCommentComposer.js +3 -3
- package/dist/client/review/ReviewCommentComposer.js.map +1 -1
- package/dist/client/review/ReviewThreadPanel.d.ts +9 -1
- package/dist/client/review/ReviewThreadPanel.d.ts.map +1 -1
- package/dist/client/review/ReviewThreadPanel.js +6 -4
- package/dist/client/review/ReviewThreadPanel.js.map +1 -1
- package/dist/client/settings/SettingsPanel.d.ts +3 -0
- package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/client/settings/SettingsPanel.js +11 -4
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +8 -4
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +19 -6
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/setup-connections/BuilderConnectCard.d.ts.map +1 -1
- package/dist/client/setup-connections/BuilderConnectCard.js +2 -5
- package/dist/client/setup-connections/BuilderConnectCard.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/integrations/a2a-continuation-processor.d.ts.map +1 -1
- package/dist/integrations/a2a-continuation-processor.js +72 -6
- package/dist/integrations/a2a-continuation-processor.js.map +1 -1
- package/dist/integrations/adapters/discord.d.ts.map +1 -1
- package/dist/integrations/adapters/discord.js +1 -0
- package/dist/integrations/adapters/discord.js.map +1 -1
- package/dist/integrations/adapters/email.d.ts.map +1 -1
- package/dist/integrations/adapters/email.js +2 -0
- package/dist/integrations/adapters/email.js.map +1 -1
- package/dist/integrations/adapters/google-docs.d.ts.map +1 -1
- package/dist/integrations/adapters/google-docs.js +2 -0
- package/dist/integrations/adapters/google-docs.js.map +1 -1
- package/dist/integrations/adapters/microsoft-teams.d.ts.map +1 -1
- package/dist/integrations/adapters/microsoft-teams.js +1 -0
- package/dist/integrations/adapters/microsoft-teams.js.map +1 -1
- package/dist/integrations/adapters/slack.d.ts.map +1 -1
- package/dist/integrations/adapters/slack.js +21 -6
- package/dist/integrations/adapters/slack.js.map +1 -1
- package/dist/integrations/adapters/telegram.d.ts.map +1 -1
- package/dist/integrations/adapters/telegram.js +11 -2
- package/dist/integrations/adapters/telegram.js.map +1 -1
- package/dist/integrations/adapters/whatsapp.d.ts.map +1 -1
- package/dist/integrations/adapters/whatsapp.js +3 -0
- package/dist/integrations/adapters/whatsapp.js.map +1 -1
- package/dist/integrations/index.d.ts +1 -1
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js.map +1 -1
- package/dist/integrations/types.d.ts +8 -2
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/integrations/types.js.map +1 -1
- package/dist/integrations/webhook-handler.d.ts.map +1 -1
- package/dist/integrations/webhook-handler.js +40 -43
- package/dist/integrations/webhook-handler.js.map +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +1 -0
- package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
- package/dist/server/auth.d.ts +1 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +19 -2
- package/dist/server/auth.js.map +1 -1
- package/dist/server/builder-browser.d.ts +78 -0
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +246 -1
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts +41 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +260 -14
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/docs/content/deployment.mdx +9 -7
- package/docs/content/locales/ar-SA/deployment.mdx +9 -7
- package/docs/content/locales/de-DE/deployment.mdx +9 -7
- package/docs/content/locales/es-ES/deployment.mdx +9 -7
- package/docs/content/locales/fr-FR/deployment.mdx +9 -7
- package/docs/content/locales/hi-IN/deployment.mdx +9 -7
- package/docs/content/locales/ja-JP/deployment.mdx +9 -7
- package/docs/content/locales/ko-KR/deployment.mdx +9 -7
- package/docs/content/locales/pt-BR/deployment.mdx +9 -7
- package/docs/content/locales/zh-CN/deployment.mdx +9 -7
- package/docs/content/locales/zh-TW/deployment.mdx +9 -7
- package/package.json +2 -2
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
} from "@/hooks/use-view-preferences";
|
|
31
31
|
import { partitionAllDayEvents } from "@/lib/all-day-layout";
|
|
32
32
|
import { getEventDisplayColor, allOtherDeclined } from "@/lib/event-colors";
|
|
33
|
+
import { isOutOfOfficeEvent } from "@/lib/out-of-office";
|
|
33
34
|
import {
|
|
34
35
|
shouldSuppressAfterPopoverClose,
|
|
35
36
|
shouldSuppressCreatePointerDown,
|
|
@@ -44,6 +45,7 @@ import {
|
|
|
44
45
|
} from "@/lib/working-location";
|
|
45
46
|
|
|
46
47
|
import { EventDetailPopover } from "./EventDetailPopover";
|
|
48
|
+
import { OutOfOfficeEvent } from "./OutOfOfficeEvent";
|
|
47
49
|
|
|
48
50
|
interface DayViewProps {
|
|
49
51
|
events: CalendarEvent[];
|
|
@@ -230,6 +232,7 @@ interface DayEventCardProps {
|
|
|
230
232
|
onDraftUpdate?: DayViewProps["onDraftUpdate"];
|
|
231
233
|
onDraftCreate?: DayViewProps["onDraftCreate"];
|
|
232
234
|
onDraftDiscard?: DayViewProps["onDraftDiscard"];
|
|
235
|
+
onPopoverOpenChange: (event: CalendarEvent, open: boolean) => void;
|
|
233
236
|
}
|
|
234
237
|
|
|
235
238
|
/**
|
|
@@ -262,6 +265,7 @@ const DayEventCard = memo(function DayEventCard({
|
|
|
262
265
|
onDraftUpdate,
|
|
263
266
|
onDraftCreate,
|
|
264
267
|
onDraftDiscard,
|
|
268
|
+
onPopoverOpenChange,
|
|
265
269
|
}: DayEventCardProps) {
|
|
266
270
|
const t = useT();
|
|
267
271
|
const workingLocationLabels = createWorkingLocationDisplayLabels(t);
|
|
@@ -488,6 +492,7 @@ const DayEventCard = memo(function DayEventCard({
|
|
|
488
492
|
onDraftUpdate={onDraftUpdate}
|
|
489
493
|
onDraftCreate={onDraftCreate}
|
|
490
494
|
onDraftDiscard={onDraftDiscard}
|
|
495
|
+
onOpenChange={(open) => onPopoverOpenChange(event, open)}
|
|
491
496
|
>
|
|
492
497
|
{eventButton}
|
|
493
498
|
</EventDetailPopover>
|
|
@@ -543,6 +548,7 @@ export const DayView = memo(function DayView({
|
|
|
543
548
|
const { prefs } = useViewPreferences();
|
|
544
549
|
const [now, setNow] = useState(new Date());
|
|
545
550
|
const [focusedEventId, setFocusedEventId] = useState<string | null>(null);
|
|
551
|
+
const focusedEventIdRef = useRef<string | null>(null);
|
|
546
552
|
const currentTimeRef = useRef<HTMLDivElement>(null);
|
|
547
553
|
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
|
548
554
|
|
|
@@ -550,6 +556,7 @@ export const DayView = memo(function DayView({
|
|
|
550
556
|
useEffect(() => {
|
|
551
557
|
function handleKey(e: KeyboardEvent) {
|
|
552
558
|
if (e.key === "Escape") {
|
|
559
|
+
focusedEventIdRef.current = null;
|
|
553
560
|
setFocusedEventId(null);
|
|
554
561
|
setFocusedEvent(null);
|
|
555
562
|
}
|
|
@@ -594,7 +601,14 @@ export const DayView = memo(function DayView({
|
|
|
594
601
|
() => partitionAllDayEvents(allDayEvents),
|
|
595
602
|
[allDayEvents],
|
|
596
603
|
);
|
|
597
|
-
const
|
|
604
|
+
const outOfOfficeEvents = useMemo(
|
|
605
|
+
() => events.filter((event) => !event.allDay && isOutOfOfficeEvent(event)),
|
|
606
|
+
[events],
|
|
607
|
+
);
|
|
608
|
+
const timedEvents = useMemo(
|
|
609
|
+
() => events.filter((event) => !event.allDay && !isOutOfOfficeEvent(event)),
|
|
610
|
+
[events],
|
|
611
|
+
);
|
|
598
612
|
const layout = useMemo(() => computeLayout(timedEvents), [timedEvents]);
|
|
599
613
|
|
|
600
614
|
// Timezone label: prefer the short generic name (e.g. "PT", "ET")
|
|
@@ -666,8 +680,25 @@ export const DayView = memo(function DayView({
|
|
|
666
680
|
|
|
667
681
|
const canDrag = !!onEventTimeChange;
|
|
668
682
|
|
|
683
|
+
const handleEventPopoverOpenChange = useCallback(
|
|
684
|
+
(event: CalendarEvent, open: boolean) => {
|
|
685
|
+
if (open) {
|
|
686
|
+
focusedEventIdRef.current = event.id;
|
|
687
|
+
setFocusedEventId(event.id);
|
|
688
|
+
setFocusedEvent(event);
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
if (focusedEventIdRef.current !== event.id) return;
|
|
692
|
+
focusedEventIdRef.current = null;
|
|
693
|
+
setFocusedEventId(null);
|
|
694
|
+
setFocusedEvent(null);
|
|
695
|
+
},
|
|
696
|
+
[setFocusedEvent],
|
|
697
|
+
);
|
|
698
|
+
|
|
669
699
|
const handleEventPointerDown = useCallback(
|
|
670
700
|
(e: React.PointerEvent, event: CalendarEvent, isStart: boolean) => {
|
|
701
|
+
focusedEventIdRef.current = event.id;
|
|
671
702
|
setFocusedEventId(event.id);
|
|
672
703
|
setFocusedEvent(event);
|
|
673
704
|
if (
|
|
@@ -999,6 +1030,53 @@ export const DayView = memo(function DayView({
|
|
|
999
1030
|
</div>
|
|
1000
1031
|
)}
|
|
1001
1032
|
|
|
1033
|
+
{/* Native Google out-of-office context sits behind meetings. */}
|
|
1034
|
+
{!isLoading &&
|
|
1035
|
+
outOfOfficeEvents.map((event, markerIndex) => {
|
|
1036
|
+
const isBeingDragged = dragEventId === event.id;
|
|
1037
|
+
const overrides = getDragOverrides(event.id);
|
|
1038
|
+
return (
|
|
1039
|
+
<OutOfOfficeEvent
|
|
1040
|
+
key={event._tempId ?? event.id}
|
|
1041
|
+
event={event}
|
|
1042
|
+
day={date}
|
|
1043
|
+
hourHeight={HOUR_HEIGHT}
|
|
1044
|
+
color={
|
|
1045
|
+
getEventDisplayColor(event, prefs) ?? "hsl(var(--primary))"
|
|
1046
|
+
}
|
|
1047
|
+
label={t("eventForm.outOfOffice")}
|
|
1048
|
+
markerIndex={markerIndex}
|
|
1049
|
+
canDrag={canDrag}
|
|
1050
|
+
isBeingDragged={isBeingDragged}
|
|
1051
|
+
isDragging={isDragging}
|
|
1052
|
+
isDragTargetDay={isBeingDragged}
|
|
1053
|
+
overrideTop={overrides?.top ?? null}
|
|
1054
|
+
overrideHeight={overrides?.height ?? null}
|
|
1055
|
+
onMovePointerDown={(pointerEvent, startsOnDay) =>
|
|
1056
|
+
handleEventPointerDown(pointerEvent, event, startsOnDay)
|
|
1057
|
+
}
|
|
1058
|
+
onResizeTopPointerDown={(pointerEvent) =>
|
|
1059
|
+
handleResizeTopPointerDown(pointerEvent, event.id)
|
|
1060
|
+
}
|
|
1061
|
+
onResizeBottomPointerDown={(pointerEvent) =>
|
|
1062
|
+
handleResizeBottomPointerDown(pointerEvent, event.id)
|
|
1063
|
+
}
|
|
1064
|
+
shouldSuppressClick={shouldSuppressClick}
|
|
1065
|
+
onDelete={onDeleteEvent}
|
|
1066
|
+
isDraft={draftEventIds.includes(event.id)}
|
|
1067
|
+
defaultOpen={quickEditEventId === event.id}
|
|
1068
|
+
onTitleSave={onQuickEditSave}
|
|
1069
|
+
onDismissNew={onQuickEditCancel}
|
|
1070
|
+
onDraftUpdate={onDraftUpdate}
|
|
1071
|
+
onDraftCreate={onDraftCreate}
|
|
1072
|
+
onDraftDiscard={onDraftDiscard}
|
|
1073
|
+
onOpenChange={(open) =>
|
|
1074
|
+
handleEventPopoverOpenChange(event, open)
|
|
1075
|
+
}
|
|
1076
|
+
/>
|
|
1077
|
+
);
|
|
1078
|
+
})}
|
|
1079
|
+
|
|
1002
1080
|
{/* Skeleton events when loading */}
|
|
1003
1081
|
{isLoading &&
|
|
1004
1082
|
DAY_SKELETONS.map(
|
|
@@ -1053,6 +1131,7 @@ export const DayView = memo(function DayView({
|
|
|
1053
1131
|
onDraftUpdate={onDraftUpdate}
|
|
1054
1132
|
onDraftCreate={onDraftCreate}
|
|
1055
1133
|
onDraftDiscard={onDraftDiscard}
|
|
1134
|
+
onPopoverOpenChange={handleEventPopoverOpenChange}
|
|
1056
1135
|
/>
|
|
1057
1136
|
);
|
|
1058
1137
|
})}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { useT } from "@agent-native/core/client";
|
|
2
2
|
import type { CalendarEvent } from "@shared/api";
|
|
3
|
-
import { IconAlertTriangleFilled } from "@tabler/icons-react";
|
|
3
|
+
import { IconAlertTriangleFilled, IconCalendarOff } from "@tabler/icons-react";
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
getEventDisplayColor,
|
|
7
7
|
allOtherDeclined,
|
|
8
8
|
type CalendarColorPreferences,
|
|
9
9
|
} from "@/lib/event-colors";
|
|
10
|
+
import { isOutOfOfficeEvent } from "@/lib/out-of-office";
|
|
10
11
|
import { EventStatusIcon } from "@/lib/rsvp-status";
|
|
11
12
|
import { cn } from "@/lib/utils";
|
|
12
13
|
import {
|
|
@@ -44,6 +45,7 @@ export function EventCard({
|
|
|
44
45
|
const title = getWorkingLocationChipLabel(event, workingLocationLabels);
|
|
45
46
|
const ariaTitle = getWorkingLocationTitle(event, workingLocationLabels);
|
|
46
47
|
const isWorkingLocation = isWorkingLocationEvent(event);
|
|
48
|
+
const isOutOfOffice = isOutOfOfficeEvent(event);
|
|
47
49
|
|
|
48
50
|
const handleDragStart = (e: React.DragEvent) => {
|
|
49
51
|
e.dataTransfer.setData("text/plain", event.id);
|
|
@@ -73,7 +75,13 @@ export function EventCard({
|
|
|
73
75
|
backgroundColor: `${accentColor}25`,
|
|
74
76
|
}}
|
|
75
77
|
>
|
|
76
|
-
{
|
|
78
|
+
{isOutOfOffice ? (
|
|
79
|
+
<IconCalendarOff
|
|
80
|
+
aria-hidden="true"
|
|
81
|
+
className="size-3 shrink-0"
|
|
82
|
+
style={{ color: accentColor }}
|
|
83
|
+
/>
|
|
84
|
+
) : allOtherDeclined(event) ? (
|
|
77
85
|
<IconAlertTriangleFilled
|
|
78
86
|
size={10}
|
|
79
87
|
className="shrink-0 text-current opacity-70"
|
|
@@ -91,6 +99,11 @@ export function EventCard({
|
|
|
91
99
|
{t("eventForm.workingLocation")}
|
|
92
100
|
</span>
|
|
93
101
|
)}
|
|
102
|
+
{isOutOfOffice && (
|
|
103
|
+
<span className="hidden shrink-0 text-[10px] font-normal text-foreground/65 sm:inline">
|
|
104
|
+
{t("eventForm.outOfOffice")}
|
|
105
|
+
</span>
|
|
106
|
+
)}
|
|
94
107
|
{event.ownerColor && (
|
|
95
108
|
<span
|
|
96
109
|
aria-hidden="true"
|
|
@@ -123,7 +136,14 @@ export function EventCard({
|
|
|
123
136
|
}}
|
|
124
137
|
>
|
|
125
138
|
<div className="flex items-center gap-1 truncate">
|
|
126
|
-
{
|
|
139
|
+
{isOutOfOffice && (
|
|
140
|
+
<IconCalendarOff
|
|
141
|
+
aria-hidden="true"
|
|
142
|
+
className="size-3 shrink-0"
|
|
143
|
+
style={{ color: accentColor }}
|
|
144
|
+
/>
|
|
145
|
+
)}
|
|
146
|
+
{!isOutOfOffice && allOtherDeclined(event) && (
|
|
127
147
|
<IconAlertTriangleFilled
|
|
128
148
|
size={12}
|
|
129
149
|
className="shrink-0 text-current opacity-70"
|
|
@@ -137,6 +157,11 @@ export function EventCard({
|
|
|
137
157
|
{t("eventForm.workingLocation")}
|
|
138
158
|
</span>
|
|
139
159
|
)}
|
|
160
|
+
{isOutOfOffice && (
|
|
161
|
+
<span className="truncate text-foreground/70">
|
|
162
|
+
{t("eventForm.outOfOffice")}
|
|
163
|
+
</span>
|
|
164
|
+
)}
|
|
140
165
|
{!event.allDay && (
|
|
141
166
|
<span className="text-foreground/70">
|
|
142
167
|
{new Date(event.start).toLocaleTimeString([], {
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
} from "@/components/ui/tooltip";
|
|
35
35
|
import { useUpdateEvent } from "@/hooks/use-events";
|
|
36
36
|
import { useViewPreferences } from "@/hooks/use-view-preferences";
|
|
37
|
+
import { isOutOfOfficeEvent } from "@/lib/out-of-office";
|
|
37
38
|
import { cn } from "@/lib/utils";
|
|
38
39
|
import {
|
|
39
40
|
buildWorkingLocationUpdate,
|
|
@@ -135,6 +136,7 @@ export function EventDetailPanel({
|
|
|
135
136
|
useGuestNotificationPrompt();
|
|
136
137
|
const isOverlay = !!event?.overlayEmail;
|
|
137
138
|
const isWorkingLocation = event ? isWorkingLocationEvent(event) : false;
|
|
139
|
+
const isOutOfOffice = event ? isOutOfOfficeEvent(event) : false;
|
|
138
140
|
const isRecurringEvent = !!(
|
|
139
141
|
event?.recurringEventId || event?.recurrence?.length
|
|
140
142
|
);
|
|
@@ -293,7 +295,9 @@ export function EventDetailPanel({
|
|
|
293
295
|
<span className="text-xs font-medium uppercase tracking-wider text-muted-foreground">
|
|
294
296
|
{isWorkingLocation
|
|
295
297
|
? t("eventForm.workingLocation")
|
|
296
|
-
:
|
|
298
|
+
: isOutOfOffice
|
|
299
|
+
? t("eventForm.outOfOffice")
|
|
300
|
+
: t("eventForm.event")}
|
|
297
301
|
</span>
|
|
298
302
|
<div className="flex items-center gap-0.5">
|
|
299
303
|
<Tooltip>
|
|
@@ -97,6 +97,7 @@ import {
|
|
|
97
97
|
type ReminderMode,
|
|
98
98
|
validateAttachmentDrafts,
|
|
99
99
|
} from "@/lib/event-form-utils";
|
|
100
|
+
import { isOutOfOfficeEvent } from "@/lib/out-of-office";
|
|
100
101
|
import {
|
|
101
102
|
createEventDetailPopoverToken,
|
|
102
103
|
markPopoverInteractOutside,
|
|
@@ -473,6 +474,8 @@ interface EventDetailPopoverProps {
|
|
|
473
474
|
onTitleSave?: (eventId: string, title: string, accountEmail?: string) => void;
|
|
474
475
|
/** Called when the popover is dismissed for a new event (to clean up if no title was set) */
|
|
475
476
|
onDismissNew?: (eventId: string, accountEmail?: string) => void;
|
|
477
|
+
/** Called after the popover's visible open state changes through its normal lifecycle. */
|
|
478
|
+
onOpenChange?: (open: boolean) => void;
|
|
476
479
|
onDraftUpdate?: (
|
|
477
480
|
eventId: string,
|
|
478
481
|
updates: Partial<CalendarEvent> & {
|
|
@@ -500,6 +503,7 @@ export function EventDetailPopover({
|
|
|
500
503
|
defaultOpen = false,
|
|
501
504
|
onTitleSave,
|
|
502
505
|
onDismissNew,
|
|
506
|
+
onOpenChange,
|
|
503
507
|
onDraftUpdate,
|
|
504
508
|
onDraftCreate,
|
|
505
509
|
onDraftDiscard,
|
|
@@ -520,11 +524,13 @@ export function EventDetailPopover({
|
|
|
520
524
|
}
|
|
521
525
|
const {
|
|
522
526
|
eventDetailSidebar,
|
|
527
|
+
sidebarEvent,
|
|
523
528
|
setEventDetailSidebar,
|
|
524
529
|
setSidebarEvent,
|
|
525
530
|
setFocusedEvent,
|
|
526
531
|
} = useCalendarContext();
|
|
527
532
|
const isWorkingLocation = isWorkingLocationEvent(event);
|
|
533
|
+
const isOutOfOffice = isOutOfOfficeEvent(event);
|
|
528
534
|
const isSingleDayWorkingLocation = isWorkingLocation && event.allDay;
|
|
529
535
|
const editableLocationValue = event.location || "";
|
|
530
536
|
|
|
@@ -1274,6 +1280,9 @@ export function EventDetailPopover({
|
|
|
1274
1280
|
(isRecurringEvent ? t("eventForm.repeats") : null);
|
|
1275
1281
|
const handleOpenChange = useCallback(
|
|
1276
1282
|
(newOpen: boolean) => {
|
|
1283
|
+
const isPopoverSuppressed =
|
|
1284
|
+
eventDetailSidebar && !isNewEventRef.current && !isDraft;
|
|
1285
|
+
if (newOpen && isPopoverSuppressed) return;
|
|
1277
1286
|
if (!newOpen && open) {
|
|
1278
1287
|
const trimmedTitle = editingTitle.trim();
|
|
1279
1288
|
let savedPendingChange = false;
|
|
@@ -1330,11 +1339,27 @@ export function EventDetailPopover({
|
|
|
1330
1339
|
handleSaveMeetingLink,
|
|
1331
1340
|
handleSaveReminders,
|
|
1332
1341
|
handleSaveAttachments,
|
|
1342
|
+
eventDetailSidebar,
|
|
1343
|
+
isDraft,
|
|
1333
1344
|
],
|
|
1334
1345
|
);
|
|
1335
1346
|
|
|
1336
1347
|
const popoverOpen =
|
|
1337
1348
|
eventDetailSidebar && !isNewEventRef.current && !isDraft ? false : open;
|
|
1349
|
+
const sidebarDetailsOpen =
|
|
1350
|
+
eventDetailSidebar &&
|
|
1351
|
+
!isNewEventRef.current &&
|
|
1352
|
+
!isDraft &&
|
|
1353
|
+
sidebarEvent?.id === event.id &&
|
|
1354
|
+
sidebarEvent.accountEmail === event.accountEmail;
|
|
1355
|
+
const detailsOpen = popoverOpen || sidebarDetailsOpen;
|
|
1356
|
+
const previousDetailsOpenRef = useRef(false);
|
|
1357
|
+
|
|
1358
|
+
useEffect(() => {
|
|
1359
|
+
if (previousDetailsOpenRef.current === detailsOpen) return;
|
|
1360
|
+
previousDetailsOpenRef.current = detailsOpen;
|
|
1361
|
+
onOpenChange?.(detailsOpen);
|
|
1362
|
+
}, [detailsOpen, onOpenChange]);
|
|
1338
1363
|
|
|
1339
1364
|
useEffect(() => {
|
|
1340
1365
|
const token = popoverTokenRef.current;
|
|
@@ -1386,9 +1411,11 @@ export function EventDetailPopover({
|
|
|
1386
1411
|
<span>
|
|
1387
1412
|
{isWorkingLocation
|
|
1388
1413
|
? t("eventForm.workingLocation")
|
|
1389
|
-
:
|
|
1390
|
-
? t("eventForm.
|
|
1391
|
-
:
|
|
1414
|
+
: isOutOfOffice
|
|
1415
|
+
? t("eventForm.outOfOffice")
|
|
1416
|
+
: isDraft
|
|
1417
|
+
? t("eventForm.draftEvent")
|
|
1418
|
+
: t("eventForm.event")}
|
|
1392
1419
|
</span>
|
|
1393
1420
|
</div>
|
|
1394
1421
|
<div className="flex items-center gap-0.5">
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import type { CalendarEvent } from "@shared/api";
|
|
2
|
+
import { IconCalendarOff } from "@tabler/icons-react";
|
|
3
|
+
|
|
4
|
+
import { getOutOfOfficeSegment } from "@/lib/out-of-office";
|
|
5
|
+
|
|
6
|
+
import { EventDetailPopover } from "./EventDetailPopover";
|
|
7
|
+
|
|
8
|
+
interface OutOfOfficeEventProps {
|
|
9
|
+
event: CalendarEvent;
|
|
10
|
+
day: Date;
|
|
11
|
+
hourHeight: number;
|
|
12
|
+
color: string;
|
|
13
|
+
label: string;
|
|
14
|
+
markerIndex?: number;
|
|
15
|
+
compactMarker?: boolean;
|
|
16
|
+
canDrag?: boolean;
|
|
17
|
+
isBeingDragged?: boolean;
|
|
18
|
+
isDragging?: boolean;
|
|
19
|
+
isDragTargetDay?: boolean;
|
|
20
|
+
overrideTop?: number | null;
|
|
21
|
+
overrideHeight?: number | null;
|
|
22
|
+
onMovePointerDown?: (event: React.PointerEvent, startsOnDay: boolean) => void;
|
|
23
|
+
onResizeTopPointerDown?: (event: React.PointerEvent) => void;
|
|
24
|
+
onResizeBottomPointerDown?: (event: React.PointerEvent) => void;
|
|
25
|
+
shouldSuppressClick?: () => boolean;
|
|
26
|
+
onDelete: (eventId: string) => void;
|
|
27
|
+
isDraft: boolean;
|
|
28
|
+
defaultOpen: boolean;
|
|
29
|
+
onTitleSave?: (eventId: string, title: string, accountEmail?: string) => void;
|
|
30
|
+
onDismissNew?: (eventId: string, accountEmail?: string) => void;
|
|
31
|
+
onDraftUpdate?: (
|
|
32
|
+
eventId: string,
|
|
33
|
+
updates: Partial<CalendarEvent> & {
|
|
34
|
+
addGoogleMeet?: boolean;
|
|
35
|
+
addZoom?: boolean;
|
|
36
|
+
workingLocationType?: "homeOffice" | "officeLocation" | "customLocation";
|
|
37
|
+
workingLocationLabel?: string;
|
|
38
|
+
},
|
|
39
|
+
) => void;
|
|
40
|
+
onDraftCreate?: (
|
|
41
|
+
eventId: string,
|
|
42
|
+
updates?: Partial<CalendarEvent> & {
|
|
43
|
+
addGoogleMeet?: boolean;
|
|
44
|
+
addZoom?: boolean;
|
|
45
|
+
},
|
|
46
|
+
) => void;
|
|
47
|
+
onDraftDiscard?: (eventId: string) => void;
|
|
48
|
+
onOpenChange?: (open: boolean) => void;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function OutOfOfficeEvent({
|
|
52
|
+
event,
|
|
53
|
+
day,
|
|
54
|
+
hourHeight,
|
|
55
|
+
color,
|
|
56
|
+
label,
|
|
57
|
+
markerIndex = 0,
|
|
58
|
+
compactMarker = false,
|
|
59
|
+
canDrag = false,
|
|
60
|
+
isBeingDragged = false,
|
|
61
|
+
isDragging = false,
|
|
62
|
+
isDragTargetDay = false,
|
|
63
|
+
overrideTop = null,
|
|
64
|
+
overrideHeight = null,
|
|
65
|
+
onMovePointerDown,
|
|
66
|
+
onResizeTopPointerDown,
|
|
67
|
+
onResizeBottomPointerDown,
|
|
68
|
+
shouldSuppressClick,
|
|
69
|
+
onDelete,
|
|
70
|
+
isDraft,
|
|
71
|
+
defaultOpen,
|
|
72
|
+
onTitleSave,
|
|
73
|
+
onDismissNew,
|
|
74
|
+
onDraftUpdate,
|
|
75
|
+
onDraftCreate,
|
|
76
|
+
onDraftDiscard,
|
|
77
|
+
onOpenChange,
|
|
78
|
+
}: OutOfOfficeEventProps) {
|
|
79
|
+
const segment = getOutOfOfficeSegment(event, day);
|
|
80
|
+
const hasDragOverride =
|
|
81
|
+
isBeingDragged &&
|
|
82
|
+
isDragTargetDay &&
|
|
83
|
+
overrideTop !== null &&
|
|
84
|
+
overrideHeight !== null;
|
|
85
|
+
if (isBeingDragged && !isDragTargetDay) return null;
|
|
86
|
+
if (!segment && !hasDragOverride) return null;
|
|
87
|
+
|
|
88
|
+
const top = hasDragOverride
|
|
89
|
+
? overrideTop
|
|
90
|
+
: ((segment?.topMinutes ?? 0) / 60) * hourHeight;
|
|
91
|
+
const height = hasDragOverride
|
|
92
|
+
? overrideHeight
|
|
93
|
+
: ((segment?.durationMinutes ?? 1) / 60) * hourHeight;
|
|
94
|
+
const title = event.title || label;
|
|
95
|
+
const startsOnDay = hasDragOverride || segment?.startsOnDay === true;
|
|
96
|
+
const endsOnDay = hasDragOverride || segment?.endsOnDay === true;
|
|
97
|
+
const canManipulate = canDrag && startsOnDay;
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<>
|
|
101
|
+
<div
|
|
102
|
+
data-out-of-office-event={event.id}
|
|
103
|
+
className="pointer-events-none absolute inset-x-0 z-0"
|
|
104
|
+
style={{ top: `${top}px`, height: `${height}px` }}
|
|
105
|
+
>
|
|
106
|
+
<div
|
|
107
|
+
aria-hidden="true"
|
|
108
|
+
className="absolute inset-0"
|
|
109
|
+
style={{
|
|
110
|
+
backgroundColor: `color-mix(in srgb, ${color} 7%, transparent)`,
|
|
111
|
+
boxShadow: `inset 2px 0 0 color-mix(in srgb, ${color} 28%, transparent)`,
|
|
112
|
+
}}
|
|
113
|
+
/>
|
|
114
|
+
</div>
|
|
115
|
+
<div
|
|
116
|
+
data-out-of-office-trigger={event.id}
|
|
117
|
+
className={`pointer-events-auto absolute ${
|
|
118
|
+
isBeingDragged && isDragging ? "z-[100]" : "z-40"
|
|
119
|
+
}`}
|
|
120
|
+
style={{
|
|
121
|
+
top: `${top + 4}px`,
|
|
122
|
+
right: `${4 + (compactMarker ? markerIndex * 24 : 0)}px`,
|
|
123
|
+
left: compactMarker ? undefined : `${4 + markerIndex * 12}px`,
|
|
124
|
+
}}
|
|
125
|
+
>
|
|
126
|
+
<EventDetailPopover
|
|
127
|
+
event={event}
|
|
128
|
+
onDelete={onDelete}
|
|
129
|
+
isDraft={isDraft}
|
|
130
|
+
defaultOpen={defaultOpen}
|
|
131
|
+
onTitleSave={onTitleSave}
|
|
132
|
+
onDismissNew={onDismissNew}
|
|
133
|
+
onDraftUpdate={onDraftUpdate}
|
|
134
|
+
onDraftCreate={onDraftCreate}
|
|
135
|
+
onDraftDiscard={onDraftDiscard}
|
|
136
|
+
onOpenChange={onOpenChange}
|
|
137
|
+
>
|
|
138
|
+
<button
|
|
139
|
+
onPointerDown={(pointerEvent) =>
|
|
140
|
+
onMovePointerDown?.(pointerEvent, startsOnDay)
|
|
141
|
+
}
|
|
142
|
+
onClick={(clickEvent) => {
|
|
143
|
+
if (shouldSuppressClick?.()) {
|
|
144
|
+
clickEvent.preventDefault();
|
|
145
|
+
clickEvent.stopPropagation();
|
|
146
|
+
}
|
|
147
|
+
}}
|
|
148
|
+
className={`flex h-5 max-w-full items-center truncate rounded-sm text-[10px] font-medium text-foreground outline-none transition-[filter,box-shadow] hover:brightness-110 focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 ${
|
|
149
|
+
compactMarker
|
|
150
|
+
? "w-5 justify-center px-0"
|
|
151
|
+
: "gap-1 px-1.5 text-left"
|
|
152
|
+
} ${canManipulate ? "cursor-grab" : ""} ${
|
|
153
|
+
isBeingDragged && isDragging ? "cursor-grabbing shadow-lg" : ""
|
|
154
|
+
}`}
|
|
155
|
+
aria-label={`${label}: ${title}`}
|
|
156
|
+
style={{
|
|
157
|
+
backgroundColor: `color-mix(in srgb, ${color} 20%, hsl(var(--background)))`,
|
|
158
|
+
boxShadow: `0 0 0 1px color-mix(in srgb, ${color} 34%, transparent)`,
|
|
159
|
+
}}
|
|
160
|
+
>
|
|
161
|
+
<IconCalendarOff
|
|
162
|
+
aria-hidden="true"
|
|
163
|
+
className="size-3 shrink-0"
|
|
164
|
+
style={{ color }}
|
|
165
|
+
/>
|
|
166
|
+
{!compactMarker && <span className="truncate">{title}</span>}
|
|
167
|
+
</button>
|
|
168
|
+
</EventDetailPopover>
|
|
169
|
+
</div>
|
|
170
|
+
{canManipulate && (
|
|
171
|
+
<div
|
|
172
|
+
data-resize-handle="true"
|
|
173
|
+
data-out-of-office-resize="top"
|
|
174
|
+
onPointerDown={(pointerEvent) => {
|
|
175
|
+
pointerEvent.stopPropagation();
|
|
176
|
+
onResizeTopPointerDown?.(pointerEvent);
|
|
177
|
+
}}
|
|
178
|
+
className="pointer-events-auto absolute right-1 z-40 h-1.5 w-5 cursor-n-resize"
|
|
179
|
+
style={{ top: `${top}px`, touchAction: "none" }}
|
|
180
|
+
/>
|
|
181
|
+
)}
|
|
182
|
+
{canManipulate && endsOnDay && (
|
|
183
|
+
<div
|
|
184
|
+
data-resize-handle="true"
|
|
185
|
+
data-out-of-office-resize="bottom"
|
|
186
|
+
onPointerDown={(pointerEvent) => {
|
|
187
|
+
pointerEvent.stopPropagation();
|
|
188
|
+
onResizeBottomPointerDown?.(pointerEvent);
|
|
189
|
+
}}
|
|
190
|
+
className="pointer-events-auto absolute right-1 z-40 h-1.5 w-5 cursor-s-resize"
|
|
191
|
+
style={{ top: `${top + height - 6}px`, touchAction: "none" }}
|
|
192
|
+
/>
|
|
193
|
+
)}
|
|
194
|
+
</>
|
|
195
|
+
);
|
|
196
|
+
}
|