@machinemetrics/mm-react-components 1.2.4 → 1.2.5-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/README.md +27 -0
- package/agent-docs/agent-documentation-reference.md +42 -22
- package/agent-docs/tickets-pattern.md +78 -0
- package/dist/README.md +27 -0
- package/dist/components/ui/date-picker.d.ts +8 -1
- package/dist/components/ui/date-picker.d.ts.map +1 -1
- package/dist/components/ui/kanban/KanbanBoard.d.ts +8 -0
- package/dist/components/ui/kanban/KanbanBoard.d.ts.map +1 -0
- package/dist/components/ui/kanban/KanbanCard.d.ts +8 -0
- package/dist/components/ui/kanban/KanbanCard.d.ts.map +1 -0
- package/dist/components/ui/kanban/KanbanCardOverlay.d.ts +8 -0
- package/dist/components/ui/kanban/KanbanCardOverlay.d.ts.map +1 -0
- package/dist/components/ui/kanban/KanbanColumn.d.ts +8 -0
- package/dist/components/ui/kanban/KanbanColumn.d.ts.map +1 -0
- package/dist/components/ui/kanban/KanbanContext.d.ts +28 -0
- package/dist/components/ui/kanban/KanbanContext.d.ts.map +1 -0
- package/dist/components/ui/kanban/dragEndUtils.d.ts +26 -0
- package/dist/components/ui/kanban/dragEndUtils.d.ts.map +1 -0
- package/dist/components/ui/kanban/index.d.ts +9 -0
- package/dist/components/ui/kanban/index.d.ts.map +1 -0
- package/dist/components/ui/kanban/types.d.ts +58 -0
- package/dist/components/ui/kanban/types.d.ts.map +1 -0
- package/dist/components/ui/sheet-banner.d.ts +1 -1
- package/dist/components/ui/sheet-banner.d.ts.map +1 -1
- package/dist/components/ui/tickets/TicketActivitySection.d.ts +20 -0
- package/dist/components/ui/tickets/TicketActivitySection.d.ts.map +1 -0
- package/dist/components/ui/tickets/TicketDates.d.ts +20 -0
- package/dist/components/ui/tickets/TicketDates.d.ts.map +1 -0
- package/dist/components/ui/tickets/TicketDetailLayout.d.ts +32 -0
- package/dist/components/ui/tickets/TicketDetailLayout.d.ts.map +1 -0
- package/dist/components/ui/tickets/TicketDetails.d.ts +32 -0
- package/dist/components/ui/tickets/TicketDetails.d.ts.map +1 -0
- package/dist/components/ui/tickets/TicketDetailsSidebar.d.ts +21 -0
- package/dist/components/ui/tickets/TicketDetailsSidebar.d.ts.map +1 -0
- package/dist/components/ui/tickets/TicketFieldControl.d.ts +32 -0
- package/dist/components/ui/tickets/TicketFieldControl.d.ts.map +1 -0
- package/dist/components/ui/tickets/TicketForm.d.ts +22 -0
- package/dist/components/ui/tickets/TicketForm.d.ts.map +1 -0
- package/dist/components/ui/tickets/TicketLabels.d.ts +57 -0
- package/dist/components/ui/tickets/TicketLabels.d.ts.map +1 -0
- package/dist/components/ui/tickets/TicketTypes.d.ts +67 -0
- package/dist/components/ui/tickets/TicketTypes.d.ts.map +1 -0
- package/dist/components/ui/tickets/TicketUserSelect.d.ts +17 -0
- package/dist/components/ui/tickets/TicketUserSelect.d.ts.map +1 -0
- package/dist/components/ui/tickets/UserDisplay.d.ts +21 -0
- package/dist/components/ui/tickets/UserDisplay.d.ts.map +1 -0
- package/dist/components/ui/tickets/UserFieldValue.d.ts +24 -0
- package/dist/components/ui/tickets/UserFieldValue.d.ts.map +1 -0
- package/dist/components/ui/tickets/index.d.ts +12 -0
- package/dist/components/ui/tickets/index.d.ts.map +1 -0
- package/dist/docs/GETTING_STARTED.md +26 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/mm-react-components.css +1 -1
- package/dist/lib/normalize-host-color-mode.d.ts +6 -0
- package/dist/lib/normalize-host-color-mode.d.ts.map +1 -0
- package/dist/lib/theme-root.d.ts +18 -0
- package/dist/lib/theme-root.d.ts.map +1 -0
- package/dist/lib/use-host-theme.d.ts +15 -0
- package/dist/lib/use-host-theme.d.ts.map +1 -0
- package/dist/mm-react-components.es.js +830 -753
- package/dist/mm-react-components.es.js.map +1 -1
- package/dist/mm-react-components.umd.js +1 -1
- package/dist/mm-react-components.umd.js.map +1 -1
- package/dist/preview/KanbanPreview.d.ts +2 -0
- package/dist/preview/KanbanPreview.d.ts.map +1 -0
- package/dist/preview/SheetBannerPreview.d.ts.map +1 -1
- package/dist/preview/TicketsPreview.d.ts +2 -0
- package/dist/preview/TicketsPreview.d.ts.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -19,6 +19,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
19
19
|
|
|
20
20
|
- Preview app: `CodePreview` route remains hash-only for tests; sidebar exclusions updated. Preview build trims `esbuild.keepNames` where snippet naming no longer requires it.
|
|
21
21
|
|
|
22
|
+
## [Unreleased]
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- **TicketDetails:** Two-column **narrative + metadata** layout: header includes ticket id, title, and **status / priority / due** (keys `status`, `priority`, `dueDate`, `due`); main column is **description** then **Activity** with **All / Comments / Updates** tabs; right rail is **Details** (people), **Dates**, and **Custom fields** with optional **Show more** and sticky positioning on large viewports. Optional `onBack` and `onAddCustomField`. `data-slot` hooks for Carbide theming.
|
|
27
|
+
- **`partitionDetailFields`:** Now returns `headerFields`, `mainColumnFields`, `sidebarPeopleFields`, `sidebarDateFields`, `sidebarCustomFields`, and composed `sidebarFields` (people → dates → custom). `assignee` key maps to the people rail. **Breaking for consumers** that assumed `status` / `priority` / `dueDate` lived only in `sidebarFields` or that `otherMainFields` rendered in the main column — those fields are repositioned in the default `TicketDetails` shell (see `PartitionDetailFieldsResult`).
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- **`TicketSystemEvent`** and optional `TicketDetails` prop **`systemEvents`** for the Updates timeline and All-tab merge.
|
|
32
|
+
- **`TicketFieldControl`:** optional **`layout="inline"`** for compact header controls; **`date`** fields use the Carbide **`DatePicker`** (not native `<input type="date">`).
|
|
33
|
+
- **`DatePicker`:** optional **`triggerClassName`** for trigger button styling; optional **`aria-invalid`** / **`aria-describedby`** on the trigger; **controlled `month`** resets when the popover opens so the calendar shows the **selected date’s month** (or `defaultMonth` / today when empty).
|
|
34
|
+
- **`TicketForm`:** **`date`** fields use **`DatePicker`** (not native `<input type="date">`).
|
|
35
|
+
- **`parseTicketDateString`** / **`formatTicketDateString`** exported from the tickets module for host apps.
|
|
36
|
+
- **`TicketFieldType` `updatedDate`:** Read-only timestamp for “last updated” (and similar). Renders as styled text in **`TicketForm`** and **`TicketDetails`** — never an `<input>`. Use **`formatTicketTimestampDisplay`** for custom UIs; value is typically ISO or `YYYY-MM-DD` on the ticket payload.
|
|
37
|
+
- **`TicketDetailsLabels`:** strings for activity tabs, sidebar section titles, back button, show more/less, add field, and comment body label.
|
|
38
|
+
|
|
39
|
+
## [1.3.0] - 2026-03-19
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- **TicketDetails** (formerly `TicketDetailSheet`): Renders **detail content only** (no outer `Sheet`), same presentation-only model as `TicketForm`. No `open` / `onClose` / `onOpen`; the host controls visibility and chrome (e.g. `Sheet` + `SheetContent` with its own close). Renamed exports: `TicketDetails`, `TicketDetailsProps`, `TicketDetailsLabels`, `defaultTicketDetailsLabels`, `mergeTicketDetailsLabels`. Removed `closeAriaLabel` from detail labels (library no longer renders a close control).
|
|
44
|
+
- **Tickets module file names:** Renamed to PascalCase under `src/components/ui/tickets/` (`TicketTypes.ts`, `TicketLabels.ts`, `UserFieldValue.ts`, `TicketUserSelect.tsx`, `TicketDates.ts`, `TicketDetailLayout.ts`) for consistency with other feature folders.
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- **Ticket pattern components:** `TicketForm`, `TicketDetails`, `TicketFieldControl`, and `UserDisplay` for schema-driven ticket create/edit and detail UI. Host apps inject `userSelectComponent` and own persistence (`onSubmit`, `onCancel`, `onValuesChange`, `onPostComment`). Optional `labels` props override default copy.
|
|
49
|
+
- **Ticket utilities and types:** Exported `Ticket`, `TicketFieldDefinition`, `Comment`, and helpers (`fieldKeyToHeader`, `getMergedDetailFields`, `partitionDetailFields`, `formatCreationDate`, `formatRelativeTime`, user-field JSON helpers).
|
|
50
|
+
- **Docs:** `src/components/ui/tickets/README.md`, `agent-docs/tickets-pattern.md`, and agent-documentation-reference table entry.
|
|
51
|
+
- **Kanban:** Compound `KanbanBoard`, `KanbanColumn`, `KanbanCard`, and `KanbanCardOverlay` with `@dnd-kit` drag-and-drop. Helpers `dataToKanbanItems`, `normalizeToKanbanColumn`, and `computeMoveFromDragEnd` map table-shaped data to board items and derive moves from drag-end events. Column chrome uses `SheetBanner`; README, preview, Playwright visual tests, and agent-documentation-reference updates.
|
|
52
|
+
|
|
22
53
|
---
|
|
23
54
|
|
|
24
55
|
## [1.2.3] - 2026-03-23
|
package/README.md
CHANGED
|
@@ -186,6 +186,33 @@ document.documentElement.classList.add('carbide');
|
|
|
186
186
|
- You want to minimize bundle size
|
|
187
187
|
- You're using our components with your own Tailwind config
|
|
188
188
|
|
|
189
|
+
#### Embedded apps: `ThemeRoot` and `useHostTheme`
|
|
190
|
+
|
|
191
|
+
For apps hosted inside the MachineMetrics shell (or any host that passes a light/dark value), wrap the tree once and sync the host value—no `next-themes` setup boilerplate.
|
|
192
|
+
|
|
193
|
+
`ThemeRoot` wraps your React tree (e.g. inside `#root`). It does **not** replace `<html>` in `index.html`; it still toggles `light` / `dark` on `document.documentElement`. Keep `class="carbide"` on `<html>` and import Carbide CSS as usual.
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
// index.tsx
|
|
197
|
+
import { ThemeRoot } from '@machinemetrics/mm-react-components';
|
|
198
|
+
|
|
199
|
+
<ThemeRoot>
|
|
200
|
+
<App />
|
|
201
|
+
</ThemeRoot>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
```tsx
|
|
205
|
+
// App.tsx — pass the host color mode (example: mm-react-tools)
|
|
206
|
+
import { useHostTheme } from '@machinemetrics/mm-react-components';
|
|
207
|
+
import { useMMAppParams } from '@machinemetrics/mm-react-tools';
|
|
208
|
+
|
|
209
|
+
useHostTheme(useMMAppParams().colorMode);
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
If you need `useTheme()` elsewhere (e.g. markdown styling), import it from **`@machinemetrics/mm-react-components`** so it uses the same context as `ThemeRoot`—not from the `next-themes` package directly.
|
|
213
|
+
|
|
214
|
+
Optional: pass any `ThemeProvider` prop to `ThemeRoot` to override defaults (e.g. `storageKey` for standalone persistence).
|
|
215
|
+
|
|
189
216
|
#### Option 3: Use Theme Utilities
|
|
190
217
|
|
|
191
218
|
```tsx
|
|
@@ -54,14 +54,14 @@ This directory contains comprehensive documentation and tools for AI agents work
|
|
|
54
54
|
|
|
55
55
|
### Layout & Navigation
|
|
56
56
|
|
|
57
|
-
| Component | Exports | Description
|
|
58
|
-
| -------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
59
|
-
| **Card** | `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, `CardFooter` | Content container with sections (no built-in scroll)
|
|
57
|
+
| Component | Exports | Description |
|
|
58
|
+
| -------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
59
|
+
| **Card** | `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, `CardFooter` | Content container with sections (no built-in scroll) |
|
|
60
60
|
| **ScrollArea** | `ScrollArea`, `ScrollBar` | Scrollable region; **must have constrained height** (e.g. `h-[300px]`, `max-h-[50vh]`, or `flex-1 min-h-0` in flex layout) or it won’t scroll |
|
|
61
|
-
| **Separator** | `Separator` | Visual divider
|
|
62
|
-
| **Tabs** | `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` | Tabbed interface
|
|
63
|
-
| **Breadcrumb** | `Breadcrumb`, `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbLink`, `BreadcrumbPage`, `BreadcrumbSeparator`, `BreadcrumbEllipsis` | Navigation breadcrumbs
|
|
64
|
-
| **PageHeader** | `PageHeader` (+ types) | Application page header with actions/tabs
|
|
61
|
+
| **Separator** | `Separator` | Visual divider |
|
|
62
|
+
| **Tabs** | `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` | Tabbed interface |
|
|
63
|
+
| **Breadcrumb** | `Breadcrumb`, `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbLink`, `BreadcrumbPage`, `BreadcrumbSeparator`, `BreadcrumbEllipsis` | Navigation breadcrumbs |
|
|
64
|
+
| **PageHeader** | `PageHeader` (+ types) | Application page header with actions/tabs |
|
|
65
65
|
|
|
66
66
|
### Overlays & Modals
|
|
67
67
|
|
|
@@ -96,15 +96,17 @@ This directory contains comprehensive documentation and tools for AI agents work
|
|
|
96
96
|
|
|
97
97
|
### Advanced Components
|
|
98
98
|
|
|
99
|
-
| Component | Exports
|
|
100
|
-
| ------------------- |
|
|
101
|
-
| **DataTable** | `DataTable`, `DataTablePagination`, `ResponsiveTable`, `TABLE_TOKENS`, column creators, hooks, toolbar, CSV export (+ types)
|
|
102
|
-
| **HeroMetricCard** | `HeroMetricCard`, `HeroMetricCardItem` (+ types)
|
|
103
|
-
| **Calendar** | `Calendar`
|
|
104
|
-
| **DatePicker** | `DatePicker`
|
|
105
|
-
| **DateRangePicker** | `DateRangePicker`
|
|
106
|
-
| **Dropzone** | `Dropzone`, `DropzoneContent`, `DropzoneEmptyState`
|
|
107
|
-
| **
|
|
99
|
+
| Component | Exports | Description |
|
|
100
|
+
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
101
|
+
| **DataTable** | `DataTable`, `DataTablePagination`, `ResponsiveTable`, `TABLE_TOKENS`, column creators, hooks, toolbar, CSV export (+ types) | Full-featured data table with sorting, filtering, pagination (client-side & server-side) |
|
|
102
|
+
| **HeroMetricCard** | `HeroMetricCard`, `HeroMetricCardItem` (+ types) | Metrics dashboard card with trends |
|
|
103
|
+
| **Calendar** | `Calendar` | Date picker calendar |
|
|
104
|
+
| **DatePicker** | `DatePicker` | Single date selection with label and placeholder |
|
|
105
|
+
| **DateRangePicker** | `DateRangePicker` | Date range selection |
|
|
106
|
+
| **Dropzone** | `Dropzone`, `DropzoneContent`, `DropzoneEmptyState` | File upload drag-drop |
|
|
107
|
+
| **Kanban** | `KanbanBoard`, `KanbanColumn`, `KanbanCard`, `KanbanCardOverlay`, `normalizeToKanbanColumn`, `dataToKanbanItems` (+ types) | Drag-and-drop Kanban board; compound API; same columns/data as DataTable |
|
|
108
|
+
| **Tickets** | `TicketForm`, `TicketDetails`, `TicketFieldControl`, `UserDisplay`, field helpers (`formatTicketTimestampDisplay`, …), `TicketSystemEvent`, `PartitionDetailFieldsResult` (+ `TicketUserSelectComponent`) | Schema-driven ticket form and detail UI; **`data-slot`** on form/details/field wrapper (see tickets README); optional `systemEvents` / `onBack` / `onAddCustomField` |
|
|
109
|
+
| **Chart** | `ChartContainer`, `ChartTooltip`, `ChartTooltipContent`, `ChartLegend`, `ChartLegendContent`, `ChartStyle` (+ `ChartConfig` type) | Recharts integration |
|
|
108
110
|
|
|
109
111
|
### Interactive Elements
|
|
110
112
|
|
|
@@ -128,6 +130,18 @@ All components follow shadcn/ui patterns with Carbide theme integration for indu
|
|
|
128
130
|
|
|
129
131
|
## Component Usage Guides
|
|
130
132
|
|
|
133
|
+
### Table + Kanban from same columns and data
|
|
134
|
+
|
|
135
|
+
Use the same column definitions and data for both DataTable and Kanban:
|
|
136
|
+
|
|
137
|
+
- **Columns**: Pass table column objects directly to `KanbanColumn` via `column={col}` (accepts `{ id, title? }` or `{ id, header? }`).
|
|
138
|
+
- **Items**: `const items = dataToKanbanItems(data, { columnIdKey: 'status', titleKey: 'name' });` then filter by column when rendering cards.
|
|
139
|
+
- **Compound API**: `<KanbanBoard onMove={...}><KanbanColumn column={col}>…<KanbanCard item={item}>…</KanbanCard>…</KanbanColumn></KanbanBoard>`. Card content is children of `KanbanCard`. Optional `renderDragPreview(item)` for custom drag overlay.
|
|
140
|
+
|
|
141
|
+
### Ticket form and detail sheet
|
|
142
|
+
|
|
143
|
+
Schema-driven ticket UI (`TicketForm`, `TicketDetails`, `TicketFieldControl`) — inject a user picker (`TicketUserSelectComponent`), pass `onSubmit` / `onCancel`, and wire `onValuesChange` + `comments` / `onPostComment` / optional `systemEvents`. `TicketDetails` has no open/close API; mount it wherever needed (header metadata, Activity tabs, sticky sidebar). See **[tickets-pattern.md](./tickets-pattern.md)**.
|
|
144
|
+
|
|
131
145
|
### Scrolling content: Card vs ScrollArea
|
|
132
146
|
|
|
133
147
|
**There is no "Panel" component.** For a panel-like or card-like region where content may be longer than the visible area, use **ScrollArea** around the scrollable content. **Card** is a structural container (border, padding, sections) and does not add scrolling.
|
|
@@ -139,25 +153,31 @@ All components follow shadcn/ui patterns with Carbide theme integration for indu
|
|
|
139
153
|
**Pattern for a scrollable card/panel:**
|
|
140
154
|
|
|
141
155
|
```tsx
|
|
142
|
-
import {
|
|
156
|
+
import {
|
|
157
|
+
Card,
|
|
158
|
+
CardHeader,
|
|
159
|
+
CardTitle,
|
|
160
|
+
CardContent,
|
|
161
|
+
ScrollArea,
|
|
162
|
+
} from '@machinemetrics/mm-react-components';
|
|
143
163
|
|
|
144
164
|
<Card className="flex max-h-[80vh] flex-col">
|
|
145
165
|
<CardHeader>
|
|
146
166
|
<CardTitle>Panel title</CardTitle>
|
|
147
167
|
</CardHeader>
|
|
148
168
|
<ScrollArea className="flex-1 min-h-0">
|
|
149
|
-
<CardContent>
|
|
150
|
-
{/* Long content here scrolls inside the card */}
|
|
151
|
-
</CardContent>
|
|
169
|
+
<CardContent>{/* Long content here scrolls inside the card */}</CardContent>
|
|
152
170
|
</ScrollArea>
|
|
153
|
-
</Card
|
|
171
|
+
</Card>;
|
|
154
172
|
```
|
|
155
173
|
|
|
156
174
|
Or wrap only the body in ScrollArea with a fixed height:
|
|
157
175
|
|
|
158
176
|
```tsx
|
|
159
177
|
<Card>
|
|
160
|
-
<CardHeader
|
|
178
|
+
<CardHeader>
|
|
179
|
+
<CardTitle>Title</CardTitle>
|
|
180
|
+
</CardHeader>
|
|
161
181
|
<ScrollArea className="h-[200px] rounded-md border">
|
|
162
182
|
<div className="p-4">{/* long content */}</div>
|
|
163
183
|
</ScrollArea>
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Ticket pattern (`TicketForm`, `TicketDetails`)
|
|
2
|
+
|
|
3
|
+
Carbide-composed UI for configurable work-item fields: form, per-field control, and **detail body** (header with id + title + status/priority/due, main column for description + activity, sticky metadata rail). Same idea as `TicketForm` — **presentation only**: no overlay, open state, or routing inside the library. Your app chooses where it mounts (page, `Sheet`, drawer) and owns visibility.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import {
|
|
9
|
+
TicketForm,
|
|
10
|
+
TicketDetails,
|
|
11
|
+
UserDisplay,
|
|
12
|
+
fieldKeyToHeader,
|
|
13
|
+
Sheet,
|
|
14
|
+
SheetContent,
|
|
15
|
+
} from '@machinemetrics/mm-react-components';
|
|
16
|
+
import { MyUserSelect } from './MyUserSelect';
|
|
17
|
+
|
|
18
|
+
<TicketForm
|
|
19
|
+
fieldDefinitions={defs}
|
|
20
|
+
onSubmit={(values) => saveTicket(values)}
|
|
21
|
+
onCancel={() => navigate(-1)}
|
|
22
|
+
getDisplayName={(id) => ...}
|
|
23
|
+
getCurrentUser={() => api.getMe()}
|
|
24
|
+
userSelectComponent={MyUserSelect}
|
|
25
|
+
/>;
|
|
26
|
+
|
|
27
|
+
<Sheet open={open} onOpenChange={setOpen}>
|
|
28
|
+
<SheetContent side="right" className="p-0 flex flex-col ...">
|
|
29
|
+
<TicketDetails
|
|
30
|
+
ticket={ticket}
|
|
31
|
+
ticketFieldDefinitions={ticketDefs}
|
|
32
|
+
formFieldDefinitions={formDefs}
|
|
33
|
+
getDisplayName={(id) => ...}
|
|
34
|
+
usersLoading={loading}
|
|
35
|
+
onValuesChange={(next) => updateTicket(ticket.id, next)}
|
|
36
|
+
userSelectComponent={MyUserSelect}
|
|
37
|
+
comments={comments}
|
|
38
|
+
systemEvents={systemEvents}
|
|
39
|
+
onPostComment={({ authorUserId, body }) => addComment(...)}
|
|
40
|
+
onBack={() => setOpen(false)}
|
|
41
|
+
onAddCustomField={() => openAddFieldFlow()}
|
|
42
|
+
/>
|
|
43
|
+
</SheetContent>
|
|
44
|
+
</Sheet>;
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Types
|
|
48
|
+
|
|
49
|
+
Use exported `TicketFieldDefinition`, `Ticket`, `Comment`, `TicketSystemEvent`, and `TicketConfig` for shared shapes between host and UI.
|
|
50
|
+
|
|
51
|
+
For **read-only timestamps** (e.g. last updated), use **`type: 'updatedDate'`** on the field — not `text` or `date`. The UI shows a muted read-only line; the host still passes the raw value (typically ISO) on the ticket. Use **`formatTicketTimestampDisplay`** if you render the value elsewhere.
|
|
52
|
+
|
|
53
|
+
## Layout helpers
|
|
54
|
+
|
|
55
|
+
`partitionDetailFields` returns `headerFields`, `mainColumnFields`, `sidebarPeopleFields`, `sidebarDateFields`, `sidebarCustomFields`, plus `sidebarFields` (flattened rail list), `mainTopFields` (same as main column / description), and `otherMainFields` (same as custom — legacy names). Use these if you build a custom shell instead of `TicketDetails`.
|
|
56
|
+
|
|
57
|
+
## Activity
|
|
58
|
+
|
|
59
|
+
- **Comments** — existing `Comment[]` and `onPostComment`.
|
|
60
|
+
- **System events** — optional `TicketSystemEvent[]` (`id`, `createdAt`, `message`) for the **Updates** tab; merged chronologically with comments under **All**.
|
|
61
|
+
|
|
62
|
+
## Copy / i18n
|
|
63
|
+
|
|
64
|
+
Pass `labels` (see `TicketFormLabels`, `TicketDetailsLabels`, `TicketFieldControlLabels`) or use `mergeTicketFormLabels` / `mergeTicketDetailsLabels` defaults.
|
|
65
|
+
|
|
66
|
+
## Theming
|
|
67
|
+
|
|
68
|
+
Carbide hooks use `data-slot` on ticket surfaces:
|
|
69
|
+
|
|
70
|
+
- **`TicketForm`:** `ticket-form` (root form), `ticket-form-readonly-field` (e.g. `updatedDate`, `currentUser` rows).
|
|
71
|
+
- **`TicketDetails`:** `ticket-details`, `ticket-details-header`, `ticket-details-main`, `ticket-details-activity`, `ticket-details-sidebar`.
|
|
72
|
+
- **`TicketFieldControl`:** `ticket-field-control` wraps each field; primitives inside still expose their own slots (`input`, `date-picker`, etc.).
|
|
73
|
+
|
|
74
|
+
See [src/components/ui/tickets/README.md](../src/components/ui/tickets/README.md) for the full table.
|
|
75
|
+
|
|
76
|
+
## See also
|
|
77
|
+
|
|
78
|
+
- [src/components/ui/tickets/README.md](../src/components/ui/tickets/README.md) (source tree; also shipped in repo)
|
package/dist/README.md
CHANGED
|
@@ -186,6 +186,33 @@ document.documentElement.classList.add('carbide');
|
|
|
186
186
|
- You want to minimize bundle size
|
|
187
187
|
- You're using our components with your own Tailwind config
|
|
188
188
|
|
|
189
|
+
#### Embedded apps: `ThemeRoot` and `useHostTheme`
|
|
190
|
+
|
|
191
|
+
For apps hosted inside the MachineMetrics shell (or any host that passes a light/dark value), wrap the tree once and sync the host value—no `next-themes` setup boilerplate.
|
|
192
|
+
|
|
193
|
+
`ThemeRoot` wraps your React tree (e.g. inside `#root`). It does **not** replace `<html>` in `index.html`; it still toggles `light` / `dark` on `document.documentElement`. Keep `class="carbide"` on `<html>` and import Carbide CSS as usual.
|
|
194
|
+
|
|
195
|
+
```tsx
|
|
196
|
+
// index.tsx
|
|
197
|
+
import { ThemeRoot } from '@machinemetrics/mm-react-components';
|
|
198
|
+
|
|
199
|
+
<ThemeRoot>
|
|
200
|
+
<App />
|
|
201
|
+
</ThemeRoot>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
```tsx
|
|
205
|
+
// App.tsx — pass the host color mode (example: mm-react-tools)
|
|
206
|
+
import { useHostTheme } from '@machinemetrics/mm-react-components';
|
|
207
|
+
import { useMMAppParams } from '@machinemetrics/mm-react-tools';
|
|
208
|
+
|
|
209
|
+
useHostTheme(useMMAppParams().colorMode);
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
If you need `useTheme()` elsewhere (e.g. markdown styling), import it from **`@machinemetrics/mm-react-components`** so it uses the same context as `ThemeRoot`—not from the `next-themes` package directly.
|
|
213
|
+
|
|
214
|
+
Optional: pass any `ThemeProvider` prop to `ThemeRoot` to override defaults (e.g. `storageKey` for standalone persistence).
|
|
215
|
+
|
|
189
216
|
#### Option 3: Use Theme Utilities
|
|
190
217
|
|
|
191
218
|
```tsx
|
|
@@ -35,6 +35,13 @@ export interface DatePickerProps {
|
|
|
35
35
|
* Initial month to display when no date is selected (e.g. for stable visual tests).
|
|
36
36
|
*/
|
|
37
37
|
readonly defaultMonth?: Date;
|
|
38
|
+
/**
|
|
39
|
+
* Classes merged onto the trigger button (e.g. compact width for toolbars).
|
|
40
|
+
*/
|
|
41
|
+
readonly triggerClassName?: string;
|
|
42
|
+
/** For form validation (e.g. ticket form field errors). */
|
|
43
|
+
readonly 'aria-invalid'?: boolean;
|
|
44
|
+
readonly 'aria-describedby'?: string;
|
|
38
45
|
}
|
|
39
|
-
export declare function DatePicker({ label, placeholder, value, onValueChange, disabled, className, id, showDropdowns, defaultMonth, }: DatePickerProps): import("react/jsx-runtime").JSX.Element;
|
|
46
|
+
export declare function DatePicker({ label, placeholder, value, onValueChange, disabled, className, id, showDropdowns, defaultMonth, triggerClassName, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, }: DatePickerProps): import("react/jsx-runtime").JSX.Element;
|
|
40
47
|
//# sourceMappingURL=date-picker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../../src/components/ui/date-picker.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../../src/components/ui/date-picker.tsx"],"names":[],"mappings":"AAeA,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;IACtB;;OAEG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,KAAK,IAAI,CAAC;IAC1D;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC;;OAEG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC;IAC7B;;OAEG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,WAA2B,EAC3B,KAAK,EACL,aAAa,EACb,QAAgB,EAChB,SAAS,EACT,EAAE,EACF,aAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,cAAc,EAAE,WAAW,EAC3B,kBAAkB,EAAE,eAAe,GACpC,EAAE,eAAe,2CA4DjB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { KanbanBoardProps } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Kanban board with drag-and-drop. Wrap columns and cards; provide onMove
|
|
5
|
+
* to persist moves between columns. Uses @dnd-kit for drag-and-drop.
|
|
6
|
+
*/
|
|
7
|
+
export declare function KanbanBoard(props: KanbanBoardProps): React.ReactElement;
|
|
8
|
+
//# sourceMappingURL=KanbanBoard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KanbanBoard.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/kanban/KanbanBoard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAcxC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAuEhD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK,CAAC,YAAY,CAMvE"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { KanbanCardProps } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* A sortable card in a column. Registers its content for the default drag overlay.
|
|
5
|
+
* Pass item and children; the card is draggable within and across columns.
|
|
6
|
+
*/
|
|
7
|
+
export declare function KanbanCard({ item, children, }: KanbanCardProps): React.ReactElement;
|
|
8
|
+
//# sourceMappingURL=KanbanCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KanbanCard.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/kanban/KanbanCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAMzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,QAAQ,GACT,EAAE,eAAe,GAAG,KAAK,CAAC,YAAY,CAsCtC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { KanbanCardOverlayProps } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Default drag overlay. Renders card content (from registered preview or children)
|
|
5
|
+
* or falls back to item.title. Use the same styling as KanbanCard for consistency.
|
|
6
|
+
*/
|
|
7
|
+
export declare function KanbanCardOverlay({ item, children, }: KanbanCardOverlayProps): React.ReactElement;
|
|
8
|
+
//# sourceMappingURL=KanbanCardOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KanbanCardOverlay.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/kanban/KanbanCardOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEtD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,QAAQ,GACT,EAAE,sBAAsB,GAAG,KAAK,CAAC,YAAY,CAe7C"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { KanbanColumnProps } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* A single Kanban column: header (SheetBanner) and sortable card list.
|
|
5
|
+
* Border color uses --kanban-column-border (primary when drag-over, border otherwise).
|
|
6
|
+
*/
|
|
7
|
+
export declare function KanbanColumn({ column, children, }: KanbanColumnProps): React.ReactElement;
|
|
8
|
+
//# sourceMappingURL=KanbanColumn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KanbanColumn.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/kanban/KanbanColumn.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AAWzC,OAAO,KAAK,EAAE,iBAAiB,EAAc,MAAM,SAAS,CAAC;AAmB7D;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,QAAQ,GACT,EAAE,iBAAiB,GAAG,KAAK,CAAC,YAAY,CAiExC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React, { type ReactNode } from 'react';
|
|
2
|
+
import type { KanbanItem } from './types';
|
|
3
|
+
type RegisterColumn = (id: string) => void;
|
|
4
|
+
type UnregisterColumn = (id: string) => void;
|
|
5
|
+
type RegisterCard = (id: string, item: KanbanItem, previewContent?: ReactNode) => void;
|
|
6
|
+
type UnregisterCard = (id: string) => void;
|
|
7
|
+
type GetItem = (id: string) => KanbanItem | undefined;
|
|
8
|
+
type GetPreviewContent = (id: string) => ReactNode | undefined;
|
|
9
|
+
type GetColumnIds = () => string[];
|
|
10
|
+
type GetAllItems = () => KanbanItem[];
|
|
11
|
+
interface KanbanContextValue {
|
|
12
|
+
registerColumn: RegisterColumn;
|
|
13
|
+
unregisterColumn: UnregisterColumn;
|
|
14
|
+
registerCard: RegisterCard;
|
|
15
|
+
unregisterCard: UnregisterCard;
|
|
16
|
+
getItem: GetItem;
|
|
17
|
+
getPreviewContent: GetPreviewContent;
|
|
18
|
+
getColumnIds: GetColumnIds;
|
|
19
|
+
getAllItems: GetAllItems;
|
|
20
|
+
}
|
|
21
|
+
/** Provides registration and lookup for columns, cards, and drag preview content. */
|
|
22
|
+
export declare function KanbanContextProvider({ children, }: {
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
}): React.ReactElement;
|
|
25
|
+
/** Hook to access Kanban registration and item/preview lookup. Must be used within KanbanBoard. */
|
|
26
|
+
export declare function useKanbanContext(): KanbanContextValue;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=KanbanContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KanbanContext.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/kanban/KanbanContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAKZ,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,KAAK,cAAc,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;AAC3C,KAAK,gBAAgB,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;AAC7C,KAAK,YAAY,GAAG,CAClB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,UAAU,EAChB,cAAc,CAAC,EAAE,SAAS,KACvB,IAAI,CAAC;AACV,KAAK,cAAc,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;AAC3C,KAAK,OAAO,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;AACtD,KAAK,iBAAiB,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,CAAC;AAC/D,KAAK,YAAY,GAAG,MAAM,MAAM,EAAE,CAAC;AACnC,KAAK,WAAW,GAAG,MAAM,UAAU,EAAE,CAAC;AAEtC,UAAU,kBAAkB;IAC1B,cAAc,EAAE,cAAc,CAAC;IAC/B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,cAAc,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,YAAY,EAAE,YAAY,CAAC;IAC3B,WAAW,EAAE,WAAW,CAAC;CAC1B;AAID,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,KAAK,CAAC,YAAY,CA0DrB;AAED,mGAAmG;AACnG,wBAAgB,gBAAgB,IAAI,kBAAkB,CAMrD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { KanbanItem } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Minimal drag end payload (compatible with DragEndEvent from @dnd-kit/core).
|
|
4
|
+
*/
|
|
5
|
+
export interface DragEndPayload {
|
|
6
|
+
active: {
|
|
7
|
+
id: string | number;
|
|
8
|
+
};
|
|
9
|
+
over: {
|
|
10
|
+
id: string | number;
|
|
11
|
+
} | null;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Result of computing a valid move from a drag end event.
|
|
15
|
+
*/
|
|
16
|
+
export interface KanbanMoveResult {
|
|
17
|
+
itemId: string;
|
|
18
|
+
fromColumnId: string;
|
|
19
|
+
toColumnId: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Computes a move from a drag end event and current items.
|
|
23
|
+
* Returns null if the move is invalid (no over target, item not found, or same column).
|
|
24
|
+
*/
|
|
25
|
+
export declare function computeMoveFromDragEnd(event: DragEndPayload, items: KanbanItem[], columnIds: string[]): KanbanMoveResult | null;
|
|
26
|
+
//# sourceMappingURL=dragEndUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dragEndUtils.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/kanban/dragEndUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAChC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,cAAc,EACrB,KAAK,EAAE,UAAU,EAAE,EACnB,SAAS,EAAE,MAAM,EAAE,GAClB,gBAAgB,GAAG,IAAI,CAqBzB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { KanbanBoard } from './KanbanBoard';
|
|
2
|
+
export { KanbanColumn } from './KanbanColumn';
|
|
3
|
+
export { KanbanCard } from './KanbanCard';
|
|
4
|
+
export { KanbanCardOverlay } from './KanbanCardOverlay';
|
|
5
|
+
export { normalizeToKanbanColumn, dataToKanbanItems } from './types';
|
|
6
|
+
export { computeMoveFromDragEnd } from './dragEndUtils';
|
|
7
|
+
export type { KanbanMoveResult } from './dragEndUtils';
|
|
8
|
+
export type { KanbanBoardProps, KanbanColumnProps, KanbanCardProps, KanbanCardOverlayProps, KanbanColumnDef, KanbanColumnInput, KanbanItem, } from './types';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/kanban/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EACjB,UAAU,GACX,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Column definition for the Kanban board (normalized shape: id + title).
|
|
4
|
+
*/
|
|
5
|
+
export interface KanbanColumnDef {
|
|
6
|
+
id: string;
|
|
7
|
+
title: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Table-compatible column shape. Use the same object as DataTable columns;
|
|
11
|
+
* KanbanColumn normalizes id + header/title internally.
|
|
12
|
+
*/
|
|
13
|
+
export interface KanbanColumnInput {
|
|
14
|
+
id: string;
|
|
15
|
+
title?: string;
|
|
16
|
+
header?: string | ReactNode;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Item (card) definition. Must have id, columnId, and title.
|
|
20
|
+
*/
|
|
21
|
+
export interface KanbanItem {
|
|
22
|
+
id: string;
|
|
23
|
+
columnId: string;
|
|
24
|
+
title: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Normalize a table-column-like object to KanbanColumn.
|
|
28
|
+
* Use when you need an explicit KanbanColumn; KanbanColumn component accepts
|
|
29
|
+
* KanbanColumnInput directly and normalizes internally.
|
|
30
|
+
*/
|
|
31
|
+
export declare function normalizeToKanbanColumn(col: KanbanColumnInput): KanbanColumnDef;
|
|
32
|
+
/**
|
|
33
|
+
* Map table data rows to KanbanItem[] using a column key and optional title key.
|
|
34
|
+
* Use the same data array as your DataTable; one call gives items for the board.
|
|
35
|
+
*/
|
|
36
|
+
export declare function dataToKanbanItems<T>(data: T[], options: {
|
|
37
|
+
columnIdKey: keyof T;
|
|
38
|
+
titleKey?: keyof T;
|
|
39
|
+
}): KanbanItem[];
|
|
40
|
+
export interface KanbanBoardProps {
|
|
41
|
+
children: ReactNode;
|
|
42
|
+
onMove?: (itemId: string, fromColumnId: string, toColumnId: string) => void;
|
|
43
|
+
renderDragPreview?: (item: KanbanItem) => ReactNode;
|
|
44
|
+
}
|
|
45
|
+
export interface KanbanColumnProps {
|
|
46
|
+
column: KanbanColumnDef | KanbanColumnInput;
|
|
47
|
+
children: ReactNode;
|
|
48
|
+
}
|
|
49
|
+
export interface KanbanCardProps {
|
|
50
|
+
item: KanbanItem;
|
|
51
|
+
children: ReactNode;
|
|
52
|
+
}
|
|
53
|
+
/** Props for the default drag overlay. Optional children override the default title-only content. */
|
|
54
|
+
export interface KanbanCardOverlayProps {
|
|
55
|
+
item: KanbanItem;
|
|
56
|
+
children?: ReactNode;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/kanban/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,iBAAiB,GACrB,eAAe,CAQjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,IAAI,EAAE,CAAC,EAAE,EACT,OAAO,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAA;CAAE,GACpD,UAAU,EAAE,CAiBd;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5E,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,SAAS,CAAC;CACrD;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,eAAe,GAAG,iBAAiB,CAAC;IAC5C,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,qGAAqG;AACrG,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sheet-banner.d.ts","sourceRoot":"","sources":["../../../src/components/ui/sheet-banner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,QAAQ,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"sheet-banner.d.ts","sourceRoot":"","sources":["../../../src/components/ui/sheet-banner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAC1C,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,WAAW,yFA6BvB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { TicketDetailsLabels } from './TicketLabels';
|
|
3
|
+
import type { Comment, TicketSystemEvent } from './TicketTypes';
|
|
4
|
+
import type { TicketUserSelectComponent } from './TicketUserSelect';
|
|
5
|
+
export interface TicketActivitySectionProps {
|
|
6
|
+
comments: Comment[];
|
|
7
|
+
systemEvents?: TicketSystemEvent[];
|
|
8
|
+
/** Resets the comment draft when the ticket id changes. */
|
|
9
|
+
ticketId: string | undefined;
|
|
10
|
+
getDisplayName: (uid: string) => string;
|
|
11
|
+
usersLoading: boolean;
|
|
12
|
+
userSelectComponent: TicketUserSelectComponent;
|
|
13
|
+
onPostComment: (payload: {
|
|
14
|
+
authorUserId: string;
|
|
15
|
+
body: string;
|
|
16
|
+
}) => void;
|
|
17
|
+
labels: Required<TicketDetailsLabels>;
|
|
18
|
+
}
|
|
19
|
+
export declare function TicketActivitySection({ comments, systemEvents, ticketId, getDisplayName, usersLoading, userSelectComponent: UserSelect, onPostComment, labels, }: Readonly<TicketActivitySectionProps>): React.ReactElement;
|
|
20
|
+
//# sourceMappingURL=TicketActivitySection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TicketActivitySection.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/tickets/TicketActivitySection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoD,MAAM,OAAO,CAAC;AAMzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AA6DpE,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,YAAY,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACnC,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,YAAY,EAAE,OAAO,CAAC;IACtB,mBAAmB,EAAE,yBAAyB,CAAC;IAC/C,aAAa,EAAE,CAAC,OAAO,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACzE,MAAM,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAC;CACvC;AAED,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,mBAAmB,EAAE,UAAU,EAC/B,aAAa,EACb,MAAM,GACP,EAAE,QAAQ,CAAC,0BAA0B,CAAC,GAAG,KAAK,CAAC,YAAY,CA6J3D"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse `YYYY-MM-DD` as a local calendar date (avoids UTC shift from `Date` string parsing).
|
|
3
|
+
*/
|
|
4
|
+
export declare function parseTicketDateString(iso: string): Date | undefined;
|
|
5
|
+
/** Format a local `Date` as `YYYY-MM-DD` for ticket field storage. */
|
|
6
|
+
export declare function formatTicketDateString(d: Date): string;
|
|
7
|
+
/**
|
|
8
|
+
* Format an ISO date string for display (e.g. "Mar 1, 2024, 2:00 PM").
|
|
9
|
+
*/
|
|
10
|
+
export declare function formatCreationDate(createdAt: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Read-only display for `updatedDate` and similar: `YYYY-MM-DD` (local) or parseable ISO datetimes.
|
|
13
|
+
*/
|
|
14
|
+
export declare function formatTicketTimestampDisplay(raw: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Format relative time from createdAt to now (e.g. "2 days ago").
|
|
17
|
+
* Accepts optional now for tests.
|
|
18
|
+
*/
|
|
19
|
+
export declare function formatRelativeTime(createdAt: string, now?: Date): string;
|
|
20
|
+
//# sourceMappingURL=TicketDates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TicketDates.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/tickets/TicketDates.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAWnE;AAED,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAKtD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAK5D;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYhE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,GAAG,GAAE,IAAiB,GACrB,MAAM,CAaR"}
|