@almadar/ui 6.25.0 → 6.27.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.
@@ -30748,6 +30748,247 @@ var init_WizardNavigation = __esm({
30748
30748
  WizardNavigation.displayName = "WizardNavigation";
30749
30749
  }
30750
30750
  });
30751
+ function parseDay(value) {
30752
+ if (value === void 0 || value === null || value === "") return null;
30753
+ const d = value instanceof Date ? new Date(value.getTime()) : new Date(value);
30754
+ if (Number.isNaN(d.getTime())) return null;
30755
+ d.setHours(0, 0, 0, 0);
30756
+ return d;
30757
+ }
30758
+ function Gantt({
30759
+ tasks = [],
30760
+ links = [],
30761
+ titleField = "title",
30762
+ startField = "start",
30763
+ endField = "end",
30764
+ durationField,
30765
+ statusField = "status",
30766
+ groupField = "",
30767
+ rangeStart,
30768
+ rangeEnd,
30769
+ showToday = true,
30770
+ dayWidth = 28,
30771
+ barClickEvent,
30772
+ className,
30773
+ isLoading = false,
30774
+ error = null
30775
+ }) {
30776
+ const { t } = useTranslate();
30777
+ const placed = useMemo(() => {
30778
+ const rows2 = Array.isArray(tasks) ? tasks : tasks ? [tasks] : [];
30779
+ const out = [];
30780
+ rows2.forEach((row, idx) => {
30781
+ const start = parseDay(getNestedValue(row, startField));
30782
+ if (!start) return;
30783
+ let end = parseDay(getNestedValue(row, endField));
30784
+ if (!end && durationField) {
30785
+ const days2 = Number(getNestedValue(row, durationField));
30786
+ if (Number.isFinite(days2) && days2 > 0) {
30787
+ end = new Date(start.getTime() + days2 * DAY_MS);
30788
+ }
30789
+ }
30790
+ if (!end || end.getTime() < start.getTime()) end = new Date(start.getTime() + DAY_MS);
30791
+ out.push({
30792
+ row,
30793
+ id: String(row.id ?? idx),
30794
+ label: String(getNestedValue(row, titleField) ?? ""),
30795
+ status: String(getNestedValue(row, statusField) ?? "").toLowerCase(),
30796
+ group: groupField ? String(getNestedValue(row, groupField) ?? "") : "",
30797
+ start,
30798
+ end
30799
+ });
30800
+ });
30801
+ return out;
30802
+ }, [tasks, titleField, startField, endField, durationField, statusField, groupField]);
30803
+ const [axisStart, axisEnd] = useMemo(() => {
30804
+ const lo = parseDay(rangeStart) ?? (placed.length ? new Date(Math.min(...placed.map((p) => p.start.getTime())) - 2 * DAY_MS) : new Date((/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0)));
30805
+ const hi = parseDay(rangeEnd) ?? (placed.length ? new Date(Math.max(...placed.map((p) => p.end.getTime())) + 2 * DAY_MS) : new Date(lo.getTime() + 30 * DAY_MS));
30806
+ return hi.getTime() > lo.getTime() ? [lo, hi] : [lo, new Date(lo.getTime() + DAY_MS)];
30807
+ }, [rangeStart, rangeEnd, placed]);
30808
+ const totalDays = Math.round((axisEnd.getTime() - axisStart.getTime()) / DAY_MS);
30809
+ const chartWidth = totalDays * dayWidth;
30810
+ const dayOffset = (d) => (d.getTime() - axisStart.getTime()) / DAY_MS * dayWidth;
30811
+ const displayItems = useMemo(() => {
30812
+ if (!groupField) return placed.map((task) => ({ kind: "task", task }));
30813
+ const items = [];
30814
+ const seen = /* @__PURE__ */ new Set();
30815
+ for (const task of placed) {
30816
+ if (!seen.has(task.group)) {
30817
+ seen.add(task.group);
30818
+ items.push({ kind: "group", label: task.group || "\u2014" });
30819
+ }
30820
+ items.push({ kind: "task", task });
30821
+ }
30822
+ return items;
30823
+ }, [placed, groupField]);
30824
+ const barGeometry = useMemo(() => {
30825
+ const offset = (d) => (d.getTime() - axisStart.getTime()) / DAY_MS * dayWidth;
30826
+ const map = /* @__PURE__ */ new Map();
30827
+ displayItems.forEach((item, idx) => {
30828
+ if (item.kind !== "task") return;
30829
+ const x0 = offset(item.task.start);
30830
+ const x1 = Math.max(offset(item.task.end), x0 + dayWidth / 2);
30831
+ map.set(item.task.id, { x0, x1, y: HEADER_HEIGHT + idx * ROW_HEIGHT + ROW_HEIGHT / 2 });
30832
+ });
30833
+ return map;
30834
+ }, [displayItems, axisStart, dayWidth]);
30835
+ const days = useMemo(() => {
30836
+ const out = [];
30837
+ for (let i = 0; i < totalDays; i++) out.push(new Date(axisStart.getTime() + i * DAY_MS));
30838
+ return out;
30839
+ }, [axisStart, totalDays]);
30840
+ const todayOffset = useMemo(() => {
30841
+ const today = parseDay(/* @__PURE__ */ new Date());
30842
+ if (!today || today < axisStart || today > axisEnd) return null;
30843
+ return (today.getTime() - axisStart.getTime()) / DAY_MS * dayWidth;
30844
+ }, [axisStart, axisEnd, dayWidth]);
30845
+ if (isLoading) {
30846
+ return /* @__PURE__ */ jsx(LoadingState, { message: t("common.loading"), className });
30847
+ }
30848
+ if (error) {
30849
+ return /* @__PURE__ */ jsx(Box, { className: cn("p-4", className), children: /* @__PURE__ */ jsx(Typography, { variant: "body", color: "error", children: error.message }) });
30850
+ }
30851
+ if (placed.length === 0) {
30852
+ return /* @__PURE__ */ jsx(
30853
+ EmptyState,
30854
+ {
30855
+ title: t("empty.noData"),
30856
+ className
30857
+ }
30858
+ );
30859
+ }
30860
+ return /* @__PURE__ */ jsx(
30861
+ Box,
30862
+ {
30863
+ className: cn("w-full overflow-auto rounded-md border border-border bg-card", className),
30864
+ children: /* @__PURE__ */ jsxs(Box, { className: "relative", style: { width: LABEL_WIDTH + chartWidth, minWidth: "100%" }, children: [
30865
+ /* @__PURE__ */ jsxs(HStack, { gap: "none", className: "sticky top-0 z-20 bg-card border-b border-border", style: { height: HEADER_HEIGHT }, children: [
30866
+ /* @__PURE__ */ jsx(Box, { className: "sticky left-0 z-10 shrink-0 bg-card border-r border-border", style: { width: LABEL_WIDTH, height: HEADER_HEIGHT } }),
30867
+ /* @__PURE__ */ jsx(Box, { className: "relative", style: { width: chartWidth, height: HEADER_HEIGHT }, children: days.map((day, i) => /* @__PURE__ */ jsx(
30868
+ Box,
30869
+ {
30870
+ className: cn(
30871
+ "absolute top-0 bottom-0 border-l border-border/50 flex items-end justify-center pb-1",
30872
+ day.getDay() === 0 || day.getDay() === 6 ? "bg-muted/40" : void 0
30873
+ ),
30874
+ style: { left: i * dayWidth, width: dayWidth },
30875
+ children: dayWidth >= 20 && /* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: day.getDate() })
30876
+ },
30877
+ i
30878
+ )) })
30879
+ ] }),
30880
+ /* @__PURE__ */ jsxs(VStack, { gap: "none", className: "relative", children: [
30881
+ displayItems.map(
30882
+ (item, idx) => item.kind === "group" ? /* @__PURE__ */ jsxs(
30883
+ HStack,
30884
+ {
30885
+ gap: "none",
30886
+ className: "border-b border-border bg-muted/30",
30887
+ style: { height: ROW_HEIGHT },
30888
+ children: [
30889
+ /* @__PURE__ */ jsx(Box, { className: "sticky left-0 z-10 shrink-0 bg-muted/30 px-3 flex items-center border-r border-border", style: { width: LABEL_WIDTH, height: ROW_HEIGHT }, children: /* @__PURE__ */ jsx(Typography, { variant: "caption", weight: "semibold", children: item.label }) }),
30890
+ /* @__PURE__ */ jsx(Box, { style: { width: chartWidth, height: ROW_HEIGHT } })
30891
+ ]
30892
+ },
30893
+ `g-${idx}`
30894
+ ) : /* @__PURE__ */ jsxs(
30895
+ HStack,
30896
+ {
30897
+ gap: "none",
30898
+ className: "border-b border-border/50",
30899
+ style: { height: ROW_HEIGHT },
30900
+ children: [
30901
+ /* @__PURE__ */ jsx(Box, { className: "sticky left-0 z-10 shrink-0 bg-card px-3 flex items-center border-r border-border", style: { width: LABEL_WIDTH, height: ROW_HEIGHT }, children: /* @__PURE__ */ jsx(Typography, { variant: "small", className: "truncate", children: item.task.label }) }),
30902
+ /* @__PURE__ */ jsx(Box, { className: "relative", style: { width: chartWidth, height: ROW_HEIGHT }, children: /* @__PURE__ */ jsx(
30903
+ Box,
30904
+ {
30905
+ className: cn(
30906
+ "absolute top-1/2 -translate-y-1/2 h-4 rounded-sm transition-colors",
30907
+ STATUS_BAR[item.task.status] ?? "bg-primary/80 hover:bg-primary",
30908
+ barClickEvent ? "cursor-pointer" : void 0
30909
+ ),
30910
+ style: {
30911
+ left: dayOffset(item.task.start),
30912
+ width: Math.max(dayOffset(item.task.end) - dayOffset(item.task.start), dayWidth / 2)
30913
+ },
30914
+ action: barClickEvent,
30915
+ actionPayload: { id: item.task.id }
30916
+ }
30917
+ ) })
30918
+ ]
30919
+ },
30920
+ item.task.id
30921
+ )
30922
+ ),
30923
+ links.length > 0 && /* @__PURE__ */ jsxs(
30924
+ "svg",
30925
+ {
30926
+ className: "absolute pointer-events-none",
30927
+ style: { left: LABEL_WIDTH, top: 0 },
30928
+ width: chartWidth,
30929
+ height: HEADER_HEIGHT + displayItems.length * ROW_HEIGHT,
30930
+ children: [
30931
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("marker", { id: "gantt-arrow", markerWidth: "8", markerHeight: "8", refX: "7", refY: "4", orient: "auto", children: /* @__PURE__ */ jsx("path", { d: "M0,0 L8,4 L0,8 z", fill: "var(--muted-foreground, currentColor)" }) }) }),
30932
+ links.map((link, i) => {
30933
+ const from = barGeometry.get(link.from);
30934
+ const to = barGeometry.get(link.to);
30935
+ if (!from || !to) return null;
30936
+ const midX = from.x1 + Math.max(8, (to.x0 - from.x1) / 2);
30937
+ return /* @__PURE__ */ jsx(
30938
+ "path",
30939
+ {
30940
+ d: `M ${from.x1} ${from.y} L ${midX} ${from.y} L ${midX} ${to.y} L ${to.x0} ${to.y}`,
30941
+ fill: "none",
30942
+ stroke: "var(--muted-foreground, currentColor)",
30943
+ strokeWidth: 1.5,
30944
+ markerEnd: "url(#gantt-arrow)"
30945
+ },
30946
+ i
30947
+ );
30948
+ })
30949
+ ]
30950
+ }
30951
+ ),
30952
+ showToday && todayOffset !== null && /* @__PURE__ */ jsx(
30953
+ Box,
30954
+ {
30955
+ className: "absolute top-0 bottom-0 w-0.5 bg-error/70 pointer-events-none",
30956
+ style: { left: LABEL_WIDTH + todayOffset }
30957
+ }
30958
+ )
30959
+ ] })
30960
+ ] })
30961
+ }
30962
+ );
30963
+ }
30964
+ var DAY_MS, ROW_HEIGHT, HEADER_HEIGHT, LABEL_WIDTH, STATUS_BAR;
30965
+ var init_Gantt = __esm({
30966
+ "components/core/molecules/Gantt.tsx"() {
30967
+ "use client";
30968
+ init_cn();
30969
+ init_getNestedValue();
30970
+ init_Box();
30971
+ init_Stack();
30972
+ init_Typography();
30973
+ init_LoadingState();
30974
+ init_EmptyState();
30975
+ DAY_MS = 24 * 60 * 60 * 1e3;
30976
+ ROW_HEIGHT = 36;
30977
+ HEADER_HEIGHT = 44;
30978
+ LABEL_WIDTH = 192;
30979
+ STATUS_BAR = {
30980
+ complete: "bg-success/80 hover:bg-success",
30981
+ done: "bg-success/80 hover:bg-success",
30982
+ active: "bg-primary/80 hover:bg-primary",
30983
+ "in-progress": "bg-primary/80 hover:bg-primary",
30984
+ blocked: "bg-error/80 hover:bg-error",
30985
+ error: "bg-error/80 hover:bg-error",
30986
+ "at-risk": "bg-warning/80 hover:bg-warning",
30987
+ pending: "bg-muted-foreground/50 hover:bg-muted-foreground/70"
30988
+ };
30989
+ Gantt.displayName = "Gantt";
30990
+ }
30991
+ });
30751
30992
  var RepeatableFormSection;
30752
30993
  var init_RepeatableFormSection = __esm({
30753
30994
  "components/core/molecules/RepeatableFormSection.tsx"() {
@@ -45750,6 +45991,7 @@ var init_molecules2 = __esm({
45750
45991
  init_QuizBlock();
45751
45992
  init_ScaledDiagram();
45752
45993
  init_CalendarGrid();
45994
+ init_Gantt();
45753
45995
  init_RepeatableFormSection();
45754
45996
  init_ViolationAlert();
45755
45997
  init_FormSectionHeader();
@@ -53021,6 +53263,7 @@ var init_component_registry_generated = __esm({
53021
53263
  init_GameIcon();
53022
53264
  init_GameMenu();
53023
53265
  init_GameShell();
53266
+ init_Gantt();
53024
53267
  init_GenericAppTemplate();
53025
53268
  init_GeometricPattern();
53026
53269
  init_GradientDivider();
@@ -53300,6 +53543,7 @@ var init_component_registry_generated = __esm({
53300
53543
  "GameIcon": GameIcon,
53301
53544
  "GameMenu": GameMenu,
53302
53545
  "GameShell": GameShell,
53546
+ "Gantt": Gantt,
53303
53547
  "GenericAppTemplate": GenericAppTemplate,
53304
53548
  "GeometricPattern": GeometricPattern,
53305
53549
  "GradientDivider": GradientDivider,
@@ -56855,7 +57099,7 @@ var I18nContext = createContext({
56855
57099
  });
56856
57100
  I18nContext.displayName = "I18nContext";
56857
57101
  var I18nProvider = I18nContext.Provider;
56858
- function useTranslate117() {
57102
+ function useTranslate118() {
56859
57103
  return useContext(I18nContext);
56860
57104
  }
56861
57105
  function createTranslate(messages) {
@@ -57055,4 +57299,4 @@ function assertUniqueSlotsPerHost(manifest) {
57055
57299
  }
57056
57300
  }
57057
57301
 
57058
- export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AlgoGraphCanvas, AlgorithmCanvas, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AtlasImage, AtlasPanel, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, CommandPalette, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DockLayout, DocumentDetails, DocumentPanel, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmojiPicker, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, FloatingToolbar, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, FxOverlay, GameAudioCue, GameAudioToggle, GameHud, GameIcon, GameMenu, GameShell, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, ImportPreviewTree, ImportProgress, ImportSourcePicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, LearningScene3D, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, Modal, ModalSlot, ModuleCard, Navigation, NodeSlotEditor, NumberStepper, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, PageTransition, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, Presence, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, RichTextEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, ServiceCatalog, SharedEntityStoreContext, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateGraph, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UploadDropZone, VStack, VersionDiff, ViolationAlert, VoteStack, WizardContainer, WizardNavigation, WizardProgress, arrowBetween, assertUniqueSlotsPerHost, billboardLabel, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createInitialGameState, createSharedEntityStore, createTranslate, createUnitAnimationState, cylinderBetween, dispatchCommandPaletteCommand, get3DClickPayload, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, keyChord, makeAsset, makeAssetMap, mapBookData, mergeCaptureTables, meshSphere, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, registerCodeLanguageLoader, renderPatternValue, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, runTickFrame, sanitizeRichHtml, screenToIso, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, useAgentChat, useAnchorRect, useAtlasSliceDataUrl, useAuthContext, useCamera, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useKeyboardRouter, useLongPress, useMediaQuery, useOrbitalHistory, usePresence, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSharedEntitySnapshot, useSharedEntityStore, useSharedEntityStoreContext, useSwipeGesture, useTapReveal, useTraitListens, useTranslate117 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };
57302
+ export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AlgoGraphCanvas, AlgorithmCanvas, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AtlasImage, AtlasPanel, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, CommandPalette, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DockLayout, DocumentDetails, DocumentPanel, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmojiPicker, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, FloatingToolbar, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, FxOverlay, GameAudioCue, GameAudioToggle, GameHud, GameIcon, GameMenu, GameShell, Gantt, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, ImportPreviewTree, ImportProgress, ImportSourcePicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, LearningScene3D, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, Modal, ModalSlot, ModuleCard, Navigation, NodeSlotEditor, NumberStepper, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, PageTransition, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, Presence, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, RichTextEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, ServiceCatalog, SharedEntityStoreContext, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateGraph, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UploadDropZone, VStack, VersionDiff, ViolationAlert, VoteStack, WizardContainer, WizardNavigation, WizardProgress, arrowBetween, assertUniqueSlotsPerHost, billboardLabel, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createInitialGameState, createSharedEntityStore, createTranslate, createUnitAnimationState, cylinderBetween, dispatchCommandPaletteCommand, get3DClickPayload, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, keyChord, makeAsset, makeAssetMap, mapBookData, mergeCaptureTables, meshSphere, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, registerCodeLanguageLoader, renderPatternValue, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, runTickFrame, sanitizeRichHtml, screenToIso, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, useAgentChat, useAnchorRect, useAtlasSliceDataUrl, useAuthContext, useCamera, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useKeyboardRouter, useLongPress, useMediaQuery, useOrbitalHistory, usePresence, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSharedEntitySnapshot, useSharedEntityStore, useSharedEntityStoreContext, useSwipeGesture, useTapReveal, useTraitListens, useTranslate118 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };
@@ -32267,6 +32267,247 @@ var init_WizardNavigation = __esm({
32267
32267
  WizardNavigation.displayName = "WizardNavigation";
32268
32268
  }
32269
32269
  });
32270
+ function parseDay(value) {
32271
+ if (value === void 0 || value === null || value === "") return null;
32272
+ const d = value instanceof Date ? new Date(value.getTime()) : new Date(value);
32273
+ if (Number.isNaN(d.getTime())) return null;
32274
+ d.setHours(0, 0, 0, 0);
32275
+ return d;
32276
+ }
32277
+ function Gantt({
32278
+ tasks = [],
32279
+ links = [],
32280
+ titleField = "title",
32281
+ startField = "start",
32282
+ endField = "end",
32283
+ durationField,
32284
+ statusField = "status",
32285
+ groupField = "",
32286
+ rangeStart,
32287
+ rangeEnd,
32288
+ showToday = true,
32289
+ dayWidth = 28,
32290
+ barClickEvent,
32291
+ className,
32292
+ isLoading = false,
32293
+ error = null
32294
+ }) {
32295
+ const { t } = hooks.useTranslate();
32296
+ const placed = React89.useMemo(() => {
32297
+ const rows = Array.isArray(tasks) ? tasks : tasks ? [tasks] : [];
32298
+ const out = [];
32299
+ rows.forEach((row, idx) => {
32300
+ const start = parseDay(core.getNestedValue(row, startField));
32301
+ if (!start) return;
32302
+ let end = parseDay(core.getNestedValue(row, endField));
32303
+ if (!end && durationField) {
32304
+ const days2 = Number(core.getNestedValue(row, durationField));
32305
+ if (Number.isFinite(days2) && days2 > 0) {
32306
+ end = new Date(start.getTime() + days2 * DAY_MS);
32307
+ }
32308
+ }
32309
+ if (!end || end.getTime() < start.getTime()) end = new Date(start.getTime() + DAY_MS);
32310
+ out.push({
32311
+ row,
32312
+ id: String(row.id ?? idx),
32313
+ label: String(core.getNestedValue(row, titleField) ?? ""),
32314
+ status: String(core.getNestedValue(row, statusField) ?? "").toLowerCase(),
32315
+ group: groupField ? String(core.getNestedValue(row, groupField) ?? "") : "",
32316
+ start,
32317
+ end
32318
+ });
32319
+ });
32320
+ return out;
32321
+ }, [tasks, titleField, startField, endField, durationField, statusField, groupField]);
32322
+ const [axisStart, axisEnd] = React89.useMemo(() => {
32323
+ const lo = parseDay(rangeStart) ?? (placed.length ? new Date(Math.min(...placed.map((p) => p.start.getTime())) - 2 * DAY_MS) : new Date((/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0)));
32324
+ const hi = parseDay(rangeEnd) ?? (placed.length ? new Date(Math.max(...placed.map((p) => p.end.getTime())) + 2 * DAY_MS) : new Date(lo.getTime() + 30 * DAY_MS));
32325
+ return hi.getTime() > lo.getTime() ? [lo, hi] : [lo, new Date(lo.getTime() + DAY_MS)];
32326
+ }, [rangeStart, rangeEnd, placed]);
32327
+ const totalDays = Math.round((axisEnd.getTime() - axisStart.getTime()) / DAY_MS);
32328
+ const chartWidth = totalDays * dayWidth;
32329
+ const dayOffset = (d) => (d.getTime() - axisStart.getTime()) / DAY_MS * dayWidth;
32330
+ const displayItems = React89.useMemo(() => {
32331
+ if (!groupField) return placed.map((task) => ({ kind: "task", task }));
32332
+ const items = [];
32333
+ const seen = /* @__PURE__ */ new Set();
32334
+ for (const task of placed) {
32335
+ if (!seen.has(task.group)) {
32336
+ seen.add(task.group);
32337
+ items.push({ kind: "group", label: task.group || "\u2014" });
32338
+ }
32339
+ items.push({ kind: "task", task });
32340
+ }
32341
+ return items;
32342
+ }, [placed, groupField]);
32343
+ const barGeometry = React89.useMemo(() => {
32344
+ const offset = (d) => (d.getTime() - axisStart.getTime()) / DAY_MS * dayWidth;
32345
+ const map = /* @__PURE__ */ new Map();
32346
+ displayItems.forEach((item, idx) => {
32347
+ if (item.kind !== "task") return;
32348
+ const x0 = offset(item.task.start);
32349
+ const x1 = Math.max(offset(item.task.end), x0 + dayWidth / 2);
32350
+ map.set(item.task.id, { x0, x1, y: HEADER_HEIGHT + idx * ROW_HEIGHT + ROW_HEIGHT / 2 });
32351
+ });
32352
+ return map;
32353
+ }, [displayItems, axisStart, dayWidth]);
32354
+ const days = React89.useMemo(() => {
32355
+ const out = [];
32356
+ for (let i = 0; i < totalDays; i++) out.push(new Date(axisStart.getTime() + i * DAY_MS));
32357
+ return out;
32358
+ }, [axisStart, totalDays]);
32359
+ const todayOffset = React89.useMemo(() => {
32360
+ const today = parseDay(/* @__PURE__ */ new Date());
32361
+ if (!today || today < axisStart || today > axisEnd) return null;
32362
+ return (today.getTime() - axisStart.getTime()) / DAY_MS * dayWidth;
32363
+ }, [axisStart, axisEnd, dayWidth]);
32364
+ if (isLoading) {
32365
+ return /* @__PURE__ */ jsxRuntime.jsx(LoadingState, { message: t("common.loading"), className });
32366
+ }
32367
+ if (error) {
32368
+ return /* @__PURE__ */ jsxRuntime.jsx(Box, { className: cn("p-4", className), children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "error", children: error.message }) });
32369
+ }
32370
+ if (placed.length === 0) {
32371
+ return /* @__PURE__ */ jsxRuntime.jsx(
32372
+ EmptyState,
32373
+ {
32374
+ title: t("empty.noData"),
32375
+ className
32376
+ }
32377
+ );
32378
+ }
32379
+ return /* @__PURE__ */ jsxRuntime.jsx(
32380
+ Box,
32381
+ {
32382
+ className: cn("w-full overflow-auto rounded-md border border-border bg-card", className),
32383
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "relative", style: { width: LABEL_WIDTH + chartWidth, minWidth: "100%" }, children: [
32384
+ /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "none", className: "sticky top-0 z-20 bg-card border-b border-border", style: { height: HEADER_HEIGHT }, children: [
32385
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "sticky left-0 z-10 shrink-0 bg-card border-r border-border", style: { width: LABEL_WIDTH, height: HEADER_HEIGHT } }),
32386
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "relative", style: { width: chartWidth, height: HEADER_HEIGHT }, children: days.map((day, i) => /* @__PURE__ */ jsxRuntime.jsx(
32387
+ Box,
32388
+ {
32389
+ className: cn(
32390
+ "absolute top-0 bottom-0 border-l border-border/50 flex items-end justify-center pb-1",
32391
+ day.getDay() === 0 || day.getDay() === 6 ? "bg-muted/40" : void 0
32392
+ ),
32393
+ style: { left: i * dayWidth, width: dayWidth },
32394
+ children: dayWidth >= 20 && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", color: "secondary", children: day.getDate() })
32395
+ },
32396
+ i
32397
+ )) })
32398
+ ] }),
32399
+ /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "none", className: "relative", children: [
32400
+ displayItems.map(
32401
+ (item, idx) => item.kind === "group" ? /* @__PURE__ */ jsxRuntime.jsxs(
32402
+ HStack,
32403
+ {
32404
+ gap: "none",
32405
+ className: "border-b border-border bg-muted/30",
32406
+ style: { height: ROW_HEIGHT },
32407
+ children: [
32408
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "sticky left-0 z-10 shrink-0 bg-muted/30 px-3 flex items-center border-r border-border", style: { width: LABEL_WIDTH, height: ROW_HEIGHT }, children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "caption", weight: "semibold", children: item.label }) }),
32409
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { style: { width: chartWidth, height: ROW_HEIGHT } })
32410
+ ]
32411
+ },
32412
+ `g-${idx}`
32413
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(
32414
+ HStack,
32415
+ {
32416
+ gap: "none",
32417
+ className: "border-b border-border/50",
32418
+ style: { height: ROW_HEIGHT },
32419
+ children: [
32420
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "sticky left-0 z-10 shrink-0 bg-card px-3 flex items-center border-r border-border", style: { width: LABEL_WIDTH, height: ROW_HEIGHT }, children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "truncate", children: item.task.label }) }),
32421
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { className: "relative", style: { width: chartWidth, height: ROW_HEIGHT }, children: /* @__PURE__ */ jsxRuntime.jsx(
32422
+ Box,
32423
+ {
32424
+ className: cn(
32425
+ "absolute top-1/2 -translate-y-1/2 h-4 rounded-sm transition-colors",
32426
+ STATUS_BAR[item.task.status] ?? "bg-primary/80 hover:bg-primary",
32427
+ barClickEvent ? "cursor-pointer" : void 0
32428
+ ),
32429
+ style: {
32430
+ left: dayOffset(item.task.start),
32431
+ width: Math.max(dayOffset(item.task.end) - dayOffset(item.task.start), dayWidth / 2)
32432
+ },
32433
+ action: barClickEvent,
32434
+ actionPayload: { id: item.task.id }
32435
+ }
32436
+ ) })
32437
+ ]
32438
+ },
32439
+ item.task.id
32440
+ )
32441
+ ),
32442
+ links.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
32443
+ "svg",
32444
+ {
32445
+ className: "absolute pointer-events-none",
32446
+ style: { left: LABEL_WIDTH, top: 0 },
32447
+ width: chartWidth,
32448
+ height: HEADER_HEIGHT + displayItems.length * ROW_HEIGHT,
32449
+ children: [
32450
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("marker", { id: "gantt-arrow", markerWidth: "8", markerHeight: "8", refX: "7", refY: "4", orient: "auto", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0,0 L8,4 L0,8 z", fill: "var(--muted-foreground, currentColor)" }) }) }),
32451
+ links.map((link, i) => {
32452
+ const from = barGeometry.get(link.from);
32453
+ const to = barGeometry.get(link.to);
32454
+ if (!from || !to) return null;
32455
+ const midX = from.x1 + Math.max(8, (to.x0 - from.x1) / 2);
32456
+ return /* @__PURE__ */ jsxRuntime.jsx(
32457
+ "path",
32458
+ {
32459
+ d: `M ${from.x1} ${from.y} L ${midX} ${from.y} L ${midX} ${to.y} L ${to.x0} ${to.y}`,
32460
+ fill: "none",
32461
+ stroke: "var(--muted-foreground, currentColor)",
32462
+ strokeWidth: 1.5,
32463
+ markerEnd: "url(#gantt-arrow)"
32464
+ },
32465
+ i
32466
+ );
32467
+ })
32468
+ ]
32469
+ }
32470
+ ),
32471
+ showToday && todayOffset !== null && /* @__PURE__ */ jsxRuntime.jsx(
32472
+ Box,
32473
+ {
32474
+ className: "absolute top-0 bottom-0 w-0.5 bg-error/70 pointer-events-none",
32475
+ style: { left: LABEL_WIDTH + todayOffset }
32476
+ }
32477
+ )
32478
+ ] })
32479
+ ] })
32480
+ }
32481
+ );
32482
+ }
32483
+ var DAY_MS, ROW_HEIGHT, HEADER_HEIGHT, LABEL_WIDTH, STATUS_BAR;
32484
+ var init_Gantt = __esm({
32485
+ "components/core/molecules/Gantt.tsx"() {
32486
+ "use client";
32487
+ init_cn();
32488
+ init_getNestedValue();
32489
+ init_Box();
32490
+ init_Stack();
32491
+ init_Typography();
32492
+ init_LoadingState();
32493
+ init_EmptyState();
32494
+ DAY_MS = 24 * 60 * 60 * 1e3;
32495
+ ROW_HEIGHT = 36;
32496
+ HEADER_HEIGHT = 44;
32497
+ LABEL_WIDTH = 192;
32498
+ STATUS_BAR = {
32499
+ complete: "bg-success/80 hover:bg-success",
32500
+ done: "bg-success/80 hover:bg-success",
32501
+ active: "bg-primary/80 hover:bg-primary",
32502
+ "in-progress": "bg-primary/80 hover:bg-primary",
32503
+ blocked: "bg-error/80 hover:bg-error",
32504
+ error: "bg-error/80 hover:bg-error",
32505
+ "at-risk": "bg-warning/80 hover:bg-warning",
32506
+ pending: "bg-muted-foreground/50 hover:bg-muted-foreground/70"
32507
+ };
32508
+ Gantt.displayName = "Gantt";
32509
+ }
32510
+ });
32270
32511
  var RepeatableFormSection;
32271
32512
  var init_RepeatableFormSection = __esm({
32272
32513
  "components/core/molecules/RepeatableFormSection.tsx"() {
@@ -51814,6 +52055,7 @@ var init_component_registry_generated = __esm({
51814
52055
  init_GameIcon();
51815
52056
  init_GameMenu();
51816
52057
  init_GameShell();
52058
+ init_Gantt();
51817
52059
  init_GenericAppTemplate();
51818
52060
  init_GeometricPattern();
51819
52061
  init_GradientDivider();
@@ -52093,6 +52335,7 @@ var init_component_registry_generated = __esm({
52093
52335
  "GameIcon": GameIcon,
52094
52336
  "GameMenu": GameMenu,
52095
52337
  "GameShell": GameShell,
52338
+ "Gantt": Gantt,
52096
52339
  "GenericAppTemplate": GenericAppTemplate,
52097
52340
  "GeometricPattern": GeometricPattern,
52098
52341
  "GradientDivider": GradientDivider,