@sascha384/tic 5.15.1 → 5.17.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/.claude-plugin/plugin.json +1 -1
- package/dist/backends/ado/index.js +1 -1
- package/dist/backends/ado/index.js.map +1 -1
- package/dist/backends/ado/mappers.d.ts +2 -2
- package/dist/backends/ado/mappers.js +7 -2
- package/dist/backends/ado/mappers.js.map +1 -1
- package/dist/backends/files/index.d.ts +6 -0
- package/dist/backends/files/index.js +36 -0
- package/dist/backends/files/index.js.map +1 -1
- package/dist/backends/files/sync.d.ts +2 -2
- package/dist/backends/files/sync.js +9 -7
- package/dist/backends/files/sync.js.map +1 -1
- package/dist/backends/github/index.js +3 -3
- package/dist/backends/github/index.js.map +1 -1
- package/dist/backends/github/mappers.js +2 -1
- package/dist/backends/github/mappers.js.map +1 -1
- package/dist/backends/github/pr-mappers.d.ts +1 -1
- package/dist/backends/github/pr-mappers.js +1 -1
- package/dist/backends/github/pr-mappers.js.map +1 -1
- package/dist/backends/gitlab/index.js +13 -6
- package/dist/backends/gitlab/index.js.map +1 -1
- package/dist/backends/gitlab/mappers.js +2 -1
- package/dist/backends/gitlab/mappers.js.map +1 -1
- package/dist/backends/jira/index.js +2 -2
- package/dist/backends/jira/index.js.map +1 -1
- package/dist/backends/jira/mappers.d.ts +1 -1
- package/dist/backends/jira/mappers.js +5 -4
- package/dist/backends/jira/mappers.js.map +1 -1
- package/dist/backends/local/items.js +9 -2
- package/dist/backends/local/items.js.map +1 -1
- package/dist/backends/shared/api-client.js +9 -1
- package/dist/backends/shared/api-client.js.map +1 -1
- package/dist/backends/types.d.ts +2 -3
- package/dist/backends/types.js +8 -2
- package/dist/backends/types.js.map +1 -1
- package/dist/cli/commands/config.js +0 -1
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/item.js +45 -17
- package/dist/cli/commands/item.js.map +1 -1
- package/dist/cli/commands/mcp.js +24 -9
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/pr.js +12 -6
- package/dist/cli/commands/pr.js.map +1 -1
- package/dist/cli/index.js +13 -6
- package/dist/cli/index.js.map +1 -1
- package/dist/components/AuthPrompt.js +1 -1
- package/dist/components/AutocompleteInput.js +1 -1
- package/dist/components/BranchList.js +4 -2
- package/dist/components/BranchList.js.map +1 -1
- package/dist/components/CommandBar.js +8 -7
- package/dist/components/CommandBar.js.map +1 -1
- package/dist/components/DetailPanel.js +2 -2
- package/dist/components/DetailPanel.js.map +1 -1
- package/dist/components/MarkdownEditor.js +9 -5
- package/dist/components/MarkdownEditor.js.map +1 -1
- package/dist/components/MultiAutocompleteInput.js +1 -1
- package/dist/components/MultiSelectInput.js +1 -1
- package/dist/components/OverlayPanel.js +1 -1
- package/dist/components/Settings.js +2 -2
- package/dist/components/Settings.js.map +1 -1
- package/dist/components/StatusScreen.js +2 -2
- package/dist/components/StatusScreen.js.map +1 -1
- package/dist/components/TextInput.d.ts +12 -0
- package/dist/components/TextInput.js +207 -0
- package/dist/components/TextInput.js.map +1 -0
- package/dist/components/WorkItemForm.js +115 -98
- package/dist/components/WorkItemForm.js.map +1 -1
- package/dist/components/WorkItemList.d.ts +5 -3
- package/dist/components/WorkItemList.js +187 -123
- package/dist/components/WorkItemList.js.map +1 -1
- package/dist/components/buildTree.js +15 -13
- package/dist/components/buildTree.js.map +1 -1
- package/dist/components/fuzzyMatch.js +1 -1
- package/dist/components/fuzzyMatch.js.map +1 -1
- package/dist/components/getMarkedDistribution.d.ts +2 -2
- package/dist/components/getMarkedDistribution.js +1 -1
- package/dist/components/getMarkedDistribution.js.map +1 -1
- package/dist/git.d.ts +2 -1
- package/dist/hooks/useFormValidation.js +31 -21
- package/dist/hooks/useFormValidation.js.map +1 -1
- package/dist/hooks/useForwardDelete.d.ts +10 -0
- package/dist/hooks/useForwardDelete.js +34 -0
- package/dist/hooks/useForwardDelete.js.map +1 -0
- package/dist/implement.js +3 -3
- package/dist/implement.js.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/storage/config.d.ts +0 -1
- package/dist/storage/config.js +0 -6
- package/dist/storage/config.js.map +1 -1
- package/dist/storage/index.d.ts +25 -6
- package/dist/storage/index.js +304 -183
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/mappers.d.ts +1 -1
- package/dist/storage/mappers.js +5 -3
- package/dist/storage/mappers.js.map +1 -1
- package/dist/storage/schema.d.ts +83 -380
- package/dist/storage/schema.js +27 -55
- package/dist/storage/schema.js.map +1 -1
- package/dist/storage/syncQueue.d.ts +2 -3
- package/dist/storage/syncQueue.js +10 -17
- package/dist/storage/syncQueue.js.map +1 -1
- package/dist/storage/undo.js +7 -6
- package/dist/storage/undo.js.map +1 -1
- package/dist/stores/backendDataStore.js +3 -1
- package/dist/stores/backendDataStore.js.map +1 -1
- package/dist/stores/formStackStore.d.ts +1 -1
- package/dist/stores/listViewStore.d.ts +6 -6
- package/dist/stores/navigationStore.d.ts +7 -7
- package/dist/stores/undoStore.d.ts +2 -2
- package/dist/sync/SyncManager.d.ts +6 -1
- package/dist/sync/SyncManager.js +80 -76
- package/dist/sync/SyncManager.js.map +1 -1
- package/dist/sync/types.d.ts +6 -7
- package/dist/test-helpers.d.ts +1 -1
- package/dist/test-helpers.js +11 -8
- package/dist/test-helpers.js.map +1 -1
- package/dist/types.d.ts +6 -5
- package/drizzle/0006_dual_id.sql +173 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextInput.js","sourceRoot":"","sources":["../../src/components/TextInput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState, useMemo, useEffect } from 'react';
|
|
3
3
|
import { Box, Text, useInput } from 'ink';
|
|
4
|
-
import TextInput from '
|
|
4
|
+
import TextInput from './TextInput.js';
|
|
5
5
|
import SelectInput from 'ink-select-input';
|
|
6
6
|
import { AutocompleteInput } from './AutocompleteInput.js';
|
|
7
7
|
import { MultiSelectInput } from './MultiSelectInput.js';
|
|
@@ -54,11 +54,21 @@ export function WorkItemForm() {
|
|
|
54
54
|
popWorkItem: s.popWorkItem,
|
|
55
55
|
})));
|
|
56
56
|
const queue = useBackendDataStore((s) => s.queue);
|
|
57
|
-
|
|
57
|
+
/** Look up the rowId for a display ID. Returns -1 if not found. */
|
|
58
|
+
const rowIdOf = (displayId) => {
|
|
59
|
+
const item = allItems.find((i) => i.id === displayId);
|
|
60
|
+
return item?.rowId ?? -1;
|
|
61
|
+
};
|
|
62
|
+
/** Look up the display ID for a rowId. Returns null if not found. */
|
|
63
|
+
const displayIdOf = (rowId) => {
|
|
64
|
+
const item = allItems.find((i) => i.rowId === rowId);
|
|
65
|
+
return item?.id ?? null;
|
|
66
|
+
};
|
|
67
|
+
const queueWrite = async (action, itemRowId, extra) => {
|
|
58
68
|
if (queue) {
|
|
59
69
|
await queue.append({
|
|
60
70
|
action,
|
|
61
|
-
|
|
71
|
+
itemRowId,
|
|
62
72
|
timestamp: new Date().toISOString(),
|
|
63
73
|
...(extra?.commentData ? { commentData: extra.commentData } : {}),
|
|
64
74
|
...(extra?.templateSlug ? { templateSlug: extra.templateSlug } : {}),
|
|
@@ -97,16 +107,24 @@ export function WorkItemForm() {
|
|
|
97
107
|
}
|
|
98
108
|
let cancelled = false;
|
|
99
109
|
setItemLoading(true);
|
|
110
|
+
const displayId = displayIdOf(selectedWorkItemId);
|
|
111
|
+
if (!displayId) {
|
|
112
|
+
setItemLoading(false);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
100
115
|
void (async () => {
|
|
101
116
|
try {
|
|
102
|
-
const item = await backend.getWorkItem(
|
|
117
|
+
const item = await backend.getWorkItem(displayId);
|
|
103
118
|
const [ch, dep] = capabilities.relationships
|
|
104
119
|
? await Promise.all([
|
|
105
|
-
backend.getChildren(
|
|
106
|
-
backend.getDependents(
|
|
120
|
+
backend.getChildren(displayId),
|
|
121
|
+
backend.getDependents(displayId),
|
|
107
122
|
])
|
|
108
123
|
: [[], []];
|
|
109
|
-
const
|
|
124
|
+
const parentDisplayId = item.parent !== null ? displayIdOf(item.parent) : null;
|
|
125
|
+
const pi = parentDisplayId
|
|
126
|
+
? await backend.getWorkItem(parentDisplayId)
|
|
127
|
+
: null;
|
|
110
128
|
if (cancelled)
|
|
111
129
|
return;
|
|
112
130
|
setExistingItem(item);
|
|
@@ -180,10 +198,10 @@ export function WorkItemForm() {
|
|
|
180
198
|
all.push('rel-parent');
|
|
181
199
|
}
|
|
182
200
|
for (const child of children) {
|
|
183
|
-
all.push(`rel-child-${child.
|
|
201
|
+
all.push(`rel-child-${child.rowId}`);
|
|
184
202
|
}
|
|
185
203
|
for (const dep of dependents) {
|
|
186
|
-
all.push(`rel-dependent-${dep.
|
|
204
|
+
all.push(`rel-dependent-${dep.rowId}`);
|
|
187
205
|
}
|
|
188
206
|
}
|
|
189
207
|
return all;
|
|
@@ -205,7 +223,9 @@ export function WorkItemForm() {
|
|
|
205
223
|
return required;
|
|
206
224
|
}, [selectedWorkItemId, capabilities.customTypes]);
|
|
207
225
|
const requiredFieldsList = useMemo(() => capabilities.requiredFields ?? [...requiredFields], [capabilities.requiredFields, requiredFields]);
|
|
208
|
-
|
|
226
|
+
// Convert selectedWorkItemId (rowId) to display ID for validation
|
|
227
|
+
const selectedDisplayId = selectedWorkItemId !== null ? displayIdOf(selectedWorkItemId) : null;
|
|
228
|
+
const { errors: validationErrors, validate, clearError, } = useFormValidation(allItems, selectedDisplayId, requiredFieldsList);
|
|
209
229
|
const [comments, setComments] = useState([]);
|
|
210
230
|
// Derive field values from current draft
|
|
211
231
|
const title = currentDraft?.fields.title ?? '';
|
|
@@ -248,6 +268,15 @@ export function WorkItemForm() {
|
|
|
248
268
|
useEffect(() => {
|
|
249
269
|
if (formStackStore.getState().stack.length > 0)
|
|
250
270
|
return; // Already has a draft
|
|
271
|
+
// Check for create-child prefill
|
|
272
|
+
const { createChildParentId, setCreateChildParentId } = navigationStore.getState();
|
|
273
|
+
let parentId = '';
|
|
274
|
+
if (selectedWorkItemId === null && createChildParentId) {
|
|
275
|
+
const parent = allItems.find((i) => i.rowId === createChildParentId);
|
|
276
|
+
const displayId = parent?.id ?? String(createChildParentId);
|
|
277
|
+
parentId = parent ? `#${displayId} - ${parent.title}` : `#${displayId}`;
|
|
278
|
+
setCreateChildParentId(null);
|
|
279
|
+
}
|
|
251
280
|
const initialFields = {
|
|
252
281
|
title: '',
|
|
253
282
|
type: activeType ?? types[0] ?? '',
|
|
@@ -257,46 +286,21 @@ export function WorkItemForm() {
|
|
|
257
286
|
assignee: '',
|
|
258
287
|
labels: '',
|
|
259
288
|
description: '',
|
|
260
|
-
parentId
|
|
289
|
+
parentId,
|
|
261
290
|
dependsOn: '',
|
|
262
291
|
newComment: '',
|
|
263
292
|
};
|
|
264
293
|
const draft = {
|
|
265
294
|
itemId: selectedWorkItemId,
|
|
266
|
-
itemTitle: selectedWorkItemId
|
|
295
|
+
itemTitle: selectedWorkItemId
|
|
296
|
+
? `#${selectedDisplayId ?? selectedWorkItemId}`
|
|
297
|
+
: '(new)',
|
|
267
298
|
fields: initialFields,
|
|
268
299
|
initialSnapshot: { ...initialFields },
|
|
269
300
|
focusedField: 0,
|
|
270
301
|
};
|
|
271
302
|
pushDraft(draft);
|
|
272
303
|
}, []); // Only on mount
|
|
273
|
-
// Prefill parent for create-child (create mode only)
|
|
274
|
-
useEffect(() => {
|
|
275
|
-
if (selectedWorkItemId !== null)
|
|
276
|
-
return;
|
|
277
|
-
const { createChildParentId, setCreateChildParentId } = navigationStore.getState();
|
|
278
|
-
if (!createChildParentId)
|
|
279
|
-
return;
|
|
280
|
-
const parentItem = allItems.find((i) => i.id === createChildParentId);
|
|
281
|
-
const parentDisplay = parentItem
|
|
282
|
-
? `#${createChildParentId} - ${parentItem.title}`
|
|
283
|
-
: `#${createChildParentId}`;
|
|
284
|
-
updateFields({ parentId: parentDisplay });
|
|
285
|
-
// Update initialSnapshot so parent doesn't count as dirty
|
|
286
|
-
formStackStore.setState((state) => {
|
|
287
|
-
if (state.stack.length === 0)
|
|
288
|
-
return state;
|
|
289
|
-
const updated = [...state.stack];
|
|
290
|
-
const current = updated[updated.length - 1];
|
|
291
|
-
updated[updated.length - 1] = {
|
|
292
|
-
...current,
|
|
293
|
-
initialSnapshot: { ...current.fields, parentId: parentDisplay },
|
|
294
|
-
};
|
|
295
|
-
return { stack: updated };
|
|
296
|
-
});
|
|
297
|
-
// Clear after use
|
|
298
|
-
setCreateChildParentId(null);
|
|
299
|
-
}, [selectedWorkItemId, allItems]);
|
|
300
304
|
// Sync form fields when the existing item finishes loading
|
|
301
305
|
useEffect(() => {
|
|
302
306
|
if (!existingItem)
|
|
@@ -308,16 +312,20 @@ export function WorkItemForm() {
|
|
|
308
312
|
// Build field values
|
|
309
313
|
const parentIdValue = existingItem.parent !== null && existingItem.parent !== undefined
|
|
310
314
|
? (() => {
|
|
311
|
-
const pi = allItems.find((i) => i.
|
|
315
|
+
const pi = allItems.find((i) => i.rowId === existingItem.parent);
|
|
316
|
+
const parentDisplayId = pi?.id ?? String(existingItem.parent);
|
|
312
317
|
return pi
|
|
313
|
-
? `#${
|
|
318
|
+
? `#${parentDisplayId} - ${pi.title}`
|
|
314
319
|
: String(existingItem.parent);
|
|
315
320
|
})()
|
|
316
321
|
: '';
|
|
317
322
|
const dependsOnValue = existingItem.dependsOn
|
|
318
|
-
?.map((
|
|
319
|
-
const depItem = allItems.find((i) => i.
|
|
320
|
-
|
|
323
|
+
?.map((depRowId) => {
|
|
324
|
+
const depItem = allItems.find((i) => i.rowId === depRowId);
|
|
325
|
+
const depDisplayId = depItem?.id ?? String(depRowId);
|
|
326
|
+
return depItem
|
|
327
|
+
? `#${depDisplayId} - ${depItem.title}`
|
|
328
|
+
: String(depRowId);
|
|
321
329
|
})
|
|
322
330
|
.join(', ') ?? '';
|
|
323
331
|
const newFields = {
|
|
@@ -420,7 +428,7 @@ export function WorkItemForm() {
|
|
|
420
428
|
}, [formMode, editingTemplateSlug, backend]);
|
|
421
429
|
const parentSuggestions = useMemo(() => {
|
|
422
430
|
return allItems
|
|
423
|
-
.filter((item) => item.id !==
|
|
431
|
+
.filter((item) => item.rowId !== selectedWorkItemId && item.id !== null)
|
|
424
432
|
.map((item) => `#${item.id} - ${item.title}`);
|
|
425
433
|
}, [allItems, selectedWorkItemId]);
|
|
426
434
|
const [editing, setEditing] = useState(false);
|
|
@@ -448,23 +456,26 @@ export function WorkItemForm() {
|
|
|
448
456
|
.split(',')
|
|
449
457
|
.map((l) => l.trim())
|
|
450
458
|
.filter((l) => l.length > 0);
|
|
459
|
+
// Parse display IDs from form fields and resolve to rowIds
|
|
451
460
|
const parsedParent = (() => {
|
|
452
461
|
const trimmed = parentId.trim();
|
|
453
462
|
if (!trimmed)
|
|
454
463
|
return null;
|
|
455
464
|
const match = trimmed.match(/^#(\S+)\s*-\s/);
|
|
456
|
-
|
|
465
|
+
const displayId = match ? match[1] : trimmed;
|
|
466
|
+
return rowIdOf(displayId);
|
|
457
467
|
})();
|
|
458
468
|
const parsedDependsOn = dependsOn
|
|
459
469
|
.split(',')
|
|
460
470
|
.map((s) => {
|
|
461
471
|
const trimmed = s.trim();
|
|
462
472
|
if (!trimmed)
|
|
463
|
-
return
|
|
473
|
+
return -1;
|
|
464
474
|
const match = trimmed.match(/^#(\S+)\s*-\s/);
|
|
465
|
-
|
|
475
|
+
const displayId = match ? match[1] : trimmed;
|
|
476
|
+
return rowIdOf(displayId);
|
|
466
477
|
})
|
|
467
|
-
.filter((
|
|
478
|
+
.filter((rowId) => rowId !== -1);
|
|
468
479
|
if (formMode === 'template') {
|
|
469
480
|
const template = {
|
|
470
481
|
slug: editingTemplateSlug ?? slugifyTemplateName(title),
|
|
@@ -484,19 +495,23 @@ export function WorkItemForm() {
|
|
|
484
495
|
template.iteration = iteration;
|
|
485
496
|
if (description)
|
|
486
497
|
template.description = description;
|
|
487
|
-
if (parsedParent)
|
|
488
|
-
template.parent = parsedParent;
|
|
489
|
-
|
|
490
|
-
|
|
498
|
+
if (parsedParent !== null) {
|
|
499
|
+
template.parent = displayIdOf(parsedParent);
|
|
500
|
+
}
|
|
501
|
+
if (parsedDependsOn.length > 0) {
|
|
502
|
+
template.dependsOn = parsedDependsOn
|
|
503
|
+
.map((rid) => displayIdOf(rid))
|
|
504
|
+
.filter((id) => id !== null);
|
|
505
|
+
}
|
|
491
506
|
if (editingTemplateSlug) {
|
|
492
507
|
await backend.updateTemplate(editingTemplateSlug, template);
|
|
493
|
-
await queueWrite('template-update',
|
|
508
|
+
await queueWrite('template-update', 0, {
|
|
494
509
|
templateSlug: template.slug,
|
|
495
510
|
});
|
|
496
511
|
}
|
|
497
512
|
else {
|
|
498
513
|
await backend.createTemplate(template);
|
|
499
|
-
await queueWrite('template-create',
|
|
514
|
+
await queueWrite('template-create', 0, {
|
|
500
515
|
templateSlug: template.slug,
|
|
501
516
|
});
|
|
502
517
|
}
|
|
@@ -505,9 +520,9 @@ export function WorkItemForm() {
|
|
|
505
520
|
setEditingTemplateSlug(null);
|
|
506
521
|
return;
|
|
507
522
|
}
|
|
508
|
-
if (selectedWorkItemId !== null) {
|
|
509
|
-
const snapshot = await backend.getWorkItem(
|
|
510
|
-
await backend.cachedUpdateWorkItem(
|
|
523
|
+
if (selectedWorkItemId !== null && selectedDisplayId) {
|
|
524
|
+
const snapshot = await backend.getWorkItem(selectedDisplayId);
|
|
525
|
+
await backend.cachedUpdateWorkItem(selectedDisplayId, {
|
|
511
526
|
title,
|
|
512
527
|
type,
|
|
513
528
|
status,
|
|
@@ -522,13 +537,13 @@ export function WorkItemForm() {
|
|
|
522
537
|
await queueWrite('update', selectedWorkItemId);
|
|
523
538
|
undoStore.getState().pushUndo({
|
|
524
539
|
type: 'update',
|
|
525
|
-
label: `edited #${
|
|
540
|
+
label: `edited #${selectedDisplayId}`,
|
|
526
541
|
itemSnapshots: [snapshot],
|
|
527
|
-
|
|
542
|
+
syncItemRowIds: [selectedWorkItemId],
|
|
528
543
|
syncAction: 'update',
|
|
529
544
|
});
|
|
530
545
|
if (capabilities.comments && newComment.trim().length > 0) {
|
|
531
|
-
const added = await backend.addComment(
|
|
546
|
+
const added = await backend.addComment(selectedDisplayId, {
|
|
532
547
|
author: 'me',
|
|
533
548
|
body: newComment.trim(),
|
|
534
549
|
});
|
|
@@ -538,10 +553,10 @@ export function WorkItemForm() {
|
|
|
538
553
|
setComments((prev) => [...prev, added]);
|
|
539
554
|
setNewComment('');
|
|
540
555
|
}
|
|
541
|
-
await backendDataStore.getState().reloadItem(
|
|
556
|
+
await backendDataStore.getState().reloadItem(selectedDisplayId);
|
|
542
557
|
uiStore
|
|
543
558
|
.getState()
|
|
544
|
-
.setToast(`Item #${
|
|
559
|
+
.setToast(`Item #${selectedDisplayId} updated — press u to undo`);
|
|
545
560
|
}
|
|
546
561
|
else {
|
|
547
562
|
const created = await backend.cachedCreateWorkItem({
|
|
@@ -556,28 +571,30 @@ export function WorkItemForm() {
|
|
|
556
571
|
parent: parsedParent,
|
|
557
572
|
dependsOn: parsedDependsOn,
|
|
558
573
|
});
|
|
559
|
-
await queueWrite('create', created.
|
|
574
|
+
await queueWrite('create', created.rowId);
|
|
560
575
|
undoStore.getState().pushUndo({
|
|
561
576
|
type: 'create',
|
|
562
|
-
label: `created #${created.id}`,
|
|
577
|
+
label: `created #${created.id ?? created.rowId}`,
|
|
563
578
|
itemSnapshots: [],
|
|
564
|
-
|
|
579
|
+
syncItemRowIds: [created.rowId],
|
|
565
580
|
syncAction: 'create',
|
|
566
|
-
|
|
581
|
+
createdRowIds: [created.rowId],
|
|
567
582
|
});
|
|
568
|
-
if (capabilities.comments && newComment.trim().length > 0) {
|
|
583
|
+
if (capabilities.comments && newComment.trim().length > 0 && created.id) {
|
|
569
584
|
await backend.addComment(created.id, {
|
|
570
585
|
author: 'me',
|
|
571
586
|
body: newComment.trim(),
|
|
572
587
|
});
|
|
573
|
-
await queueWrite('comment', created.
|
|
588
|
+
await queueWrite('comment', created.rowId, {
|
|
574
589
|
commentData: { author: 'me', body: newComment.trim() },
|
|
575
590
|
});
|
|
576
591
|
}
|
|
577
|
-
|
|
592
|
+
if (created.id) {
|
|
593
|
+
await backendDataStore.getState().reloadItem(created.id);
|
|
594
|
+
}
|
|
578
595
|
uiStore
|
|
579
596
|
.getState()
|
|
580
|
-
.setToast(`Item #${created.id} created — press u to undo`);
|
|
597
|
+
.setToast(`Item #${created.id ?? created.rowId} created — press u to undo`);
|
|
581
598
|
setActiveTemplate(null);
|
|
582
599
|
}
|
|
583
600
|
// Update the initialSnapshot after saving so isDirty becomes false
|
|
@@ -609,7 +626,7 @@ export function WorkItemForm() {
|
|
|
609
626
|
await save();
|
|
610
627
|
if (pendingRelNav) {
|
|
611
628
|
// Push a new draft for the target item
|
|
612
|
-
const targetItem = allItems.find((i) => i.
|
|
629
|
+
const targetItem = allItems.find((i) => i.rowId === pendingRelNav);
|
|
613
630
|
const defaultFields = {
|
|
614
631
|
title: '',
|
|
615
632
|
type: activeType ?? types[0] ?? '',
|
|
@@ -625,7 +642,7 @@ export function WorkItemForm() {
|
|
|
625
642
|
};
|
|
626
643
|
const newDraft = {
|
|
627
644
|
itemId: pendingRelNav,
|
|
628
|
-
itemTitle: targetItem?.title ?? `#${pendingRelNav}`,
|
|
645
|
+
itemTitle: targetItem?.title ?? `#${targetItem?.id ?? pendingRelNav}`,
|
|
629
646
|
fields: defaultFields,
|
|
630
647
|
initialSnapshot: { ...defaultFields },
|
|
631
648
|
focusedField: 0,
|
|
@@ -659,7 +676,7 @@ export function WorkItemForm() {
|
|
|
659
676
|
if (pendingRelNav) {
|
|
660
677
|
// Push a new draft for the target item (discarding current)
|
|
661
678
|
formStackStore.getState().pop();
|
|
662
|
-
const targetItem = allItems.find((i) => i.
|
|
679
|
+
const targetItem = allItems.find((i) => i.rowId === pendingRelNav);
|
|
663
680
|
const defaultFields = {
|
|
664
681
|
title: '',
|
|
665
682
|
type: activeType ?? types[0] ?? '',
|
|
@@ -675,7 +692,7 @@ export function WorkItemForm() {
|
|
|
675
692
|
};
|
|
676
693
|
const newDraft = {
|
|
677
694
|
itemId: pendingRelNav,
|
|
678
|
-
itemTitle: targetItem?.title ?? `#${pendingRelNav}`,
|
|
695
|
+
itemTitle: targetItem?.title ?? `#${targetItem?.id ?? pendingRelNav}`,
|
|
679
696
|
fields: defaultFields,
|
|
680
697
|
initialSnapshot: { ...defaultFields },
|
|
681
698
|
focusedField: 0,
|
|
@@ -807,24 +824,24 @@ export function WorkItemForm() {
|
|
|
807
824
|
}
|
|
808
825
|
if (matchesCommand('form-edit', _input, key)) {
|
|
809
826
|
if (isRelationshipField) {
|
|
810
|
-
let
|
|
827
|
+
let targetRowId = null;
|
|
811
828
|
if (currentField === 'rel-parent' && existingItem?.parent) {
|
|
812
|
-
|
|
829
|
+
targetRowId = existingItem.parent;
|
|
813
830
|
}
|
|
814
831
|
else if (currentField.startsWith('rel-child-')) {
|
|
815
|
-
|
|
832
|
+
targetRowId = Number(currentField.slice('rel-child-'.length));
|
|
816
833
|
}
|
|
817
834
|
else if (currentField.startsWith('rel-dependent-')) {
|
|
818
|
-
|
|
835
|
+
targetRowId = Number(currentField.slice('rel-dependent-'.length));
|
|
819
836
|
}
|
|
820
|
-
if (
|
|
837
|
+
if (targetRowId) {
|
|
821
838
|
if (isDirty) {
|
|
822
|
-
setPendingRelNav(
|
|
839
|
+
setPendingRelNav(targetRowId);
|
|
823
840
|
setShowDirtyPrompt(true);
|
|
824
841
|
}
|
|
825
842
|
else {
|
|
826
843
|
// Create new draft for target item before navigating
|
|
827
|
-
const targetItem = allItems.find((i) => i.
|
|
844
|
+
const targetItem = allItems.find((i) => i.rowId === targetRowId);
|
|
828
845
|
const defaultFields = {
|
|
829
846
|
title: '',
|
|
830
847
|
type: activeType ?? types[0] ?? '',
|
|
@@ -839,14 +856,14 @@ export function WorkItemForm() {
|
|
|
839
856
|
newComment: '',
|
|
840
857
|
};
|
|
841
858
|
const newDraft = {
|
|
842
|
-
itemId:
|
|
843
|
-
itemTitle: targetItem?.title ?? `#${
|
|
859
|
+
itemId: targetRowId,
|
|
860
|
+
itemTitle: targetItem?.title ?? `#${targetItem?.id ?? targetRowId}`,
|
|
844
861
|
fields: defaultFields,
|
|
845
862
|
initialSnapshot: { ...defaultFields },
|
|
846
863
|
focusedField: 0,
|
|
847
864
|
};
|
|
848
865
|
pushDraft(newDraft);
|
|
849
|
-
pushWorkItem(
|
|
866
|
+
pushWorkItem(targetRowId);
|
|
850
867
|
}
|
|
851
868
|
}
|
|
852
869
|
}
|
|
@@ -1106,24 +1123,24 @@ export function WorkItemForm() {
|
|
|
1106
1123
|
function renderRelationshipField(field, index) {
|
|
1107
1124
|
const focused = index === focusedField;
|
|
1108
1125
|
const cursor = focused ? '>' : ' ';
|
|
1109
|
-
const
|
|
1110
|
-
? field.slice('rel-child-'.length)
|
|
1126
|
+
const rowId = field.startsWith('rel-child-')
|
|
1127
|
+
? Number(field.slice('rel-child-'.length))
|
|
1111
1128
|
: field.startsWith('rel-dependent-')
|
|
1112
|
-
? field.slice('rel-dependent-'.length)
|
|
1129
|
+
? Number(field.slice('rel-dependent-'.length))
|
|
1113
1130
|
: null;
|
|
1114
|
-
let
|
|
1131
|
+
let relItem = null;
|
|
1115
1132
|
if (field === 'rel-parent' && parentItem) {
|
|
1116
|
-
|
|
1133
|
+
relItem = parentItem;
|
|
1117
1134
|
}
|
|
1118
|
-
else if (
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1135
|
+
else if (rowId !== null) {
|
|
1136
|
+
relItem =
|
|
1137
|
+
children.find((c) => c.rowId === rowId) ??
|
|
1138
|
+
dependents.find((d) => d.rowId === rowId) ??
|
|
1139
|
+
null;
|
|
1123
1140
|
}
|
|
1124
|
-
if (!
|
|
1141
|
+
if (!relItem)
|
|
1125
1142
|
return null;
|
|
1126
|
-
return (_jsxs(Box, { children: [_jsxs(Text, { color: focused ? accent : undefined, children: [cursor, " "] }), _jsxs(Text, { bold: focused, color: focused ? accent : undefined, children: ["#",
|
|
1143
|
+
return (_jsxs(Box, { children: [_jsxs(Text, { color: focused ? accent : undefined, children: [cursor, " "] }), _jsxs(Text, { bold: focused, color: focused ? accent : undefined, children: ["#", relItem.id ?? relItem.rowId, " (", relItem.title, ")"] })] }, field));
|
|
1127
1144
|
}
|
|
1128
1145
|
const formStackLength = useFormStackStore((s) => s.stack.length);
|
|
1129
1146
|
const chromeLines = useMemo(() => {
|
|
@@ -1168,7 +1185,7 @@ export function WorkItemForm() {
|
|
|
1168
1185
|
const typeLabel = formMode === 'template' ? '' : type.charAt(0).toUpperCase() + type.slice(1);
|
|
1169
1186
|
const isFieldVisible = (index) => index >= viewport.start && index < viewport.end;
|
|
1170
1187
|
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: accent, children: [mode, typeLabel ? ` ${typeLabel}` : '', formMode !== 'template' && selectedWorkItemId !== null
|
|
1171
|
-
? ` #${selectedWorkItemId}`
|
|
1188
|
+
? ` #${selectedDisplayId ?? selectedWorkItemId}`
|
|
1172
1189
|
: ''] }) }), _jsx(Breadcrumbs, {}), fields.map((field, index) => {
|
|
1173
1190
|
if (field === 'rel-parent' ||
|
|
1174
1191
|
field.startsWith('rel-child-') ||
|