@awesome-markdown/board-ui 0.0.0-stage → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -2
- package/dist/board/Board.d.ts +24 -0
- package/dist/board/Board.d.ts.map +1 -0
- package/dist/board/Board.js +166 -0
- package/dist/board/Board.js.map +1 -0
- package/dist/board/Cell.d.ts +23 -0
- package/dist/board/Cell.d.ts.map +1 -0
- package/dist/board/Cell.js +145 -0
- package/dist/board/Cell.js.map +1 -0
- package/dist/board/ColumnHeader.d.ts +18 -0
- package/dist/board/ColumnHeader.d.ts.map +1 -0
- package/dist/board/ColumnHeader.js +31 -0
- package/dist/board/ColumnHeader.js.map +1 -0
- package/dist/board/HomelessItemCard.d.ts +15 -0
- package/dist/board/HomelessItemCard.d.ts.map +1 -0
- package/dist/board/HomelessItemCard.js +36 -0
- package/dist/board/HomelessItemCard.js.map +1 -0
- package/dist/board/HomelessPanel.d.ts +17 -0
- package/dist/board/HomelessPanel.d.ts.map +1 -0
- package/dist/board/HomelessPanel.js +26 -0
- package/dist/board/HomelessPanel.js.map +1 -0
- package/dist/board/ItemCard.d.ts +21 -0
- package/dist/board/ItemCard.d.ts.map +1 -0
- package/dist/board/ItemCard.js +104 -0
- package/dist/board/ItemCard.js.map +1 -0
- package/dist/board/SwimlaneRow.d.ts +23 -0
- package/dist/board/SwimlaneRow.d.ts.map +1 -0
- package/dist/board/SwimlaneRow.js +30 -0
- package/dist/board/SwimlaneRow.js.map +1 -0
- package/dist/board/dnd/boardDnd.d.ts +15 -0
- package/dist/board/dnd/boardDnd.d.ts.map +1 -0
- package/dist/board/dnd/boardDnd.js +69 -0
- package/dist/board/dnd/boardDnd.js.map +1 -0
- package/dist/board/dnd/dragTypes.d.ts +24 -0
- package/dist/board/dnd/dragTypes.d.ts.map +1 -0
- package/dist/board/dnd/dragTypes.js +22 -0
- package/dist/board/dnd/dragTypes.js.map +1 -0
- package/dist/board/dnd/mutateDragDrop.d.ts +37 -0
- package/dist/board/dnd/mutateDragDrop.d.ts.map +1 -0
- package/dist/board/dnd/mutateDragDrop.js +116 -0
- package/dist/board/dnd/mutateDragDrop.js.map +1 -0
- package/dist/board/dnd/onDragEnd.d.ts +24 -0
- package/dist/board/dnd/onDragEnd.d.ts.map +1 -0
- package/dist/board/dnd/onDragEnd.js +47 -0
- package/dist/board/dnd/onDragEnd.js.map +1 -0
- package/dist/board/layout/AxisBehavior.d.ts +35 -0
- package/dist/board/layout/AxisBehavior.d.ts.map +1 -0
- package/dist/board/layout/AxisBehavior.js +82 -0
- package/dist/board/layout/AxisBehavior.js.map +1 -0
- package/dist/board/layout/AxisDrawer.d.ts +17 -0
- package/dist/board/layout/AxisDrawer.d.ts.map +1 -0
- package/dist/board/layout/AxisDrawer.js +40 -0
- package/dist/board/layout/AxisDrawer.js.map +1 -0
- package/dist/board/layout/BoardDrawer.d.ts +11 -0
- package/dist/board/layout/BoardDrawer.d.ts.map +1 -0
- package/dist/board/layout/BoardDrawer.js +27 -0
- package/dist/board/layout/BoardDrawer.js.map +1 -0
- package/dist/board/layout/Drawer.d.ts +19 -0
- package/dist/board/layout/Drawer.d.ts.map +1 -0
- package/dist/board/layout/Drawer.js +18 -0
- package/dist/board/layout/Drawer.js.map +1 -0
- package/dist/board/layout/FilterEditor.d.ts +12 -0
- package/dist/board/layout/FilterEditor.d.ts.map +1 -0
- package/dist/board/layout/FilterEditor.js +11 -0
- package/dist/board/layout/FilterEditor.js.map +1 -0
- package/dist/board/layout/InlineControls.d.ts +22 -0
- package/dist/board/layout/InlineControls.d.ts.map +1 -0
- package/dist/board/layout/InlineControls.js +39 -0
- package/dist/board/layout/InlineControls.js.map +1 -0
- package/dist/board/layout/SortableAxis.d.ts +28 -0
- package/dist/board/layout/SortableAxis.d.ts.map +1 -0
- package/dist/board/layout/SortableAxis.js +39 -0
- package/dist/board/layout/SortableAxis.js.map +1 -0
- package/dist/board/layout/axis-defaults.d.ts +22 -0
- package/dist/board/layout/axis-defaults.d.ts.map +1 -0
- package/dist/board/layout/axis-defaults.js +37 -0
- package/dist/board/layout/axis-defaults.js.map +1 -0
- package/dist/board/layout/filter-draft.d.ts +21 -0
- package/dist/board/layout/filter-draft.d.ts.map +1 -0
- package/dist/board/layout/filter-draft.js +110 -0
- package/dist/board/layout/filter-draft.js.map +1 -0
- package/dist/board/layout/useBoardLayout.d.ts +27 -0
- package/dist/board/layout/useBoardLayout.d.ts.map +1 -0
- package/dist/board/layout/useBoardLayout.js +92 -0
- package/dist/board/layout/useBoardLayout.js.map +1 -0
- package/dist/breadcrumb.d.ts +22 -0
- package/dist/breadcrumb.d.ts.map +1 -0
- package/dist/breadcrumb.js +15 -0
- package/dist/breadcrumb.js.map +1 -0
- package/dist/components/BoardAssigneeField.d.ts +10 -0
- package/dist/components/BoardAssigneeField.d.ts.map +1 -0
- package/dist/components/BoardAssigneeField.js +37 -0
- package/dist/components/BoardAssigneeField.js.map +1 -0
- package/dist/components/ConflictBanner.d.ts +12 -0
- package/dist/components/ConflictBanner.d.ts.map +1 -0
- package/dist/components/ConflictBanner.js +47 -0
- package/dist/components/ConflictBanner.js.map +1 -0
- package/dist/components/ConflictDiff.d.ts +13 -0
- package/dist/components/ConflictDiff.d.ts.map +1 -0
- package/dist/components/ConflictDiff.js +97 -0
- package/dist/components/ConflictDiff.js.map +1 -0
- package/dist/components/ConflictPanel.d.ts +16 -0
- package/dist/components/ConflictPanel.d.ts.map +1 -0
- package/dist/components/ConflictPanel.js +53 -0
- package/dist/components/ConflictPanel.js.map +1 -0
- package/dist/components/DeleteItemConfirmDialog.d.ts +14 -0
- package/dist/components/DeleteItemConfirmDialog.d.ts.map +1 -0
- package/dist/components/DeleteItemConfirmDialog.js +46 -0
- package/dist/components/DeleteItemConfirmDialog.js.map +1 -0
- package/dist/components/ItemEditorActions.d.ts +15 -0
- package/dist/components/ItemEditorActions.d.ts.map +1 -0
- package/dist/components/ItemEditorActions.js +48 -0
- package/dist/components/ItemEditorActions.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/derive-summary.d.ts +9 -0
- package/dist/lib/derive-summary.d.ts.map +1 -0
- package/dist/lib/derive-summary.js +27 -0
- package/dist/lib/derive-summary.js.map +1 -0
- package/dist/lib/item-board.d.ts +5 -0
- package/dist/lib/item-board.d.ts.map +1 -0
- package/dist/lib/item-board.js +14 -0
- package/dist/lib/item-board.js.map +1 -0
- package/dist/lib/property-display.d.ts +18 -0
- package/dist/lib/property-display.d.ts.map +1 -0
- package/dist/lib/property-display.js +81 -0
- package/dist/lib/property-display.js.map +1 -0
- package/dist/pages/BoardListPage.d.ts +9 -0
- package/dist/pages/BoardListPage.d.ts.map +1 -0
- package/dist/pages/BoardListPage.js +113 -0
- package/dist/pages/BoardListPage.js.map +1 -0
- package/dist/pages/BoardPage.d.ts +7 -0
- package/dist/pages/BoardPage.d.ts.map +1 -0
- package/dist/pages/BoardPage.js +37 -0
- package/dist/pages/BoardPage.js.map +1 -0
- package/dist/pages/ItemEditorPage.d.ts +3 -0
- package/dist/pages/ItemEditorPage.d.ts.map +1 -0
- package/dist/pages/ItemEditorPage.js +255 -0
- package/dist/pages/ItemEditorPage.js.map +1 -0
- package/dist/provider/ProviderContext.d.ts +17 -0
- package/dist/provider/ProviderContext.d.ts.map +1 -0
- package/dist/provider/ProviderContext.js +21 -0
- package/dist/provider/ProviderContext.js.map +1 -0
- package/dist/router/RouterAdapter.d.ts +43 -0
- package/dist/router/RouterAdapter.d.ts.map +1 -0
- package/dist/router/RouterAdapter.js +21 -0
- package/dist/router/RouterAdapter.js.map +1 -0
- package/dist/shell/SyncStatusDot.d.ts +8 -0
- package/dist/shell/SyncStatusDot.d.ts.map +1 -0
- package/dist/shell/SyncStatusDot.js +58 -0
- package/dist/shell/SyncStatusDot.js.map +1 -0
- package/dist/shell/ThemeToggle.d.ts +8 -0
- package/dist/shell/ThemeToggle.d.ts.map +1 -0
- package/dist/shell/ThemeToggle.js +21 -0
- package/dist/shell/ThemeToggle.js.map +1 -0
- package/dist/state/theme-store.d.ts +17 -0
- package/dist/state/theme-store.d.ts.map +1 -0
- package/dist/state/theme-store.js +58 -0
- package/dist/state/theme-store.js.map +1 -0
- package/dist/state/useBoardRender.d.ts +16 -0
- package/dist/state/useBoardRender.d.ts.map +1 -0
- package/dist/state/useBoardRender.js +53 -0
- package/dist/state/useBoardRender.js.map +1 -0
- package/dist/state/useProviderSubscribe.d.ts +22 -0
- package/dist/state/useProviderSubscribe.d.ts.map +1 -0
- package/dist/state/useProviderSubscribe.js +48 -0
- package/dist/state/useProviderSubscribe.js.map +1 -0
- package/dist/sync/conflict-api.d.ts +16 -0
- package/dist/sync/conflict-api.d.ts.map +1 -0
- package/dist/sync/conflict-api.js +35 -0
- package/dist/sync/conflict-api.js.map +1 -0
- package/dist/sync/conflict-store.d.ts +44 -0
- package/dist/sync/conflict-store.d.ts.map +1 -0
- package/dist/sync/conflict-store.js +159 -0
- package/dist/sync/conflict-store.js.map +1 -0
- package/fonts/InterTight-Medium.woff2 +0 -0
- package/fonts/InterTight-Regular.woff2 +0 -0
- package/fonts/JetBrainsMono-Medium.woff2 +0 -0
- package/fonts/JetBrainsMono-Regular.woff2 +0 -0
- package/fonts/LICENSE +14 -0
- package/package.json +58 -3
- package/styles.css +232 -0
package/README.md
CHANGED
|
@@ -1,3 +1,77 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @awesome-markdown/board-ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The awesome-markdown board surface — board list, kanban board with filter-derived
|
|
4
|
+
drag-and-drop, homeless panel, inline layout editing, item editor and sync-engine
|
|
5
|
+
conflict resolution — as a router-agnostic React 19 library.
|
|
6
|
+
|
|
7
|
+
`apps/kanban-ui` is a thin shell around this package; other hosts (for example a
|
|
8
|
+
multi-tenant cloud app) mount the same pages under their own router and provider.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pnpm add @awesome-markdown/board-ui react react-dom
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import '@awesome-markdown/board-ui/styles.css';
|
|
20
|
+
import {
|
|
21
|
+
BoardListPage,
|
|
22
|
+
BoardPage,
|
|
23
|
+
ItemEditorPage,
|
|
24
|
+
ProviderContextProvider,
|
|
25
|
+
RouterAdapterProvider,
|
|
26
|
+
type RouterAdapter,
|
|
27
|
+
} from '@awesome-markdown/board-ui';
|
|
28
|
+
|
|
29
|
+
const adapter: RouterAdapter = {
|
|
30
|
+
Link: ({ to, ...props }) => <MyLink to={`/w/acme${to}`} {...props} />,
|
|
31
|
+
navigate: (to) => router.navigate(`/w/acme${to}`),
|
|
32
|
+
useParams: () => useMyRouterParams(),
|
|
33
|
+
useSearchParams: () => new URLSearchParams(useMyRouterLocation().search),
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
<RouterAdapterProvider adapter={adapter}>
|
|
37
|
+
<ProviderContextProvider provider={persistenceProvider}>
|
|
38
|
+
{/* route `/` → <BoardListPage/>, `/boards/:slug` → <BoardPage/>, `/items/:slug` → <ItemEditorPage/> */}
|
|
39
|
+
</ProviderContextProvider>
|
|
40
|
+
</RouterAdapterProvider>;
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### RouterAdapter
|
|
44
|
+
|
|
45
|
+
board-ui never imports a router. All paths it emits are **board-relative**
|
|
46
|
+
(`/`, `/boards/:slug`, `/items/:slug?board=:boardSlug`); the adapter maps them onto
|
|
47
|
+
the host URL space.
|
|
48
|
+
|
|
49
|
+
| Member | Purpose |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `Link` | Component rendering an in-app link (`to`, `children`, `className`, `style`, `data-testid`, …) |
|
|
52
|
+
| `navigate(to)` | Imperative navigation to a board-relative path |
|
|
53
|
+
| `useParams()` | Hook returning route params; pages read `slug` |
|
|
54
|
+
| `useSearchParams()` | Hook returning the current query string; the item editor reads `board` |
|
|
55
|
+
|
|
56
|
+
`apps/kanban-ui/src/router/react-router-adapter.tsx` is the reference
|
|
57
|
+
implementation for `react-router-dom`.
|
|
58
|
+
|
|
59
|
+
### Optional contexts
|
|
60
|
+
|
|
61
|
+
- `BreadcrumbContext` — pages push `BreadcrumbSegment[]` via `useBreadcrumb()`; provide it
|
|
62
|
+
if your shell renders a breadcrumb. The default is a no-op.
|
|
63
|
+
- `ConflictProvider syncEngineUrl="…"` + `<ConflictBanner/>` — only for hosts backed by
|
|
64
|
+
the git sync-engine.
|
|
65
|
+
|
|
66
|
+
### Shell widgets
|
|
67
|
+
|
|
68
|
+
`SyncStatusDot` (HTTP provider connection state), `ThemeToggle` / `useTheme`
|
|
69
|
+
(light/dark via `data-theme` on `<html>`).
|
|
70
|
+
|
|
71
|
+
## Styles
|
|
72
|
+
|
|
73
|
+
`@awesome-markdown/board-ui/styles.css` contains the design tokens (`--bg`, `--ink`,
|
|
74
|
+
`--ink-muted`, `--border`, `--accent`, `--font-mono`, `--font-sans`; light and
|
|
75
|
+
`[data-theme="dark"]`), the self-hosted JetBrains Mono / Inter Tight fonts (resolved
|
|
76
|
+
relative to the CSS file, so any bundler that handles CSS `url()` picks them up), the
|
|
77
|
+
small utility-class set the components use, and the board-editing classes.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { BoardRender, Homeless } from '@awesome-markdown/contracts';
|
|
3
|
+
interface BoardProps {
|
|
4
|
+
render: BoardRender;
|
|
5
|
+
homeless: Homeless | null;
|
|
6
|
+
onRefetch: () => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Main board component: renders the column×swimlane grid and wires up DnD.
|
|
10
|
+
*
|
|
11
|
+
* Manages optimistic cell state — on drag-drop, applies the move immediately
|
|
12
|
+
* then reverts on PATCH failure with a user-visible error toast.
|
|
13
|
+
*
|
|
14
|
+
* Drop semantics:
|
|
15
|
+
* - Invertibility check + mutation derivation via @awesome-markdown/filter-engine
|
|
16
|
+
* - Read-only cells reject drops before any network call
|
|
17
|
+
* - One drop → exactly one PATCH /items/:slug
|
|
18
|
+
*
|
|
19
|
+
* Layout editing: "+" adds a column/swimlane, headers drag to reorder, the
|
|
20
|
+
* pencil opens the axis (or board) settings drawer.
|
|
21
|
+
*/
|
|
22
|
+
export declare function Board({ render, homeless, onRefetch }: BoardProps): React.ReactElement;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=Board.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Board.d.ts","sourceRoot":"","sources":["../../src/board/Board.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgC,MAAM,OAAO,CAAC;AAgBrD,OAAO,KAAK,EAAE,WAAW,EAAoB,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAe3F,UAAU,UAAU;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAgB,KAAK,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,KAAK,CAAC,YAAY,CA0UrF"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React, { useCallback, useState } from 'react';
|
|
3
|
+
import { DndContext, DragOverlay, PointerSensor, KeyboardSensor, useSensor, useSensors, } from '@dnd-kit/core';
|
|
4
|
+
import { SortableContext, horizontalListSortingStrategy, sortableKeyboardCoordinates, verticalListSortingStrategy, } from '@dnd-kit/sortable';
|
|
5
|
+
import { ColumnHeader } from './ColumnHeader.js';
|
|
6
|
+
import { SwimlaneRow } from './SwimlaneRow.js';
|
|
7
|
+
import { HomelessPanel } from './HomelessPanel.js';
|
|
8
|
+
import { onDragEnd } from './dnd/onDragEnd.js';
|
|
9
|
+
import { computeDropMutations, applyOptimisticMove } from './dnd/mutateDragDrop.js';
|
|
10
|
+
import { layoutAwareCollision, planHomelessDrop } from './dnd/boardDnd.js';
|
|
11
|
+
import { useProvider } from '../provider/ProviderContext.js';
|
|
12
|
+
import { useBoardLayout } from './layout/useBoardLayout.js';
|
|
13
|
+
import { axisDragId } from './layout/axis-defaults.js';
|
|
14
|
+
import { AddAxisButton, PencilIcon } from './layout/InlineControls.js';
|
|
15
|
+
import { AxisDrawer } from './layout/AxisDrawer.js';
|
|
16
|
+
import { BoardDrawer } from './layout/BoardDrawer.js';
|
|
17
|
+
/**
|
|
18
|
+
* Main board component: renders the column×swimlane grid and wires up DnD.
|
|
19
|
+
*
|
|
20
|
+
* Manages optimistic cell state — on drag-drop, applies the move immediately
|
|
21
|
+
* then reverts on PATCH failure with a user-visible error toast.
|
|
22
|
+
*
|
|
23
|
+
* Drop semantics:
|
|
24
|
+
* - Invertibility check + mutation derivation via @awesome-markdown/filter-engine
|
|
25
|
+
* - Read-only cells reject drops before any network call
|
|
26
|
+
* - One drop → exactly one PATCH /items/:slug
|
|
27
|
+
*
|
|
28
|
+
* Layout editing: "+" adds a column/swimlane, headers drag to reorder, the
|
|
29
|
+
* pencil opens the axis (or board) settings drawer.
|
|
30
|
+
*/
|
|
31
|
+
export function Board({ render, homeless, onRefetch }) {
|
|
32
|
+
const provider = useProvider();
|
|
33
|
+
const [activeItemSlug, setActiveItemSlug] = useState(null);
|
|
34
|
+
const [optimisticCells, setOptimisticCells] = useState(null);
|
|
35
|
+
const [error, setError] = useState(null);
|
|
36
|
+
const [editing, setEditing] = useState(null);
|
|
37
|
+
const layout = useBoardLayout(render, onRefetch, setError);
|
|
38
|
+
const closeDrawer = useCallback(() => setEditing(null), []);
|
|
39
|
+
const cells = optimisticCells ?? render.cells;
|
|
40
|
+
const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 4 } }), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }));
|
|
41
|
+
const handleDragStart = useCallback((event) => {
|
|
42
|
+
setActiveItemSlug(String(event.active.id));
|
|
43
|
+
}, []);
|
|
44
|
+
const handleDragCancel = useCallback(() => {
|
|
45
|
+
setActiveItemSlug(null);
|
|
46
|
+
}, []);
|
|
47
|
+
const handleDragEnd = useCallback((event) => {
|
|
48
|
+
setActiveItemSlug(null);
|
|
49
|
+
// --- Axis header reorder branch ---
|
|
50
|
+
const activeData = event.active.data.current;
|
|
51
|
+
if (activeData?.type === 'axis') {
|
|
52
|
+
const { dim, slug } = activeData;
|
|
53
|
+
const over = event.over?.data.current;
|
|
54
|
+
if (over?.type === 'axis' && over.dim === dim)
|
|
55
|
+
void layout.moveAxis(dim, slug, over.slug);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// --- Homeless item drop branch ---
|
|
59
|
+
if (activeData?.type === 'homeless-item') {
|
|
60
|
+
if (!homeless)
|
|
61
|
+
return;
|
|
62
|
+
const plan = planHomelessDrop(event, cells, render, homeless);
|
|
63
|
+
if (!plan)
|
|
64
|
+
return;
|
|
65
|
+
setOptimisticCells(plan.newCells);
|
|
66
|
+
void (async () => {
|
|
67
|
+
try {
|
|
68
|
+
await provider.patchItem(plan.itemSlug, { mutations: plan.mutations });
|
|
69
|
+
setOptimisticCells(null);
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
setOptimisticCells(null);
|
|
73
|
+
setError(`Failed to move item: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
74
|
+
}
|
|
75
|
+
})();
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// --- Regular cell-to-cell drop branch ---
|
|
79
|
+
const action = onDragEnd(event, cells);
|
|
80
|
+
if (action.type === 'noop')
|
|
81
|
+
return;
|
|
82
|
+
const { itemSlug, srcColumnSlug, srcSwimlaneSlug, dstColumnSlug, dstSwimlaneSlug, insertBeforeSlug, } = action;
|
|
83
|
+
const srcCell = cells.find((c) => c.columnSlug === srcColumnSlug && c.swimlaneSlug === srcSwimlaneSlug);
|
|
84
|
+
const dstCell = cells.find((c) => c.columnSlug === dstColumnSlug && c.swimlaneSlug === dstSwimlaneSlug);
|
|
85
|
+
if (!srcCell || !dstCell)
|
|
86
|
+
return;
|
|
87
|
+
// Reject read-only destination before any UI change
|
|
88
|
+
if (dstCell.readOnly)
|
|
89
|
+
return;
|
|
90
|
+
const colAxis = render.axes.columns.find((a) => a.slug === dstColumnSlug);
|
|
91
|
+
const slAxis = render.axes.swimlanes.find((a) => a.slug === dstSwimlaneSlug);
|
|
92
|
+
if (!colAxis || !slAxis)
|
|
93
|
+
return;
|
|
94
|
+
const dropResult = computeDropMutations({
|
|
95
|
+
itemSlug,
|
|
96
|
+
srcCell,
|
|
97
|
+
dstCell,
|
|
98
|
+
colAxis,
|
|
99
|
+
slAxis,
|
|
100
|
+
board: render.board,
|
|
101
|
+
insertBeforeSlug,
|
|
102
|
+
});
|
|
103
|
+
if (!dropResult)
|
|
104
|
+
return; // readonly guard
|
|
105
|
+
// Optimistic update — apply before the network call
|
|
106
|
+
const movingItem = srcCell.items.find((i) => i.slug === itemSlug);
|
|
107
|
+
if (!movingItem)
|
|
108
|
+
return;
|
|
109
|
+
const newCells = applyOptimisticMove(cells, movingItem, srcColumnSlug, srcSwimlaneSlug, dstColumnSlug, dstSwimlaneSlug, insertBeforeSlug);
|
|
110
|
+
setOptimisticCells(newCells);
|
|
111
|
+
void (async () => {
|
|
112
|
+
try {
|
|
113
|
+
await provider.patchItem(itemSlug, { mutations: dropResult.mutations });
|
|
114
|
+
// Clear optimistic state; SSE will deliver the definitive render
|
|
115
|
+
setOptimisticCells(null);
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
setOptimisticCells(null);
|
|
119
|
+
setError(`Failed to move item: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
120
|
+
}
|
|
121
|
+
})();
|
|
122
|
+
}, [cells, render, provider, homeless, layout]);
|
|
123
|
+
const activeItem = activeItemSlug !== null
|
|
124
|
+
? (cells.flatMap((c) => c.items).find((i) => i.slug === activeItemSlug) ??
|
|
125
|
+
homeless?.items.find((i) => i.slug === activeItemSlug) ??
|
|
126
|
+
null)
|
|
127
|
+
: null;
|
|
128
|
+
const visibleHomelessItems = homeless
|
|
129
|
+
? homeless.items.filter((i) => !optimisticCells ||
|
|
130
|
+
!optimisticCells.some((c) => c.items.some((it) => it.slug === i.slug)))
|
|
131
|
+
: [];
|
|
132
|
+
const isEditing = (dim, slug) => editing?.kind === 'axis' && editing.dim === dim && editing.slug === slug;
|
|
133
|
+
const toggleAxis = (dim, slug) => setEditing(isEditing(dim, slug) ? null : { kind: 'axis', dim, slug });
|
|
134
|
+
const editingAxis = editing?.kind === 'axis' ? layout[editing.dim].find((a) => a.slug === editing.slug) : undefined;
|
|
135
|
+
return (_jsxs("div", { className: "flex flex-col h-full", "data-testid": "board", "data-board-slug": render.board.slug, children: [_jsxs("div", { className: "px-4 py-3", style: { borderBottom: '1px solid var(--border)', background: 'var(--bg)' }, children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("h1", { style: { fontFamily: 'var(--font-mono)', fontSize: '1.125rem', fontWeight: 500, color: 'var(--ink)', margin: 0 }, "data-testid": "board-title", children: render.board.title }), _jsx("button", { type: "button", className: "icon-btn", "aria-pressed": editing?.kind === 'board', "aria-label": "Board settings", title: "Board settings", "data-testid": "edit-board", onClick: () => setEditing(editing?.kind === 'board' ? null : { kind: 'board' }), children: _jsx(PencilIcon, {}) })] }), render.board.description !== undefined && (_jsx("p", { style: { fontSize: '0.875rem', color: 'var(--ink-muted)', marginTop: '2px' }, children: render.board.description }))] }), error !== null && (_jsxs("div", { className: "flex items-center justify-between px-4 py-2 flex-shrink-0", style: {
|
|
136
|
+
borderBottom: '1px solid var(--border)',
|
|
137
|
+
fontFamily: 'var(--font-mono)',
|
|
138
|
+
fontSize: '12px',
|
|
139
|
+
color: 'var(--ink)',
|
|
140
|
+
background: 'var(--bg)',
|
|
141
|
+
}, "data-testid": "board-error-toast", role: "alert", children: [_jsx("span", { children: error }), _jsx("button", { type: "button", onClick: () => setError(null), style: {
|
|
142
|
+
marginLeft: '1rem',
|
|
143
|
+
color: 'var(--ink-muted)',
|
|
144
|
+
background: 'none',
|
|
145
|
+
border: 'none',
|
|
146
|
+
cursor: 'pointer',
|
|
147
|
+
fontFamily: 'var(--font-mono)',
|
|
148
|
+
fontSize: '12px',
|
|
149
|
+
}, "aria-label": "Dismiss error", children: "\u2715" })] })), _jsxs(DndContext, { sensors: sensors, collisionDetection: layoutAwareCollision, onDragStart: handleDragStart, onDragEnd: handleDragEnd, onDragCancel: handleDragCancel, children: [_jsxs("div", { className: "flex-1 overflow-auto", children: [_jsxs("div", { className: "flex sticky top-0 z-10", style: { background: 'var(--bg)', borderBottom: '1px solid var(--border)' }, children: [_jsx("div", { className: "w-28 flex-shrink-0" }), _jsx(SortableContext, { items: layout.columns.map((c) => axisDragId('columns', c.slug)), strategy: horizontalListSortingStrategy, children: layout.columns.map((col) => {
|
|
150
|
+
const count = cells
|
|
151
|
+
.filter((c) => c.columnSlug === col.slug)
|
|
152
|
+
.reduce((sum, c) => sum + c.items.length, 0);
|
|
153
|
+
return (_jsx(ColumnHeader, { column: col, itemCount: count, editable: !layout.implicit.columns, selected: isEditing('columns', col.slug), onEdit: () => toggleAxis('columns', col.slug), onRename: (title) => void layout.saveAxis(col.slug, { title }) }, col.slug));
|
|
154
|
+
}) }), _jsx(AddAxisButton, { label: "column", style: { width: '36px', minWidth: '36px', margin: '4px 8px', alignSelf: 'stretch' }, onAdd: (title) => void layout.addAxis('columns', title) })] }), _jsxs("div", { className: "flex flex-col", "data-testid": "swimlane-rows", children: [_jsx(SortableContext, { items: layout.swimlanes.map((s) => axisDragId('swimlanes', s.slug)), strategy: verticalListSortingStrategy, children: layout.swimlanes.map((sl) => (_jsx(SwimlaneRow, { swimlane: sl, columns: layout.columns, cells: cells, board: render.board, editable: !layout.implicit.swimlanes, selected: isEditing('swimlanes', sl.slug), onEdit: () => toggleAxis('swimlanes', sl.slug), onRename: (title) => void layout.saveAxis(sl.slug, { title }), onError: setError, onCreated: onRefetch }, sl.slug))) }), _jsx(AddAxisButton, { label: "swimlane", style: { width: '112px', height: '32px', margin: '8px 0' }, onAdd: (title) => void layout.addAxis('swimlanes', title) })] })] }), homeless !== null && visibleHomelessItems.length > 0 && (_jsx(HomelessPanel, { homeless: homeless, items: visibleHomelessItems })), _jsx(DragOverlay, { children: activeItem !== null && (_jsx("div", { style: {
|
|
155
|
+
background: 'var(--bg)',
|
|
156
|
+
border: '1px solid var(--border)',
|
|
157
|
+
padding: '10px 12px',
|
|
158
|
+
fontSize: '14px',
|
|
159
|
+
fontWeight: 500,
|
|
160
|
+
color: 'var(--ink)',
|
|
161
|
+
fontFamily: 'var(--font-sans)',
|
|
162
|
+
opacity: 0.9,
|
|
163
|
+
boxShadow: 'none',
|
|
164
|
+
}, children: activeItem.title })) })] }), editing?.kind === 'axis' && editingAxis && (_jsx(AxisDrawer, { axis: editingAxis, dim: editing.dim, boardSlug: render.board.slug, usage: layout.usage(editing.slug), onSave: (patch) => layout.saveAxis(editing.slug, patch), onRemove: () => layout.removeAxis(editing.dim, editing.slug), onClose: closeDrawer }, `${editing.dim}:${editing.slug}`)), editing?.kind === 'board' && (_jsx(BoardDrawer, { board: render.board, onSave: layout.saveBoard, onClose: closeDrawer }))] }));
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=Board.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Board.js","sourceRoot":"","sources":["../../src/board/Board.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Cell as CellData, Axis, Board } from '@awesome-markdown/contracts';
|
|
3
|
+
interface CellProps {
|
|
4
|
+
cell: CellData;
|
|
5
|
+
columnAxis: Axis;
|
|
6
|
+
swimlaneAxis: Axis;
|
|
7
|
+
board: Board;
|
|
8
|
+
onError: (msg: string) => void;
|
|
9
|
+
/** Called after a successful item creation so the board can refetch. */
|
|
10
|
+
onCreated: () => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A droppable column×swimlane cell containing sortable ItemCards.
|
|
14
|
+
*
|
|
15
|
+
* Read-only cells (cell.readOnly) suppress the drag-over highlight,
|
|
16
|
+
* show a tooltip explaining why, and hide the "+ Add" affordance.
|
|
17
|
+
*
|
|
18
|
+
* "+ Add" derives mutations from the cell's combined filter via
|
|
19
|
+
* filter-engine and sends POST /items (createItem).
|
|
20
|
+
*/
|
|
21
|
+
export declare function Cell({ cell, columnAxis, swimlaneAxis, board, onError, onCreated, }: CellProps): React.ReactElement;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=Cell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Cell.d.ts","sourceRoot":"","sources":["../../src/board/Cell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAGhD,OAAO,KAAK,EAAE,IAAI,IAAI,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAOjF,UAAU,SAAS;IACjB,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,IAAI,CAAC;IACjB,YAAY,EAAE,IAAI,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,wEAAwE;IACxE,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAYD;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,EACnB,IAAI,EACJ,UAAU,EACV,YAAY,EACZ,KAAK,EACL,OAAO,EACP,SAAS,GACV,EAAE,SAAS,GAAG,KAAK,CAAC,YAAY,CA0MhC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import React, { useState, useRef } from 'react';
|
|
3
|
+
import { useDroppable } from '@dnd-kit/core';
|
|
4
|
+
import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable';
|
|
5
|
+
import { deriveMutations, analyzeInvertibility } from '@awesome-markdown/filter-engine';
|
|
6
|
+
import { ItemCard } from './ItemCard.js';
|
|
7
|
+
import { encodeCellId } from './dnd/dragTypes.js';
|
|
8
|
+
import { buildCellFilter } from './dnd/mutateDragDrop.js';
|
|
9
|
+
import { useProvider } from '../provider/ProviderContext.js';
|
|
10
|
+
/** Slugify a title string to a valid slug. */
|
|
11
|
+
function slugify(title) {
|
|
12
|
+
const s = title
|
|
13
|
+
.toLowerCase()
|
|
14
|
+
.trim()
|
|
15
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
16
|
+
.replace(/^-|-$/g, '');
|
|
17
|
+
return s.length > 0 ? s : 'item';
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A droppable column×swimlane cell containing sortable ItemCards.
|
|
21
|
+
*
|
|
22
|
+
* Read-only cells (cell.readOnly) suppress the drag-over highlight,
|
|
23
|
+
* show a tooltip explaining why, and hide the "+ Add" affordance.
|
|
24
|
+
*
|
|
25
|
+
* "+ Add" derives mutations from the cell's combined filter via
|
|
26
|
+
* filter-engine and sends POST /items (createItem).
|
|
27
|
+
*/
|
|
28
|
+
export function Cell({ cell, columnAxis, swimlaneAxis, board, onError, onCreated, }) {
|
|
29
|
+
const provider = useProvider();
|
|
30
|
+
const [creating, setCreating] = useState(false);
|
|
31
|
+
const [newTitle, setNewTitle] = useState('');
|
|
32
|
+
const [saving, setSaving] = useState(false);
|
|
33
|
+
const inputRef = useRef(null);
|
|
34
|
+
const cellId = encodeCellId(columnAxis.slug, swimlaneAxis.slug);
|
|
35
|
+
const { setNodeRef, isOver } = useDroppable({
|
|
36
|
+
id: cellId,
|
|
37
|
+
disabled: cell.readOnly,
|
|
38
|
+
});
|
|
39
|
+
const itemIds = cell.items.map((i) => i.slug);
|
|
40
|
+
// Compute read-only tooltip from invertibility reasons
|
|
41
|
+
const readOnlyTooltip = React.useMemo(() => {
|
|
42
|
+
if (!cell.readOnly)
|
|
43
|
+
return '';
|
|
44
|
+
const filter = buildCellFilter(board, columnAxis, swimlaneAxis);
|
|
45
|
+
const override = columnAxis.writeOnDrop ?? swimlaneAxis.writeOnDrop;
|
|
46
|
+
if (override !== undefined && !Array.isArray(override)) {
|
|
47
|
+
return 'This cell is marked read-only.';
|
|
48
|
+
}
|
|
49
|
+
const { reasons } = analyzeInvertibility(filter);
|
|
50
|
+
return reasons.length > 0 ? reasons.join('; ') : 'This cell is read-only.';
|
|
51
|
+
}, [cell.readOnly, board, columnAxis, swimlaneAxis]);
|
|
52
|
+
const handleAddClick = () => {
|
|
53
|
+
setCreating(true);
|
|
54
|
+
setNewTitle('');
|
|
55
|
+
setTimeout(() => inputRef.current?.focus(), 0);
|
|
56
|
+
};
|
|
57
|
+
const handleCreate = async () => {
|
|
58
|
+
const title = newTitle.trim();
|
|
59
|
+
if (!title) {
|
|
60
|
+
setCreating(false);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const filter = buildCellFilter(board, columnAxis, swimlaneAxis);
|
|
64
|
+
const writeOnDrop = columnAxis.writeOnDrop ?? swimlaneAxis.writeOnDrop;
|
|
65
|
+
const result = deriveMutations(filter, { board: board.slug }, writeOnDrop);
|
|
66
|
+
if (!Array.isArray(result)) {
|
|
67
|
+
onError('Cannot create item: cell is read-only.');
|
|
68
|
+
setCreating(false);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
setSaving(true);
|
|
72
|
+
try {
|
|
73
|
+
await provider.createItem({ slug: slugify(title), title, mutations: result });
|
|
74
|
+
setCreating(false);
|
|
75
|
+
setNewTitle('');
|
|
76
|
+
onCreated();
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
onError(`Failed to create item: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
setSaving(false);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const handleKeyDown = (e) => {
|
|
86
|
+
if (e.key === 'Enter') {
|
|
87
|
+
void handleCreate();
|
|
88
|
+
}
|
|
89
|
+
else if (e.key === 'Escape') {
|
|
90
|
+
setCreating(false);
|
|
91
|
+
setNewTitle('');
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const dropHighlight = isOver && !cell.readOnly;
|
|
95
|
+
return (_jsxs("div", { ref: setNodeRef, className: "min-w-[240px] w-[240px] flex-shrink-0 min-h-[120px] p-2 flex flex-col gap-1", style: {
|
|
96
|
+
border: dropHighlight
|
|
97
|
+
? '1.5px solid var(--accent)'
|
|
98
|
+
: cell.readOnly
|
|
99
|
+
? '1px dashed var(--ink-muted)'
|
|
100
|
+
: '1px solid var(--border)',
|
|
101
|
+
background: 'transparent',
|
|
102
|
+
cursor: cell.readOnly ? 'not-allowed' : 'default',
|
|
103
|
+
borderRadius: 0,
|
|
104
|
+
}, "data-testid": `cell-${columnAxis.slug}-${swimlaneAxis.slug}`, "data-column-slug": columnAxis.slug, "data-swimlane-slug": swimlaneAxis.slug, "data-readonly": cell.readOnly ? 'true' : undefined, title: cell.readOnly ? readOnlyTooltip : undefined, children: [_jsx(SortableContext, { items: itemIds, strategy: verticalListSortingStrategy, children: cell.items.map((item) => (_jsx(ItemCard, { item: item, columnSlug: columnAxis.slug, swimlaneSlug: swimlaneAxis.slug, boardSlug: board.slug, board: board }, item.slug))) }), !cell.readOnly && (_jsxs(_Fragment, { children: [!creating && (_jsx("button", { type: "button", onClick: handleAddClick, style: {
|
|
105
|
+
marginTop: '4px',
|
|
106
|
+
fontFamily: 'var(--font-mono)',
|
|
107
|
+
fontSize: '11px',
|
|
108
|
+
color: 'var(--ink-muted)',
|
|
109
|
+
background: 'none',
|
|
110
|
+
border: 'none',
|
|
111
|
+
padding: '4px 8px',
|
|
112
|
+
cursor: 'pointer',
|
|
113
|
+
textAlign: 'left',
|
|
114
|
+
}, "data-testid": `add-item-${columnAxis.slug}-${swimlaneAxis.slug}`, children: "+ add item" })), creating && (_jsxs("div", { className: "mt-1 flex flex-col gap-1", children: [_jsx("input", { ref: inputRef, type: "text", value: newTitle, onChange: (e) => setNewTitle(e.target.value), onKeyDown: handleKeyDown, placeholder: "Item title\u2026", disabled: saving, style: {
|
|
115
|
+
fontFamily: 'var(--font-sans)',
|
|
116
|
+
fontSize: '12px',
|
|
117
|
+
border: '1px solid var(--border)',
|
|
118
|
+
borderRadius: 0,
|
|
119
|
+
padding: '4px 8px',
|
|
120
|
+
width: '100%',
|
|
121
|
+
background: 'var(--bg)',
|
|
122
|
+
color: 'var(--ink)',
|
|
123
|
+
outline: 'none',
|
|
124
|
+
}, onFocus: (e) => { e.currentTarget.style.boxShadow = '0 0 0 2px var(--accent)'; }, onBlur: (e) => { e.currentTarget.style.boxShadow = 'none'; }, "data-testid": `new-item-input-${columnAxis.slug}-${swimlaneAxis.slug}` }), _jsxs("div", { className: "flex gap-1", children: [_jsx("button", { type: "button", onClick: () => void handleCreate(), disabled: saving || !newTitle.trim(), style: {
|
|
125
|
+
fontFamily: 'var(--font-mono)',
|
|
126
|
+
fontSize: '11px',
|
|
127
|
+
background: 'var(--accent)',
|
|
128
|
+
color: 'var(--on-accent)',
|
|
129
|
+
border: 'none',
|
|
130
|
+
borderRadius: 0,
|
|
131
|
+
padding: '2px 8px',
|
|
132
|
+
cursor: saving || !newTitle.trim() ? 'not-allowed' : 'pointer',
|
|
133
|
+
opacity: saving || !newTitle.trim() ? 0.5 : 1,
|
|
134
|
+
}, "data-testid": `confirm-add-${columnAxis.slug}-${swimlaneAxis.slug}`, children: saving ? '…' : 'add' }), _jsx("button", { type: "button", onClick: () => { setCreating(false); setNewTitle(''); }, disabled: saving, style: {
|
|
135
|
+
fontFamily: 'var(--font-mono)',
|
|
136
|
+
fontSize: '11px',
|
|
137
|
+
color: 'var(--ink-muted)',
|
|
138
|
+
background: 'none',
|
|
139
|
+
border: 'none',
|
|
140
|
+
borderRadius: 0,
|
|
141
|
+
padding: '2px 8px',
|
|
142
|
+
cursor: saving ? 'not-allowed' : 'pointer',
|
|
143
|
+
}, "data-testid": `cancel-add-${columnAxis.slug}-${swimlaneAxis.slug}`, children: "cancel" })] })] }))] }))] }));
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=Cell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Cell.js","sourceRoot":"","sources":["../../src/board/Cell.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAEjF,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAY7D,8CAA8C;AAC9C,SAAS,OAAO,CAAC,KAAa;IAC5B,MAAM,CAAC,GAAG,KAAK;SACZ,WAAW,EAAE;SACb,IAAI,EAAE;SACN,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACzB,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACnC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,IAAI,CAAC,EACnB,IAAI,EACJ,UAAU,EACV,YAAY,EACZ,KAAK,EACL,OAAO,EACP,SAAS,GACC;IACV,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC7C,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IAEhD,MAAM,MAAM,GAAG,YAAY,CAAC,UAAU,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IAChE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC;QAC1C,EAAE,EAAE,MAAM;QACV,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAE9C,uDAAuD;IACvD,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE;QACjD,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;QAChE,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,IAAI,YAAY,CAAC,WAAW,CAAC;QACpE,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvD,OAAO,gCAAgC,CAAC;QAC1C,CAAC;QACD,MAAM,EAAE,OAAO,EAAE,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;QACjD,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,yBAAyB,CAAC;IAC7E,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;IAErD,MAAM,cAAc,GAAG,GAAS,EAAE;QAChC,WAAW,CAAC,IAAI,CAAC,CAAC;QAClB,WAAW,CAAC,EAAE,CAAC,CAAC;QAChB,UAAU,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,KAAK,IAAmB,EAAE;QAC7C,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,WAAW,CAAC,KAAK,CAAC,CAAC;YACnB,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;QAChE,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,IAAI,YAAY,CAAC,WAAW,CAAC;QACvE,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,WAAW,CAAC,CAAC;QAE3E,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,wCAAwC,CAAC,CAAC;YAClD,WAAW,CAAC,KAAK,CAAC,CAAC;YACnB,OAAO;QACT,CAAC;QAED,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9E,WAAW,CAAC,KAAK,CAAC,CAAC;YACnB,WAAW,CAAC,EAAE,CAAC,CAAC;YAChB,SAAS,EAAE,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CACL,0BAA0B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CACjF,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,SAAS,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,CAAsB,EAAQ,EAAE;QACrD,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YACtB,KAAK,YAAY,EAAE,CAAC;QACtB,CAAC;aAAM,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC9B,WAAW,CAAC,KAAK,CAAC,CAAC;YACnB,WAAW,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;IAE/C,OAAO,CACL,eACE,GAAG,EAAE,UAAU,EACf,SAAS,EAAC,6EAA6E,EACvF,KAAK,EAAE;YACL,MAAM,EAAE,aAAa;gBACnB,CAAC,CAAC,2BAA2B;gBAC7B,CAAC,CAAC,IAAI,CAAC,QAAQ;oBACb,CAAC,CAAC,6BAA6B;oBAC/B,CAAC,CAAC,yBAAyB;YAC/B,UAAU,EAAE,aAAa;YACzB,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;YACjD,YAAY,EAAE,CAAC;SAChB,iBACY,QAAQ,UAAU,CAAC,IAAI,IAAI,YAAY,CAAC,IAAI,EAAE,sBACzC,UAAU,CAAC,IAAI,wBACb,YAAY,CAAC,IAAI,mBACtB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EACjD,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS,aAElD,KAAC,eAAe,IAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,2BAA2B,YACnE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACxB,KAAC,QAAQ,IAEP,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,UAAU,CAAC,IAAI,EAC3B,YAAY,EAAE,YAAY,CAAC,IAAI,EAC/B,SAAS,EAAE,KAAK,CAAC,IAAI,EACrB,KAAK,EAAE,KAAK,IALP,IAAI,CAAC,IAAI,CAMd,CACH,CAAC,GACc,EAEjB,CAAC,IAAI,CAAC,QAAQ,IAAI,CACjB,8BACG,CAAC,QAAQ,IAAI,CACZ,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE;4BACL,SAAS,EAAE,KAAK;4BAChB,UAAU,EAAE,kBAAkB;4BAC9B,QAAQ,EAAE,MAAM;4BAChB,KAAK,EAAE,kBAAkB;4BACzB,UAAU,EAAE,MAAM;4BAClB,MAAM,EAAE,MAAM;4BACd,OAAO,EAAE,SAAS;4BAClB,MAAM,EAAE,SAAS;4BACjB,SAAS,EAAE,MAAM;yBAClB,iBACY,YAAY,UAAU,CAAC,IAAI,IAAI,YAAY,CAAC,IAAI,EAAE,2BAGxD,CACV,EAEA,QAAQ,IAAI,CACX,eAAK,SAAS,EAAC,0BAA0B,aACvC,gBACE,GAAG,EAAE,QAAQ,EACb,IAAI,EAAC,MAAM,EACX,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC5C,SAAS,EAAE,aAAa,EACxB,WAAW,EAAC,kBAAa,EACzB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE;oCACL,UAAU,EAAE,kBAAkB;oCAC9B,QAAQ,EAAE,MAAM;oCAChB,MAAM,EAAE,yBAAyB;oCACjC,YAAY,EAAE,CAAC;oCACf,OAAO,EAAE,SAAS;oCAClB,KAAK,EAAE,MAAM;oCACb,UAAU,EAAE,WAAW;oCACvB,KAAK,EAAE,YAAY;oCACnB,OAAO,EAAE,MAAM;iCAChB,EACD,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,GAAG,yBAAyB,CAAC,CAAC,CAAC,EAChF,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,iBAC/C,kBAAkB,UAAU,CAAC,IAAI,IAAI,YAAY,CAAC,IAAI,EAAE,GACrE,EACF,eAAK,SAAS,EAAC,YAAY,aACzB,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,YAAY,EAAE,EAClC,QAAQ,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EACpC,KAAK,EAAE;4CACL,UAAU,EAAE,kBAAkB;4CAC9B,QAAQ,EAAE,MAAM;4CAChB,UAAU,EAAE,eAAe;4CAC3B,KAAK,EAAE,kBAAkB;4CACzB,MAAM,EAAE,MAAM;4CACd,YAAY,EAAE,CAAC;4CACf,OAAO,EAAE,SAAS;4CAClB,MAAM,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;4CAC9D,OAAO,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;yCAC9C,iBACY,eAAe,UAAU,CAAC,IAAI,IAAI,YAAY,CAAC,IAAI,EAAE,YAEjE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GACd,EACT,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EACvD,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE;4CACL,UAAU,EAAE,kBAAkB;4CAC9B,QAAQ,EAAE,MAAM;4CAChB,KAAK,EAAE,kBAAkB;4CACzB,UAAU,EAAE,MAAM;4CAClB,MAAM,EAAE,MAAM;4CACd,YAAY,EAAE,CAAC;4CACf,OAAO,EAAE,SAAS;4CAClB,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;yCAC3C,iBACY,cAAc,UAAU,CAAC,IAAI,IAAI,YAAY,CAAC,IAAI,EAAE,uBAG1D,IACL,IACF,CACP,IACA,CACJ,IACG,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Axis } from '@awesome-markdown/contracts';
|
|
3
|
+
interface ColumnHeaderProps {
|
|
4
|
+
column: Axis;
|
|
5
|
+
itemCount: number;
|
|
6
|
+
editable: boolean;
|
|
7
|
+
selected: boolean;
|
|
8
|
+
onEdit: () => void;
|
|
9
|
+
onRename: (title: string) => void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Renders the header cell for a single column axis.
|
|
13
|
+
* Format: "TODO · 3" — uppercase mono, hairline rule below. Editable columns
|
|
14
|
+
* are drag handles (reorder), rename on double-click and open settings via the pencil.
|
|
15
|
+
*/
|
|
16
|
+
export declare function ColumnHeader({ column, itemCount, editable, selected, onEdit, onRename, }: ColumnHeaderProps): React.ReactElement;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=ColumnHeader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColumnHeader.d.ts","sourceRoot":"","sources":["../../src/board/ColumnHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAIxD,UAAU,iBAAiB;IACzB,MAAM,EAAE,IAAI,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAQD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,QAAQ,GACT,EAAE,iBAAiB,GAAG,KAAK,CAAC,YAAY,CA2CxC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { SortableAxis } from './layout/SortableAxis.js';
|
|
4
|
+
import { filterSummary } from './layout/filter-draft.js';
|
|
5
|
+
function orderLabel(column) {
|
|
6
|
+
if (!column.order)
|
|
7
|
+
return 'recently updated';
|
|
8
|
+
if (column.order.by === 'boards.$board.order')
|
|
9
|
+
return 'manual';
|
|
10
|
+
return `by ${column.order.by} ${column.order.direction === 'desc' ? '↓' : '↑'}`;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Renders the header cell for a single column axis.
|
|
14
|
+
* Format: "TODO · 3" — uppercase mono, hairline rule below. Editable columns
|
|
15
|
+
* are drag handles (reorder), rename on double-click and open settings via the pencil.
|
|
16
|
+
*/
|
|
17
|
+
export function ColumnHeader({ column, itemCount, editable, selected, onEdit, onRename, }) {
|
|
18
|
+
return (_jsx(SortableAxis, { dim: "columns", axis: column, editable: editable, selected: selected, label: `${column.title} · ${itemCount}`, subtitle: editable ? `${filterSummary(column.filter)} · ${orderLabel(column)}` : undefined, onEdit: onEdit, onRename: onRename, children: ({ setNodeRef, style, handleProps, handleClassName, title }) => (_jsx("div", { ref: setNodeRef, ...handleProps, className: `min-w-[240px] w-[240px] flex-shrink-0 px-3 py-2 ${handleClassName}`, style: {
|
|
19
|
+
...style,
|
|
20
|
+
borderBottom: selected ? '3px solid var(--accent)' : '1px solid var(--border)',
|
|
21
|
+
background: 'var(--bg)',
|
|
22
|
+
}, "data-testid": `column-header-${column.slug}`, "data-column-slug": column.slug, "data-synthetic": column.synthetic ? 'true' : undefined, children: _jsx("span", { className: "block", style: {
|
|
23
|
+
fontFamily: 'var(--font-mono)',
|
|
24
|
+
fontSize: '11px',
|
|
25
|
+
fontWeight: 500,
|
|
26
|
+
textTransform: 'uppercase',
|
|
27
|
+
letterSpacing: '0.08em',
|
|
28
|
+
color: 'var(--ink-muted)',
|
|
29
|
+
}, children: title }) })) }));
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=ColumnHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColumnHeader.js","sourceRoot":"","sources":["../../src/board/ColumnHeader.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAWzD,SAAS,UAAU,CAAC,MAAY;IAC9B,IAAI,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,kBAAkB,CAAC;IAC7C,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,qBAAqB;QAAE,OAAO,QAAQ,CAAC;IAC/D,OAAO,MAAM,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;AAClF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,EAC3B,MAAM,EACN,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,QAAQ,GACU;IAClB,OAAO,CACL,KAAC,YAAY,IACX,GAAG,EAAC,SAAS,EACb,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,GAAG,MAAM,CAAC,KAAK,MAAM,SAAS,EAAE,EACvC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAC1F,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,YAEjB,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAC/D,cACE,GAAG,EAAE,UAAU,KACX,WAAW,EACf,SAAS,EAAE,mDAAmD,eAAe,EAAE,EAC/E,KAAK,EAAE;gBACL,GAAG,KAAK;gBACR,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,yBAAyB;gBAC9E,UAAU,EAAE,WAAW;aACxB,iBACY,iBAAiB,MAAM,CAAC,IAAI,EAAE,sBACzB,MAAM,CAAC,IAAI,oBACb,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,YAErD,eACE,SAAS,EAAC,OAAO,EACjB,KAAK,EAAE;oBACL,UAAU,EAAE,kBAAkB;oBAC9B,QAAQ,EAAE,MAAM;oBAChB,UAAU,EAAE,GAAG;oBACf,aAAa,EAAE,WAAW;oBAC1B,aAAa,EAAE,QAAQ;oBACvB,KAAK,EAAE,kBAAkB;iBAC1B,YAEA,KAAK,GACD,GACH,CACP,GACY,CAChB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Item } from '@awesome-markdown/contracts';
|
|
3
|
+
interface HomelessItemCardProps {
|
|
4
|
+
item: Item;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* A draggable card for homeless items. Uses `useDraggable` (not `useSortable`)
|
|
8
|
+
* because the homeless panel is a drag source only — no in-panel reordering.
|
|
9
|
+
*
|
|
10
|
+
* Carries `HomelessItemDragData` so Board.handleDragEnd can distinguish it
|
|
11
|
+
* from a regular cell-to-cell item drag.
|
|
12
|
+
*/
|
|
13
|
+
export declare function HomelessItemCard({ item }: HomelessItemCardProps): React.ReactElement;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=HomelessItemCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HomelessItemCard.d.ts","sourceRoot":"","sources":["../../src/board/HomelessItemCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,6BAA6B,CAAC;AAGxD,UAAU,qBAAqB;IAC7B,IAAI,EAAE,IAAI,CAAC;CACZ;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,IAAI,EAAE,EAAE,qBAAqB,GAAG,KAAK,CAAC,YAAY,CAqCpF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { useDraggable } from '@dnd-kit/core';
|
|
4
|
+
import { CSS } from '@dnd-kit/utilities';
|
|
5
|
+
/**
|
|
6
|
+
* A draggable card for homeless items. Uses `useDraggable` (not `useSortable`)
|
|
7
|
+
* because the homeless panel is a drag source only — no in-panel reordering.
|
|
8
|
+
*
|
|
9
|
+
* Carries `HomelessItemDragData` so Board.handleDragEnd can distinguish it
|
|
10
|
+
* from a regular cell-to-cell item drag.
|
|
11
|
+
*/
|
|
12
|
+
export function HomelessItemCard({ item }) {
|
|
13
|
+
const dragData = {
|
|
14
|
+
type: 'homeless-item',
|
|
15
|
+
itemSlug: item.slug,
|
|
16
|
+
};
|
|
17
|
+
const { attributes, listeners, setNodeRef, transform, isDragging } = useDraggable({
|
|
18
|
+
id: item.slug,
|
|
19
|
+
data: dragData,
|
|
20
|
+
});
|
|
21
|
+
const style = {
|
|
22
|
+
transform: CSS.Translate.toString(transform),
|
|
23
|
+
fontFamily: 'var(--font-sans)',
|
|
24
|
+
fontSize: '13px',
|
|
25
|
+
color: 'var(--ink)',
|
|
26
|
+
border: '1px solid var(--border)',
|
|
27
|
+
padding: '2px 10px',
|
|
28
|
+
background: 'var(--bg)',
|
|
29
|
+
cursor: isDragging ? 'grabbing' : 'grab',
|
|
30
|
+
opacity: isDragging ? 0.4 : 1,
|
|
31
|
+
userSelect: 'none',
|
|
32
|
+
touchAction: 'none',
|
|
33
|
+
};
|
|
34
|
+
return (_jsx("li", { ref: setNodeRef, style: style, "data-testid": `homeless-item-${item.slug}`, "data-item-slug": item.slug, ...attributes, ...listeners, children: item.title }));
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=HomelessItemCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HomelessItemCard.js","sourceRoot":"","sources":["../../src/board/HomelessItemCard.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAQzC;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAAE,IAAI,EAAyB;IAC9D,MAAM,QAAQ,GAAyB;QACrC,IAAI,EAAE,eAAe;QACrB,QAAQ,EAAE,IAAI,CAAC,IAAI;KACpB,CAAC;IAEF,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,YAAY,CAAC;QAChF,EAAE,EAAE,IAAI,CAAC,IAAI;QACb,IAAI,EAAE,QAAQ;KACf,CAAC,CAAC;IAEH,MAAM,KAAK,GAAwB;QACjC,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;QAC5C,UAAU,EAAE,kBAAkB;QAC9B,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,yBAAyB;QACjC,OAAO,EAAE,UAAU;QACnB,UAAU,EAAE,WAAW;QACvB,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM;QACxC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7B,UAAU,EAAE,MAAM;QAClB,WAAW,EAAE,MAAM;KACpB,CAAC;IAEF,OAAO,CACL,aACE,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,KAAK,iBACC,iBAAiB,IAAI,CAAC,IAAI,EAAE,oBACzB,IAAI,CAAC,IAAI,KACrB,UAAU,KACV,SAAS,YAEZ,IAAI,CAAC,KAAK,GACR,CACN,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Homeless, Item } from '@awesome-markdown/contracts';
|
|
3
|
+
interface HomelessPanelProps {
|
|
4
|
+
homeless: Homeless;
|
|
5
|
+
/**
|
|
6
|
+
* When provided, overrides `homeless.items` for rendering (e.g. to hide
|
|
7
|
+
* items that have been optimistically moved into a cell).
|
|
8
|
+
*/
|
|
9
|
+
items?: Item[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Collapsible panel listing items that belong to this board but no longer
|
|
13
|
+
* match any column filter. Populated from GET /boards/:slug/homeless.
|
|
14
|
+
*/
|
|
15
|
+
export declare function HomelessPanel({ homeless, items: itemsProp }: HomelessPanelProps): React.ReactElement;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=HomelessPanel.d.ts.map
|