@chelone/core 0.3.0 → 0.4.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.
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SourcePath } from "../resource/source-path.js";
|
|
1
2
|
import { type CalendarRange } from "./calendar-dates.js";
|
|
2
3
|
export interface CalendarEvent<R> {
|
|
3
4
|
record: R;
|
|
@@ -7,10 +8,10 @@ export interface CalendarEvent<R> {
|
|
|
7
8
|
color?: string;
|
|
8
9
|
}
|
|
9
10
|
export interface ToCalendarEventsOptions<R> {
|
|
10
|
-
startSource:
|
|
11
|
-
endSource?:
|
|
12
|
-
titleSource?:
|
|
13
|
-
colorSource?:
|
|
11
|
+
startSource: SourcePath<R>;
|
|
12
|
+
endSource?: SourcePath<R>;
|
|
13
|
+
titleSource?: SourcePath<R>;
|
|
14
|
+
colorSource?: SourcePath<R>;
|
|
14
15
|
/** Maps the value at `colorSource` to a color. */
|
|
15
16
|
colorMap?: Record<string, string>;
|
|
16
17
|
/** The title when `titleSource` is unset or empty: the adapter fills it from the record representation. */
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure rules behind a kanban board: which column holds which record, and what
|
|
3
|
+
* a drop writes back. No react, no vue: both `KanbanBoard` adapters build the
|
|
4
|
+
* same columns from the same records, and a drag handler that decides for
|
|
5
|
+
* itself lets the two boards disagree about the same drop.
|
|
6
|
+
*
|
|
7
|
+
* Drag events stay in the adapters, as `CalendarList` keeps its drag glue
|
|
8
|
+
* beside {@link moveCalendarEvent}.
|
|
9
|
+
*/
|
|
10
|
+
import type { Identifier } from "../resource/identifier.js";
|
|
11
|
+
import type { ResourceRecord } from "../resource/record.js";
|
|
12
|
+
import type { SourceKey } from "../resource/source-path.js";
|
|
13
|
+
export interface KanbanColumnDef {
|
|
14
|
+
/** Value written to `groupSource` by a drop into this column. */
|
|
15
|
+
id: string;
|
|
16
|
+
label: string;
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface KanbanBucket<R> {
|
|
20
|
+
column: KanbanColumnDef;
|
|
21
|
+
records: R[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The update a drop asks for, in the shape `update` takes: `data` is the patch
|
|
25
|
+
* and `previousData` the record as it was, so an adapter can undo the drop
|
|
26
|
+
* without a second read.
|
|
27
|
+
*/
|
|
28
|
+
export interface KanbanMove<R> {
|
|
29
|
+
id: Identifier;
|
|
30
|
+
data: Record<string, string>;
|
|
31
|
+
previousData: R;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* One bucket per column, in column order, empty columns included. A record
|
|
35
|
+
* lands in the column whose id is its group key; a record that names no column
|
|
36
|
+
* is in no bucket, and records keep list order inside a bucket. A repeated
|
|
37
|
+
* column id keeps the first column's records and leaves the later one empty.
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildKanbanBuckets<R extends ResourceRecord>(records: readonly R[], groupSource: SourceKey<R>, columns: readonly KanbanColumnDef[]): KanbanBucket<R>[];
|
|
40
|
+
/**
|
|
41
|
+
* The update a drop into `targetColumnId` asks for, or `null` when there is
|
|
42
|
+
* nothing to write: the target is not a column, or the record already sits in
|
|
43
|
+
* it. A drop that writes nothing still fires a data-provider `update` on every
|
|
44
|
+
* board that re-renders on a dropped drag, so the adapters ask here first.
|
|
45
|
+
*/
|
|
46
|
+
export declare function planKanbanMove<R extends ResourceRecord>(record: R, groupSource: SourceKey<R>, columns: readonly KanbanColumnDef[], targetColumnId: string): KanbanMove<R> | null;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
function bucketKey(record, groupSource) {
|
|
2
|
+
const value = record[groupSource];
|
|
3
|
+
return String(value ?? "");
|
|
4
|
+
}
|
|
5
|
+
function buildKanbanBuckets(records, groupSource, columns) {
|
|
6
|
+
const buckets = columns.map((column) => ({
|
|
7
|
+
column,
|
|
8
|
+
records: []
|
|
9
|
+
}));
|
|
10
|
+
const bucketOf = /* @__PURE__ */ new Map();
|
|
11
|
+
columns.forEach((column, index) => {
|
|
12
|
+
if (!bucketOf.has(column.id)) bucketOf.set(column.id, index);
|
|
13
|
+
});
|
|
14
|
+
for (const record of records) {
|
|
15
|
+
const index = bucketOf.get(bucketKey(record, groupSource));
|
|
16
|
+
if (index === void 0) continue;
|
|
17
|
+
buckets[index].records.push(record);
|
|
18
|
+
}
|
|
19
|
+
return buckets;
|
|
20
|
+
}
|
|
21
|
+
function planKanbanMove(record, groupSource, columns, targetColumnId) {
|
|
22
|
+
if (!columns.some((column) => column.id === targetColumnId)) return null;
|
|
23
|
+
if (bucketKey(record, groupSource) === targetColumnId) return null;
|
|
24
|
+
const data = { [groupSource]: targetColumnId };
|
|
25
|
+
return { id: record.id, data, previousData: record };
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
buildKanbanBuckets,
|
|
29
|
+
planKanbanMove
|
|
30
|
+
};
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* records, and no record disappears when the data holds a parent cycle.
|
|
5
5
|
*/
|
|
6
6
|
import type { Identifier } from "../resource/identifier.js";
|
|
7
|
+
import type { SourcePath } from "../resource/source-path.js";
|
|
7
8
|
export interface RecordTreeNode<R> {
|
|
8
9
|
record: R;
|
|
9
10
|
children: RecordTreeNode<R>[];
|
|
@@ -17,4 +18,4 @@ export interface RecordTreeNode<R> {
|
|
|
17
18
|
*/
|
|
18
19
|
export declare function buildRecordTree<R extends {
|
|
19
20
|
id: Identifier;
|
|
20
|
-
}>(records: readonly R[], parentSource:
|
|
21
|
+
}>(records: readonly R[], parentSource: SourcePath<R>): RecordTreeNode<R>[];
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export { arrangeColumns, columnLabelMatches, dataTableColumnKeys, defaultDataTab
|
|
|
21
21
|
export { isFilterSelected, toggleFilterValue, } from "./controller/filter-toggle.js";
|
|
22
22
|
export type { InfiniteListController, InfiniteListControllerState, } from "./controller/infinite-list-controller.js";
|
|
23
23
|
export { createInfiniteListController } from "./controller/infinite-list-controller.js";
|
|
24
|
+
export type { KanbanBucket, KanbanColumnDef, KanbanMove, } from "./controller/kanban-board.js";
|
|
25
|
+
export { buildKanbanBuckets, planKanbanMove, } from "./controller/kanban-board.js";
|
|
24
26
|
export type { ListController, ListControllerContext, ListControllerOptions, ListControllerState, ListParamsPatch, } from "./controller/list-controller.js";
|
|
25
27
|
export { createListController, listControllerActions, } from "./controller/list-controller.js";
|
|
26
28
|
export type { ListParamsQuery, ListUrlState, } from "./controller/list-params.js";
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { createClientListController } from "./controller/client-list-controller.
|
|
|
10
10
|
import { arrangeColumns, columnLabelMatches, dataTableColumnKeys, defaultDataTableStoreKey, getDataTableColumnId, moveColumn, toggleHiddenColumn } from "./controller/data-table-columns.js";
|
|
11
11
|
import { isFilterSelected, toggleFilterValue } from "./controller/filter-toggle.js";
|
|
12
12
|
import { createInfiniteListController } from "./controller/infinite-list-controller.js";
|
|
13
|
+
import { buildKanbanBuckets, planKanbanMove } from "./controller/kanban-board.js";
|
|
13
14
|
import { createListController, listControllerActions } from "./controller/list-controller.js";
|
|
14
15
|
import { hasCustomParams, listPatchFromSearch, parseListParams, serializeListParams, serializeListState } from "./controller/list-params.js";
|
|
15
16
|
import { canUseCachedPage, getPrevNextParams, resolvePrevNext } from "./controller/prev-next.js";
|
|
@@ -117,6 +118,7 @@ export {
|
|
|
117
118
|
authStateQueryOptions,
|
|
118
119
|
bboxToPolygon,
|
|
119
120
|
buildApprovalUpdate,
|
|
121
|
+
buildKanbanBuckets,
|
|
120
122
|
buildOverpassQuery,
|
|
121
123
|
buildRecordTree,
|
|
122
124
|
calendarDayKey,
|
|
@@ -290,6 +292,7 @@ export {
|
|
|
290
292
|
parseLocation,
|
|
291
293
|
patchedRecord,
|
|
292
294
|
permissionsQueryOptions,
|
|
295
|
+
planKanbanMove,
|
|
293
296
|
polygonToBBox,
|
|
294
297
|
presenceTopic,
|
|
295
298
|
rasterTileStyle,
|