Files
Agent-System/web/src/lib/workflowCategoryNavigation.ts
T
weichenandCursor ba4bb41e1c fix(e2e): switch to workflow category before opening controlled docs
UI-13a stayed on private after upload, so the doc menu had no
doc_proj* entries. Always use the category trigger first, then exact id.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 21:03:23 +00:00

58 lines
2.0 KiB
TypeScript

export type DeliverableCategory = 'workflow' | 'shared' | 'private';
export const CATEGORY_TRIGGER_LABEL: Record<DeliverableCategory, string> = {
workflow: '流程受控',
shared: '项目共享',
private: '我的私密',
};
export type DocOpenIntent =
| { kind: 'exact-id'; docId: string }
| { kind: 'controlled-task-key'; taskKey: string }
| { kind: 'workflow-label' };
export type DocSelectorStep =
| { action: 'ensure_category'; category: DeliverableCategory }
| { action: 'select_exact'; docId: string }
| { action: 'fail'; reason: string };
const CONTROLLED_DOC_ID = /^doc_proj\d+_[a-z][a-z0-9_]*$/;
export function requiredCategoryForDocOpen(intent: DocOpenIntent): DeliverableCategory {
if (intent.kind === 'workflow-label' || intent.kind === 'controlled-task-key') {
return 'workflow';
}
const docId = intent.docId.trim();
if (CONTROLLED_DOC_ID.test(docId)) {
return 'workflow';
}
if (docId.startsWith('doc-free-')) {
return 'private';
}
throw new Error(`cannot infer deliverable category for ${JSON.stringify(docId)}`);
}
/**
* Plan the real UI sequence: always ensure the target category via the category
* trigger, then select by exact data-doc-id from that category's menu.
* A private (or other) menu missing doc_proj* is not a failure until after switch.
*/
export function planExactDocOpen(input: {
currentCategory: DeliverableCategory;
visibleMenuDocIds: string[];
targetDocId: string;
}): DocSelectorStep[] {
const category = requiredCategoryForDocOpen({ kind: 'exact-id', docId: input.targetDocId });
const ensure: DocSelectorStep = { action: 'ensure_category', category };
if (input.currentCategory !== category) {
return [ensure];
}
if (!input.visibleMenuDocIds.includes(input.targetDocId)) {
return [
ensure,
{ action: 'fail', reason: `doc-selector menu missing data-doc-id=${input.targetDocId}` },
];
}
return [ensure, { action: 'select_exact', docId: input.targetDocId }];
}