@devfellowship/components 3.2.3 → 3.3.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/dist/cli.js +132 -10
- package/dist/index.cjs +523 -0
- package/dist/index.d.cts +1061 -1
- package/dist/index.d.ts +1061 -1
- package/dist/index.js +467 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -118,7 +118,14 @@ __export(src_exports, {
|
|
|
118
118
|
ContextMenuSubContent: () => ContextMenuSubContent,
|
|
119
119
|
ContextMenuSubTrigger: () => ContextMenuSubTrigger,
|
|
120
120
|
ContextMenuTrigger: () => ContextMenuTrigger,
|
|
121
|
+
DEFAULT_EDGE_ARROW: () => DEFAULT_EDGE_ARROW,
|
|
122
|
+
DEFAULT_EDGE_ROUTE: () => DEFAULT_EDGE_ROUTE,
|
|
123
|
+
DEFAULT_EDGE_STYLE: () => DEFAULT_EDGE_STYLE,
|
|
124
|
+
DEFAULT_GROUP_TONE: () => DEFAULT_GROUP_TONE,
|
|
125
|
+
DEFAULT_LEGEND_PLACEMENT: () => DEFAULT_LEGEND_PLACEMENT,
|
|
121
126
|
DEFAULT_NAME_COL_WIDTH: () => DEFAULT_NAME_COL_WIDTH,
|
|
127
|
+
DEFAULT_NODE_SPAN: () => DEFAULT_NODE_SPAN,
|
|
128
|
+
DEFAULT_NODE_STATE: () => DEFAULT_NODE_STATE,
|
|
122
129
|
DflRemote: () => DflRemote,
|
|
123
130
|
Dialog: () => Dialog,
|
|
124
131
|
DialogClose: () => DialogClose,
|
|
@@ -196,6 +203,7 @@ __export(src_exports, {
|
|
|
196
203
|
MenubarSubContent: () => MenubarSubContent,
|
|
197
204
|
MenubarSubTrigger: () => MenubarSubTrigger,
|
|
198
205
|
MenubarTrigger: () => MenubarTrigger,
|
|
206
|
+
NODE_KIND_DEFAULT_TONE: () => NODE_KIND_DEFAULT_TONE,
|
|
199
207
|
NavigationMenu: () => NavigationMenu,
|
|
200
208
|
NavigationMenuContent: () => NavigationMenuContent,
|
|
201
209
|
NavigationMenuIndicator: () => NavigationMenuIndicator,
|
|
@@ -219,6 +227,17 @@ __export(src_exports, {
|
|
|
219
227
|
Progress: () => Progress,
|
|
220
228
|
ProtectedRoute: () => ProtectedRoute,
|
|
221
229
|
PublishDrawer: () => PublishDrawer,
|
|
230
|
+
ROADMAP_ARROWS: () => ROADMAP_ARROWS,
|
|
231
|
+
ROADMAP_COLUMNS: () => ROADMAP_COLUMNS,
|
|
232
|
+
ROADMAP_EDGE_LABEL_MAX: () => ROADMAP_EDGE_LABEL_MAX,
|
|
233
|
+
ROADMAP_EDGE_ROUTES: () => ROADMAP_EDGE_ROUTES,
|
|
234
|
+
ROADMAP_EDGE_STYLES: () => ROADMAP_EDGE_STYLES,
|
|
235
|
+
ROADMAP_LABEL_MAX: () => ROADMAP_LABEL_MAX,
|
|
236
|
+
ROADMAP_LEGEND_PLACEMENTS: () => ROADMAP_LEGEND_PLACEMENTS,
|
|
237
|
+
ROADMAP_NODE_ID_PATTERN: () => ROADMAP_NODE_ID_PATTERN,
|
|
238
|
+
ROADMAP_NODE_KINDS: () => ROADMAP_NODE_KINDS,
|
|
239
|
+
ROADMAP_NODE_STATES: () => ROADMAP_NODE_STATES,
|
|
240
|
+
ROADMAP_TONES: () => ROADMAP_TONES,
|
|
222
241
|
RadioGroup: () => RadioGroup4,
|
|
223
242
|
RadioGroupItem: () => RadioGroupItem,
|
|
224
243
|
RadioGroupRow: () => RadioGroupRow,
|
|
@@ -312,19 +331,55 @@ __export(src_exports, {
|
|
|
312
331
|
buttonVariants: () => buttonVariants,
|
|
313
332
|
clampPct: () => clampPct,
|
|
314
333
|
cn: () => cn,
|
|
334
|
+
columnIndex: () => columnIndex,
|
|
335
|
+
columnsCovered: () => columnsCovered,
|
|
336
|
+
columnsUsed: () => columnsUsed,
|
|
315
337
|
filterPublishableAccounts: () => filterPublishableAccounts,
|
|
338
|
+
firstFreeRow: () => firstFreeRow,
|
|
316
339
|
getInitials: () => getInitials,
|
|
340
|
+
gridColumnFor: () => gridColumnFor,
|
|
341
|
+
groupColumnRuns: () => groupColumnRuns,
|
|
342
|
+
groupRanges: () => groupRanges,
|
|
317
343
|
iconButtonVariants: () => iconButtonVariants,
|
|
318
344
|
isAllowedOrigin: () => isAllowedOrigin,
|
|
319
345
|
kbdVariants: () => kbdVariants,
|
|
320
346
|
labelVariants: () => labelVariants,
|
|
347
|
+
maxRowOf: () => maxRowOf,
|
|
321
348
|
memberHueIndex: () => memberHueIndex,
|
|
322
349
|
memberHueVar: () => memberHueVar,
|
|
323
350
|
navigationMenuTriggerStyle: () => navigationMenuTriggerStyle,
|
|
351
|
+
nodesByRow: () => nodesByRow,
|
|
352
|
+
parseRoadmapDocument: () => parseRoadmapDocument,
|
|
353
|
+
parseRoadmapStateOverlay: () => parseRoadmapStateOverlay,
|
|
324
354
|
parseTags: () => parseTags,
|
|
355
|
+
placeNodes: () => placeNodes,
|
|
356
|
+
resolveEdgeArrow: () => resolveEdgeArrow,
|
|
357
|
+
resolveEdgeRoute: () => resolveEdgeRoute,
|
|
358
|
+
resolveEdgeStyle: () => resolveEdgeStyle,
|
|
359
|
+
resolveGroupColumns: () => resolveGroupColumns,
|
|
360
|
+
resolveGroupTone: () => resolveGroupTone,
|
|
361
|
+
resolveLegendPlacement: () => resolveLegendPlacement,
|
|
325
362
|
resolveNameColWidth: () => resolveNameColWidth,
|
|
363
|
+
resolveNodeSpan: () => resolveNodeSpan,
|
|
364
|
+
resolveNodeState: () => resolveNodeState,
|
|
365
|
+
resolveNodeTone: () => resolveNodeTone,
|
|
326
366
|
resolveWeekCount: () => resolveWeekCount,
|
|
327
367
|
resolveWeekLabels: () => resolveWeekLabels,
|
|
368
|
+
roadmapActionSchema: () => roadmapActionSchema,
|
|
369
|
+
roadmapDocumentSchema: () => roadmapDocumentSchema,
|
|
370
|
+
roadmapEdgeSchema: () => roadmapEdgeSchema,
|
|
371
|
+
roadmapGroupSchema: () => roadmapGroupSchema,
|
|
372
|
+
roadmapIconSchema: () => roadmapIconSchema,
|
|
373
|
+
roadmapLegendEntrySchema: () => roadmapLegendEntrySchema,
|
|
374
|
+
roadmapLegendSchema: () => roadmapLegendSchema,
|
|
375
|
+
roadmapLinkSchema: () => roadmapLinkSchema,
|
|
376
|
+
roadmapNodeSchema: () => roadmapNodeSchema,
|
|
377
|
+
roadmapNodeStateSchema: () => roadmapNodeStateSchema,
|
|
378
|
+
roadmapStateOverlaySchema: () => roadmapStateOverlaySchema,
|
|
379
|
+
roadmapStateSchema: () => roadmapStateSchema,
|
|
380
|
+
rowsOf: () => rowsOf,
|
|
381
|
+
safeParseRoadmapDocument: () => safeParseRoadmapDocument,
|
|
382
|
+
safeParseRoadmapStateOverlay: () => safeParseRoadmapStateOverlay,
|
|
328
383
|
stageProgress: () => stageProgress,
|
|
329
384
|
toast: () => toast,
|
|
330
385
|
toggleVariants: () => toggleVariants,
|
|
@@ -338,6 +393,7 @@ __export(src_exports, {
|
|
|
338
393
|
useSession: () => useSession,
|
|
339
394
|
useSidebar: () => useSidebar,
|
|
340
395
|
useToast: () => useToast,
|
|
396
|
+
validateNoOverlap: () => validateNoOverlap,
|
|
341
397
|
validatePublishForm: () => validatePublishForm
|
|
342
398
|
});
|
|
343
399
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -8637,6 +8693,417 @@ function PublishDrawer({
|
|
|
8637
8693
|
) });
|
|
8638
8694
|
}
|
|
8639
8695
|
|
|
8696
|
+
// src/components/organisms/roadmap/contract.ts
|
|
8697
|
+
var import_zod = require("zod");
|
|
8698
|
+
var ROADMAP_COLUMNS = ["left", "center", "right"];
|
|
8699
|
+
var ROADMAP_TONES = [
|
|
8700
|
+
"primary",
|
|
8701
|
+
"secondary",
|
|
8702
|
+
"accent",
|
|
8703
|
+
"muted",
|
|
8704
|
+
"success",
|
|
8705
|
+
"info",
|
|
8706
|
+
"danger",
|
|
8707
|
+
"neutral"
|
|
8708
|
+
];
|
|
8709
|
+
var ROADMAP_NODE_KINDS = [
|
|
8710
|
+
"topic",
|
|
8711
|
+
"subtopic",
|
|
8712
|
+
"label",
|
|
8713
|
+
"title",
|
|
8714
|
+
"paragraph",
|
|
8715
|
+
"button",
|
|
8716
|
+
"legend"
|
|
8717
|
+
];
|
|
8718
|
+
var ROADMAP_NODE_STATES = ["todo", "done", "learning", "skipped", "locked"];
|
|
8719
|
+
var ROADMAP_EDGE_STYLES = ["solid", "dashed", "dotted"];
|
|
8720
|
+
var ROADMAP_EDGE_ROUTES = ["auto", "straight", "elbow", "curve"];
|
|
8721
|
+
var ROADMAP_ARROWS = ["none", "end", "both"];
|
|
8722
|
+
var ROADMAP_LEGEND_PLACEMENTS = ["top", "bottom", "inline"];
|
|
8723
|
+
var DEFAULT_NODE_SPAN = 1;
|
|
8724
|
+
var DEFAULT_EDGE_STYLE = "dashed";
|
|
8725
|
+
var DEFAULT_EDGE_ROUTE = "auto";
|
|
8726
|
+
var DEFAULT_EDGE_ARROW = "none";
|
|
8727
|
+
var DEFAULT_GROUP_TONE = "neutral";
|
|
8728
|
+
var DEFAULT_LEGEND_PLACEMENT = "top";
|
|
8729
|
+
var DEFAULT_NODE_STATE = "todo";
|
|
8730
|
+
var NODE_KIND_DEFAULT_TONE = {
|
|
8731
|
+
topic: "primary",
|
|
8732
|
+
subtopic: "secondary",
|
|
8733
|
+
button: "primary",
|
|
8734
|
+
label: "neutral",
|
|
8735
|
+
title: "neutral",
|
|
8736
|
+
paragraph: "neutral",
|
|
8737
|
+
legend: "neutral"
|
|
8738
|
+
};
|
|
8739
|
+
var resolveNodeSpan = (node) => node.span ?? DEFAULT_NODE_SPAN;
|
|
8740
|
+
var resolveNodeTone = (node) => node.tone ?? NODE_KIND_DEFAULT_TONE[node.kind];
|
|
8741
|
+
var resolveEdgeStyle = (edge) => edge.style ?? DEFAULT_EDGE_STYLE;
|
|
8742
|
+
var resolveEdgeRoute = (edge) => edge.route ?? DEFAULT_EDGE_ROUTE;
|
|
8743
|
+
var resolveEdgeArrow = (edge) => edge.arrow ?? DEFAULT_EDGE_ARROW;
|
|
8744
|
+
var resolveGroupTone = (group) => group.tone ?? DEFAULT_GROUP_TONE;
|
|
8745
|
+
var resolveGroupColumns = (group) => group.columns && group.columns.length > 0 ? group.columns : [...ROADMAP_COLUMNS];
|
|
8746
|
+
var resolveLegendPlacement = (legend) => legend.placement ?? DEFAULT_LEGEND_PLACEMENT;
|
|
8747
|
+
var resolveNodeState = (node, overlay) => overlay?.nodes[node.id] ?? node.state ?? DEFAULT_NODE_STATE;
|
|
8748
|
+
var ROADMAP_NODE_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
8749
|
+
var ROADMAP_EDGE_LABEL_MAX = 40;
|
|
8750
|
+
var ROADMAP_LABEL_MAX = 200;
|
|
8751
|
+
var columnSchema = import_zod.z.enum(ROADMAP_COLUMNS);
|
|
8752
|
+
var toneSchema = import_zod.z.enum(ROADMAP_TONES);
|
|
8753
|
+
var idSchema = import_zod.z.string().regex(ROADMAP_NODE_ID_PATTERN, "must match /^[A-Za-z0-9_-]{1,64}$/");
|
|
8754
|
+
var metaSchema = import_zod.z.record(import_zod.z.unknown());
|
|
8755
|
+
var roadmapIconSchema = import_zod.z.object({
|
|
8756
|
+
name: import_zod.z.string().min(1).max(64),
|
|
8757
|
+
side: import_zod.z.enum(["left", "right"]),
|
|
8758
|
+
tone: toneSchema.optional()
|
|
8759
|
+
}).strict();
|
|
8760
|
+
var roadmapActionSchema = import_zod.z.object({
|
|
8761
|
+
label: import_zod.z.string().min(1).max(80),
|
|
8762
|
+
href: import_zod.z.string().min(1).optional(),
|
|
8763
|
+
actionId: import_zod.z.string().min(1).optional(),
|
|
8764
|
+
tone: toneSchema.optional()
|
|
8765
|
+
}).strict().superRefine((action, ctx) => {
|
|
8766
|
+
const given = [action.href, action.actionId].filter((v) => v !== void 0).length;
|
|
8767
|
+
if (given !== 1) {
|
|
8768
|
+
ctx.addIssue({
|
|
8769
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
8770
|
+
path: ["href"],
|
|
8771
|
+
message: "an action needs exactly one of `href` or `actionId`"
|
|
8772
|
+
});
|
|
8773
|
+
}
|
|
8774
|
+
});
|
|
8775
|
+
var roadmapLinkSchema = import_zod.z.object({ label: import_zod.z.string().min(1).max(120), href: import_zod.z.string().min(1) }).strict();
|
|
8776
|
+
var roadmapNodeStateSchema = import_zod.z.enum(ROADMAP_NODE_STATES);
|
|
8777
|
+
var roadmapNodeSchema = import_zod.z.object({
|
|
8778
|
+
id: idSchema,
|
|
8779
|
+
column: columnSchema,
|
|
8780
|
+
order: import_zod.z.number().int().min(0),
|
|
8781
|
+
span: import_zod.z.union([import_zod.z.literal(1), import_zod.z.literal(2), import_zod.z.literal(3)]).optional(),
|
|
8782
|
+
kind: import_zod.z.enum(ROADMAP_NODE_KINDS),
|
|
8783
|
+
label: import_zod.z.string().min(1).max(ROADMAP_LABEL_MAX),
|
|
8784
|
+
description: import_zod.z.string().max(2e3).optional(),
|
|
8785
|
+
tone: toneSchema.optional(),
|
|
8786
|
+
icon: roadmapIconSchema.optional(),
|
|
8787
|
+
badge: import_zod.z.string().min(1).optional(),
|
|
8788
|
+
state: roadmapNodeStateSchema.optional(),
|
|
8789
|
+
action: roadmapActionSchema.optional(),
|
|
8790
|
+
href: import_zod.z.string().min(1).optional(),
|
|
8791
|
+
links: import_zod.z.array(roadmapLinkSchema).optional(),
|
|
8792
|
+
meta: metaSchema.optional()
|
|
8793
|
+
}).strict();
|
|
8794
|
+
var roadmapEdgeSchema = import_zod.z.object({
|
|
8795
|
+
id: idSchema,
|
|
8796
|
+
source: import_zod.z.string().min(1),
|
|
8797
|
+
target: import_zod.z.string().min(1),
|
|
8798
|
+
style: import_zod.z.enum(ROADMAP_EDGE_STYLES).optional(),
|
|
8799
|
+
label: import_zod.z.string().min(1).max(ROADMAP_EDGE_LABEL_MAX).optional(),
|
|
8800
|
+
route: import_zod.z.enum(ROADMAP_EDGE_ROUTES).optional(),
|
|
8801
|
+
arrow: import_zod.z.enum(ROADMAP_ARROWS).optional(),
|
|
8802
|
+
tone: toneSchema.optional()
|
|
8803
|
+
}).strict();
|
|
8804
|
+
var roadmapGroupSchema = import_zod.z.object({
|
|
8805
|
+
id: idSchema,
|
|
8806
|
+
title: import_zod.z.string().min(1).max(ROADMAP_LABEL_MAX).optional(),
|
|
8807
|
+
tone: toneSchema.optional(),
|
|
8808
|
+
from: import_zod.z.number().int().min(0),
|
|
8809
|
+
to: import_zod.z.number().int().min(0),
|
|
8810
|
+
columns: import_zod.z.array(columnSchema).min(1).max(3).optional(),
|
|
8811
|
+
description: import_zod.z.string().max(2e3).optional()
|
|
8812
|
+
}).strict();
|
|
8813
|
+
var roadmapLegendEntrySchema = import_zod.z.object({
|
|
8814
|
+
id: idSchema,
|
|
8815
|
+
label: import_zod.z.string().min(1).max(ROADMAP_LABEL_MAX),
|
|
8816
|
+
tone: toneSchema,
|
|
8817
|
+
icon: import_zod.z.string().min(1).max(64).optional()
|
|
8818
|
+
}).strict();
|
|
8819
|
+
var roadmapLegendSchema = import_zod.z.object({
|
|
8820
|
+
entries: import_zod.z.array(roadmapLegendEntrySchema).min(1),
|
|
8821
|
+
placement: import_zod.z.enum(ROADMAP_LEGEND_PLACEMENTS).optional()
|
|
8822
|
+
}).strict();
|
|
8823
|
+
function columnsCovered(node) {
|
|
8824
|
+
const span = node.span ?? DEFAULT_NODE_SPAN;
|
|
8825
|
+
if (span === 3) return [...ROADMAP_COLUMNS];
|
|
8826
|
+
const start = ROADMAP_COLUMNS.indexOf(node.column);
|
|
8827
|
+
return ROADMAP_COLUMNS.slice(start, start + span);
|
|
8828
|
+
}
|
|
8829
|
+
var roadmapDocumentBaseSchema = import_zod.z.object({
|
|
8830
|
+
version: import_zod.z.literal("roadmap/v1"),
|
|
8831
|
+
title: import_zod.z.string().min(1).max(ROADMAP_LABEL_MAX).optional(),
|
|
8832
|
+
direction: import_zod.z.literal("down"),
|
|
8833
|
+
columns: import_zod.z.literal(3),
|
|
8834
|
+
nodes: import_zod.z.array(roadmapNodeSchema),
|
|
8835
|
+
edges: import_zod.z.array(roadmapEdgeSchema),
|
|
8836
|
+
groups: import_zod.z.array(roadmapGroupSchema),
|
|
8837
|
+
legend: roadmapLegendSchema.optional(),
|
|
8838
|
+
meta: metaSchema.optional()
|
|
8839
|
+
}).strict();
|
|
8840
|
+
var roadmapDocumentSchema = roadmapDocumentBaseSchema.superRefine((doc, ctx) => {
|
|
8841
|
+
const nodeIndexById = /* @__PURE__ */ new Map();
|
|
8842
|
+
doc.nodes.forEach((node, i) => {
|
|
8843
|
+
if (nodeIndexById.has(node.id)) {
|
|
8844
|
+
ctx.addIssue({
|
|
8845
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
8846
|
+
path: ["nodes", i, "id"],
|
|
8847
|
+
message: `duplicate node id "${node.id}" (first seen at nodes[${nodeIndexById.get(node.id)}])`
|
|
8848
|
+
});
|
|
8849
|
+
return;
|
|
8850
|
+
}
|
|
8851
|
+
nodeIndexById.set(node.id, i);
|
|
8852
|
+
});
|
|
8853
|
+
const cellOwner = /* @__PURE__ */ new Map();
|
|
8854
|
+
doc.nodes.forEach((node, i) => {
|
|
8855
|
+
const span = node.span ?? DEFAULT_NODE_SPAN;
|
|
8856
|
+
if (span === 2 && node.column === "right") {
|
|
8857
|
+
ctx.addIssue({
|
|
8858
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
8859
|
+
path: ["nodes", i, "span"],
|
|
8860
|
+
message: 'a `span: 2` node at column "right" runs past the last track'
|
|
8861
|
+
});
|
|
8862
|
+
return;
|
|
8863
|
+
}
|
|
8864
|
+
for (const column of columnsCovered(node)) {
|
|
8865
|
+
const key = `${column}:${node.order}`;
|
|
8866
|
+
const owner = cellOwner.get(key);
|
|
8867
|
+
if (owner !== void 0) {
|
|
8868
|
+
ctx.addIssue({
|
|
8869
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
8870
|
+
path: ["nodes", i, "order"],
|
|
8871
|
+
message: `cell (${column}, ${node.order}) is already taken by nodes[${owner}] ("${doc.nodes[owner].id}")`
|
|
8872
|
+
});
|
|
8873
|
+
continue;
|
|
8874
|
+
}
|
|
8875
|
+
cellOwner.set(key, i);
|
|
8876
|
+
}
|
|
8877
|
+
});
|
|
8878
|
+
const edgeIds = /* @__PURE__ */ new Set();
|
|
8879
|
+
doc.edges.forEach((edge, i) => {
|
|
8880
|
+
if (edgeIds.has(edge.id)) {
|
|
8881
|
+
ctx.addIssue({
|
|
8882
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
8883
|
+
path: ["edges", i, "id"],
|
|
8884
|
+
message: `duplicate edge id "${edge.id}"`
|
|
8885
|
+
});
|
|
8886
|
+
}
|
|
8887
|
+
edgeIds.add(edge.id);
|
|
8888
|
+
if (!nodeIndexById.has(edge.source)) {
|
|
8889
|
+
ctx.addIssue({
|
|
8890
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
8891
|
+
path: ["edges", i, "source"],
|
|
8892
|
+
message: `edge source "${edge.source}" is not a node in this document`
|
|
8893
|
+
});
|
|
8894
|
+
}
|
|
8895
|
+
if (!nodeIndexById.has(edge.target)) {
|
|
8896
|
+
ctx.addIssue({
|
|
8897
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
8898
|
+
path: ["edges", i, "target"],
|
|
8899
|
+
message: `edge target "${edge.target}" is not a node in this document`
|
|
8900
|
+
});
|
|
8901
|
+
}
|
|
8902
|
+
if (edge.source === edge.target) {
|
|
8903
|
+
ctx.addIssue({
|
|
8904
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
8905
|
+
path: ["edges", i, "target"],
|
|
8906
|
+
message: `edge "${edge.id}" is a self-loop`
|
|
8907
|
+
});
|
|
8908
|
+
}
|
|
8909
|
+
});
|
|
8910
|
+
const groupIds = /* @__PURE__ */ new Set();
|
|
8911
|
+
doc.groups.forEach((group, i) => {
|
|
8912
|
+
if (groupIds.has(group.id)) {
|
|
8913
|
+
ctx.addIssue({
|
|
8914
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
8915
|
+
path: ["groups", i, "id"],
|
|
8916
|
+
message: `duplicate group id "${group.id}"`
|
|
8917
|
+
});
|
|
8918
|
+
}
|
|
8919
|
+
groupIds.add(group.id);
|
|
8920
|
+
if (group.from > group.to) {
|
|
8921
|
+
ctx.addIssue({
|
|
8922
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
8923
|
+
path: ["groups", i, "to"],
|
|
8924
|
+
message: `group "${group.id}" has from (${group.from}) greater than to (${group.to})`
|
|
8925
|
+
});
|
|
8926
|
+
}
|
|
8927
|
+
});
|
|
8928
|
+
for (let i = 0; i < doc.groups.length; i += 1) {
|
|
8929
|
+
const a = doc.groups[i];
|
|
8930
|
+
if (a.from > a.to) continue;
|
|
8931
|
+
const aColumns = new Set(resolveGroupColumns(a));
|
|
8932
|
+
for (let j = i + 1; j < doc.groups.length; j += 1) {
|
|
8933
|
+
const b = doc.groups[j];
|
|
8934
|
+
if (b.from > b.to) continue;
|
|
8935
|
+
const rowsOverlap = a.from <= b.to && b.from <= a.to;
|
|
8936
|
+
if (!rowsOverlap) continue;
|
|
8937
|
+
const shared = resolveGroupColumns(b).filter((c) => aColumns.has(c));
|
|
8938
|
+
if (shared.length === 0) continue;
|
|
8939
|
+
ctx.addIssue({
|
|
8940
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
8941
|
+
path: ["groups", j, "from"],
|
|
8942
|
+
message: `group "${b.id}" overlaps rows ${a.from}..${a.to} of group "${a.id}" on column(s) ${shared.join(", ")}`
|
|
8943
|
+
});
|
|
8944
|
+
}
|
|
8945
|
+
}
|
|
8946
|
+
const legendIds = /* @__PURE__ */ new Set();
|
|
8947
|
+
doc.legend?.entries.forEach((entry, i) => {
|
|
8948
|
+
if (legendIds.has(entry.id)) {
|
|
8949
|
+
ctx.addIssue({
|
|
8950
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
8951
|
+
path: ["legend", "entries", i, "id"],
|
|
8952
|
+
message: `duplicate legend entry id "${entry.id}"`
|
|
8953
|
+
});
|
|
8954
|
+
}
|
|
8955
|
+
legendIds.add(entry.id);
|
|
8956
|
+
});
|
|
8957
|
+
doc.nodes.forEach((node, i) => {
|
|
8958
|
+
if (node.badge === void 0) return;
|
|
8959
|
+
if (!legendIds.has(node.badge)) {
|
|
8960
|
+
ctx.addIssue({
|
|
8961
|
+
code: import_zod.z.ZodIssueCode.custom,
|
|
8962
|
+
path: ["nodes", i, "badge"],
|
|
8963
|
+
message: `badge "${node.badge}" is not a legend entry of this document`
|
|
8964
|
+
});
|
|
8965
|
+
}
|
|
8966
|
+
});
|
|
8967
|
+
});
|
|
8968
|
+
var roadmapStateOverlaySchema = import_zod.z.object({
|
|
8969
|
+
version: import_zod.z.literal("roadmap-state/v1"),
|
|
8970
|
+
nodes: import_zod.z.record(roadmapNodeStateSchema)
|
|
8971
|
+
}).strict();
|
|
8972
|
+
var roadmapStateSchema = roadmapStateOverlaySchema;
|
|
8973
|
+
function parseRoadmapDocument(input) {
|
|
8974
|
+
return roadmapDocumentSchema.parse(input);
|
|
8975
|
+
}
|
|
8976
|
+
function safeParseRoadmapDocument(input) {
|
|
8977
|
+
return roadmapDocumentSchema.safeParse(input);
|
|
8978
|
+
}
|
|
8979
|
+
function parseRoadmapStateOverlay(input) {
|
|
8980
|
+
return roadmapStateOverlaySchema.parse(input);
|
|
8981
|
+
}
|
|
8982
|
+
function safeParseRoadmapStateOverlay(input) {
|
|
8983
|
+
return roadmapStateOverlaySchema.safeParse(input);
|
|
8984
|
+
}
|
|
8985
|
+
|
|
8986
|
+
// src/components/organisms/roadmap/layout.ts
|
|
8987
|
+
function columnIndex(column) {
|
|
8988
|
+
return ROADMAP_COLUMNS.indexOf(column);
|
|
8989
|
+
}
|
|
8990
|
+
function gridColumnFor(node) {
|
|
8991
|
+
const span = resolveNodeSpan(node);
|
|
8992
|
+
if (span === 3) return { start: 1, span: 3 };
|
|
8993
|
+
return { start: columnIndex(node.column) + 1, span };
|
|
8994
|
+
}
|
|
8995
|
+
function rowsOf(doc) {
|
|
8996
|
+
const rows = /* @__PURE__ */ new Set();
|
|
8997
|
+
for (const node of doc.nodes) rows.add(node.order);
|
|
8998
|
+
return [...rows].sort((a, b) => a - b);
|
|
8999
|
+
}
|
|
9000
|
+
function maxRowOf(doc) {
|
|
9001
|
+
return doc.nodes.reduce((max, node) => Math.max(max, node.order), -1);
|
|
9002
|
+
}
|
|
9003
|
+
function nodesByRow(doc) {
|
|
9004
|
+
const byRow = /* @__PURE__ */ new Map();
|
|
9005
|
+
for (const node of doc.nodes) {
|
|
9006
|
+
const bucket = byRow.get(node.order);
|
|
9007
|
+
if (bucket) bucket.push(node);
|
|
9008
|
+
else byRow.set(node.order, [node]);
|
|
9009
|
+
}
|
|
9010
|
+
for (const bucket of byRow.values()) {
|
|
9011
|
+
bucket.sort((a, b) => {
|
|
9012
|
+
const byColumn = columnIndex(a.column) - columnIndex(b.column);
|
|
9013
|
+
return byColumn !== 0 ? byColumn : a.id.localeCompare(b.id);
|
|
9014
|
+
});
|
|
9015
|
+
}
|
|
9016
|
+
return byRow;
|
|
9017
|
+
}
|
|
9018
|
+
function columnsUsed(doc) {
|
|
9019
|
+
const used = /* @__PURE__ */ new Set();
|
|
9020
|
+
for (const node of doc.nodes) for (const column of columnsCovered(node)) used.add(column);
|
|
9021
|
+
return ROADMAP_COLUMNS.filter((column) => used.has(column));
|
|
9022
|
+
}
|
|
9023
|
+
function groupRanges(doc) {
|
|
9024
|
+
return doc.groups.map((group) => {
|
|
9025
|
+
const columns = resolveGroupColumns(group);
|
|
9026
|
+
const indices = columns.map(columnIndex).sort((a, b) => a - b);
|
|
9027
|
+
const start = indices[0];
|
|
9028
|
+
const end = indices[indices.length - 1];
|
|
9029
|
+
return {
|
|
9030
|
+
id: group.id,
|
|
9031
|
+
from: group.from,
|
|
9032
|
+
to: group.to,
|
|
9033
|
+
columns: ROADMAP_COLUMNS.filter((c) => columns.includes(c)),
|
|
9034
|
+
row: { start: group.from + 1, span: group.to - group.from + 1 },
|
|
9035
|
+
column: { start: start + 1, span: end - start + 1 },
|
|
9036
|
+
fragmented: end - start + 1 !== indices.length
|
|
9037
|
+
};
|
|
9038
|
+
});
|
|
9039
|
+
}
|
|
9040
|
+
function groupColumnRuns(group) {
|
|
9041
|
+
const indices = resolveGroupColumns(group).map(columnIndex).sort((a, b) => a - b);
|
|
9042
|
+
const runs = [];
|
|
9043
|
+
for (const index of indices) {
|
|
9044
|
+
const last = runs[runs.length - 1];
|
|
9045
|
+
if (last && last.start + last.span === index + 1) last.span += 1;
|
|
9046
|
+
else runs.push({ start: index + 1, span: 1 });
|
|
9047
|
+
}
|
|
9048
|
+
return runs;
|
|
9049
|
+
}
|
|
9050
|
+
function validateNoOverlap(doc) {
|
|
9051
|
+
const overlaps = [];
|
|
9052
|
+
const nodeCell = /* @__PURE__ */ new Map();
|
|
9053
|
+
for (const node of doc.nodes) {
|
|
9054
|
+
for (const column of columnsCovered(node)) {
|
|
9055
|
+
const key = `${column}:${node.order}`;
|
|
9056
|
+
const owner = nodeCell.get(key);
|
|
9057
|
+
if (owner !== void 0) {
|
|
9058
|
+
overlaps.push({ kind: "node", column, row: node.order, ids: [owner, node.id] });
|
|
9059
|
+
continue;
|
|
9060
|
+
}
|
|
9061
|
+
nodeCell.set(key, node.id);
|
|
9062
|
+
}
|
|
9063
|
+
}
|
|
9064
|
+
const groupCell = /* @__PURE__ */ new Map();
|
|
9065
|
+
for (const group of doc.groups) {
|
|
9066
|
+
if (group.from > group.to) continue;
|
|
9067
|
+
for (const column of resolveGroupColumns(group)) {
|
|
9068
|
+
for (let row = group.from; row <= group.to; row += 1) {
|
|
9069
|
+
const key = `${column}:${row}`;
|
|
9070
|
+
const owner = groupCell.get(key);
|
|
9071
|
+
if (owner !== void 0) {
|
|
9072
|
+
if (owner !== group.id) {
|
|
9073
|
+
overlaps.push({ kind: "group", column, row, ids: [owner, group.id] });
|
|
9074
|
+
}
|
|
9075
|
+
continue;
|
|
9076
|
+
}
|
|
9077
|
+
groupCell.set(key, group.id);
|
|
9078
|
+
}
|
|
9079
|
+
}
|
|
9080
|
+
}
|
|
9081
|
+
return overlaps;
|
|
9082
|
+
}
|
|
9083
|
+
function placeNodes(doc) {
|
|
9084
|
+
const byRow = nodesByRow(doc);
|
|
9085
|
+
const rows = rowsOf(doc);
|
|
9086
|
+
const placements = [];
|
|
9087
|
+
for (const row of rows) {
|
|
9088
|
+
for (const node of byRow.get(row) ?? []) {
|
|
9089
|
+
placements.push({
|
|
9090
|
+
node,
|
|
9091
|
+
row: { start: node.order + 1, span: 1 },
|
|
9092
|
+
column: gridColumnFor(node)
|
|
9093
|
+
});
|
|
9094
|
+
}
|
|
9095
|
+
}
|
|
9096
|
+
return { placements, rows, rowCount: maxRowOf(doc) + 1 };
|
|
9097
|
+
}
|
|
9098
|
+
function firstFreeRow(taken, columns, from) {
|
|
9099
|
+
let row = from;
|
|
9100
|
+
for (let guard = 0; guard < 1e5; guard += 1) {
|
|
9101
|
+
if (columns.every((column) => !taken.has(`${column}:${row}`))) return row;
|
|
9102
|
+
row += 1;
|
|
9103
|
+
}
|
|
9104
|
+
return row;
|
|
9105
|
+
}
|
|
9106
|
+
|
|
8640
9107
|
// src/hooks/use-iframe-auth.ts
|
|
8641
9108
|
var import_react7 = require("react");
|
|
8642
9109
|
function useIframeAuth() {
|
|
@@ -8774,7 +9241,14 @@ var useFeatureFlags = () => {
|
|
|
8774
9241
|
ContextMenuSubContent,
|
|
8775
9242
|
ContextMenuSubTrigger,
|
|
8776
9243
|
ContextMenuTrigger,
|
|
9244
|
+
DEFAULT_EDGE_ARROW,
|
|
9245
|
+
DEFAULT_EDGE_ROUTE,
|
|
9246
|
+
DEFAULT_EDGE_STYLE,
|
|
9247
|
+
DEFAULT_GROUP_TONE,
|
|
9248
|
+
DEFAULT_LEGEND_PLACEMENT,
|
|
8777
9249
|
DEFAULT_NAME_COL_WIDTH,
|
|
9250
|
+
DEFAULT_NODE_SPAN,
|
|
9251
|
+
DEFAULT_NODE_STATE,
|
|
8778
9252
|
DflRemote,
|
|
8779
9253
|
Dialog,
|
|
8780
9254
|
DialogClose,
|
|
@@ -8852,6 +9326,7 @@ var useFeatureFlags = () => {
|
|
|
8852
9326
|
MenubarSubContent,
|
|
8853
9327
|
MenubarSubTrigger,
|
|
8854
9328
|
MenubarTrigger,
|
|
9329
|
+
NODE_KIND_DEFAULT_TONE,
|
|
8855
9330
|
NavigationMenu,
|
|
8856
9331
|
NavigationMenuContent,
|
|
8857
9332
|
NavigationMenuIndicator,
|
|
@@ -8875,6 +9350,17 @@ var useFeatureFlags = () => {
|
|
|
8875
9350
|
Progress,
|
|
8876
9351
|
ProtectedRoute,
|
|
8877
9352
|
PublishDrawer,
|
|
9353
|
+
ROADMAP_ARROWS,
|
|
9354
|
+
ROADMAP_COLUMNS,
|
|
9355
|
+
ROADMAP_EDGE_LABEL_MAX,
|
|
9356
|
+
ROADMAP_EDGE_ROUTES,
|
|
9357
|
+
ROADMAP_EDGE_STYLES,
|
|
9358
|
+
ROADMAP_LABEL_MAX,
|
|
9359
|
+
ROADMAP_LEGEND_PLACEMENTS,
|
|
9360
|
+
ROADMAP_NODE_ID_PATTERN,
|
|
9361
|
+
ROADMAP_NODE_KINDS,
|
|
9362
|
+
ROADMAP_NODE_STATES,
|
|
9363
|
+
ROADMAP_TONES,
|
|
8878
9364
|
RadioGroup,
|
|
8879
9365
|
RadioGroupItem,
|
|
8880
9366
|
RadioGroupRow,
|
|
@@ -8968,19 +9454,55 @@ var useFeatureFlags = () => {
|
|
|
8968
9454
|
buttonVariants,
|
|
8969
9455
|
clampPct,
|
|
8970
9456
|
cn,
|
|
9457
|
+
columnIndex,
|
|
9458
|
+
columnsCovered,
|
|
9459
|
+
columnsUsed,
|
|
8971
9460
|
filterPublishableAccounts,
|
|
9461
|
+
firstFreeRow,
|
|
8972
9462
|
getInitials,
|
|
9463
|
+
gridColumnFor,
|
|
9464
|
+
groupColumnRuns,
|
|
9465
|
+
groupRanges,
|
|
8973
9466
|
iconButtonVariants,
|
|
8974
9467
|
isAllowedOrigin,
|
|
8975
9468
|
kbdVariants,
|
|
8976
9469
|
labelVariants,
|
|
9470
|
+
maxRowOf,
|
|
8977
9471
|
memberHueIndex,
|
|
8978
9472
|
memberHueVar,
|
|
8979
9473
|
navigationMenuTriggerStyle,
|
|
9474
|
+
nodesByRow,
|
|
9475
|
+
parseRoadmapDocument,
|
|
9476
|
+
parseRoadmapStateOverlay,
|
|
8980
9477
|
parseTags,
|
|
9478
|
+
placeNodes,
|
|
9479
|
+
resolveEdgeArrow,
|
|
9480
|
+
resolveEdgeRoute,
|
|
9481
|
+
resolveEdgeStyle,
|
|
9482
|
+
resolveGroupColumns,
|
|
9483
|
+
resolveGroupTone,
|
|
9484
|
+
resolveLegendPlacement,
|
|
8981
9485
|
resolveNameColWidth,
|
|
9486
|
+
resolveNodeSpan,
|
|
9487
|
+
resolveNodeState,
|
|
9488
|
+
resolveNodeTone,
|
|
8982
9489
|
resolveWeekCount,
|
|
8983
9490
|
resolveWeekLabels,
|
|
9491
|
+
roadmapActionSchema,
|
|
9492
|
+
roadmapDocumentSchema,
|
|
9493
|
+
roadmapEdgeSchema,
|
|
9494
|
+
roadmapGroupSchema,
|
|
9495
|
+
roadmapIconSchema,
|
|
9496
|
+
roadmapLegendEntrySchema,
|
|
9497
|
+
roadmapLegendSchema,
|
|
9498
|
+
roadmapLinkSchema,
|
|
9499
|
+
roadmapNodeSchema,
|
|
9500
|
+
roadmapNodeStateSchema,
|
|
9501
|
+
roadmapStateOverlaySchema,
|
|
9502
|
+
roadmapStateSchema,
|
|
9503
|
+
rowsOf,
|
|
9504
|
+
safeParseRoadmapDocument,
|
|
9505
|
+
safeParseRoadmapStateOverlay,
|
|
8984
9506
|
stageProgress,
|
|
8985
9507
|
toast,
|
|
8986
9508
|
toggleVariants,
|
|
@@ -8994,5 +9516,6 @@ var useFeatureFlags = () => {
|
|
|
8994
9516
|
useSession,
|
|
8995
9517
|
useSidebar,
|
|
8996
9518
|
useToast,
|
|
9519
|
+
validateNoOverlap,
|
|
8997
9520
|
validatePublishForm
|
|
8998
9521
|
});
|