Add guide metadata, redesign PDF cover, paginate steps, and run exports in a helper process #19

Merged
Tyler merged 16 commits from export_changes into main 2026-06-15 22:10:32 +00:00
Showing only changes of commit b85eaad0cb - Show all commits
+32 -24
View File
@@ -87,6 +87,16 @@ function stepNumberMap(steps) {
return numbers; return numbers;
} }
function stepDepth(step, stepMap) {
let depth = 0;
let parent = step.parentStepId;
while (parent && stepMap.has(parent)) {
depth += 1;
parent = stepMap.get(parent).parentStepId;
}
return depth;
}
function isEditableTarget(target) { function isEditableTarget(target) {
return target && ( return target && (
target.tagName === 'INPUT' || target.tagName === 'INPUT' ||
@@ -761,15 +771,10 @@ class GuideEditor {
this.dom.selectStepsBtn.className = this.stepSelectMode ? 'primary' : ''; this.dom.selectStepsBtn.className = this.stepSelectMode ? 'primary' : '';
for (const step of this.steps) { for (const step of this.steps) {
const number = numbers.get(step.stepId) || ''; const number = numbers.get(step.stepId) || '';
let depth = 0; const depth = stepDepth(step, this.stepMap);
let parent = step.parentStepId;
while (parent && this.stepMap.has(parent)) {
depth += 1;
parent = this.stepMap.get(parent).parentStepId;
}
const selected = current && current.stepId === step.stepId; const selected = current && current.stepId === step.stepId;
const checked = this.selectedSteps.has(step.stepId); const checked = this.selectedSteps.has(step.stepId);
const item = el('div.step-item', { const itemProps = {
className: `step-item${selected ? ' selected' : ''}${depth ? ' sub' : ''}${step.skipped ? ' skipped' : ''}${step.hidden ? ' hiddenstep' : ''}`, className: `step-item${selected ? ' selected' : ''}${depth ? ' sub' : ''}${step.skipped ? ' skipped' : ''}${step.hidden ? ' hiddenstep' : ''}`,
dataset: { stepId: step.stepId }, dataset: { stepId: step.stepId },
onClick: () => { onClick: () => {
@@ -802,23 +807,26 @@ class GuideEditor {
{ label: 'Delete step', danger: true, action: () => this.deleteSelectedStep() }, { label: 'Delete step', danger: true, action: () => this.deleteSelectedStep() },
]); ]);
}, },
}, };
this.stepSelectMode if (depth) itemProps.style = { marginLeft: `${depth * 18}px` };
? el('input', { const item = el('div.step-item', itemProps,
type: 'checkbox', this.stepSelectMode
checked, ? el('input', {
onClick: (e) => e.stopPropagation(), type: 'checkbox',
onChange: () => this.toggleStepSelection(step.stepId), checked,
}) onClick: (e) => e.stopPropagation(),
: null, onChange: () => this.toggleStepSelection(step.stepId),
el('span.status-dot', { className: `status-dot status-${step.status}` }), })
el('span.num', {}, number || '•'), : null,
el('span.t', {}, step.title || 'Untitled step'), el('span.status-dot', { className: `status-dot status-${step.status}` }),
el('span.flags', {}, [ el('span.num', {}, number || '•'),
step.parentStepId ? 'sub' : '', el('span.t', {}, step.title || 'Untitled step'),
step.hidden ? 'hidden' : '', el('span.flags', {}, [
step.skipped ? 'skipped' : '', step.parentStepId ? 'sub' : '',
].filter(Boolean).join(' · '))); step.hidden ? 'hidden' : '',
step.skipped ? 'skipped' : '',
].filter(Boolean).join(' · ')),
);
this.dom.stepsList.append(item); this.dom.stepsList.append(item);
} }
if (!this.steps.length) { if (!this.steps.length) {