- Foldable left panel (user profile) and right panel (task details) - Clicking a task in the list or graph node selects it and shows details - Both views (task list + graph) always mounted via absolute inset-0 for correct canvas dimensions; tabs toggle visibility with opacity - Graph node selection animation: other nodes repel outward (charge -600), then selected node smoothly slides to center (500ms cubic ease-out), then charge restores to -120 and graph stabilizes - Graph re-fits on tab switch and panel resize via ResizeObserver - Fix UUID string IDs throughout (backend returns UUIDs, not integers) - Add TaskDetailPanel, UserPanel components - Add CLAUDE.md project documentation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
40 lines
908 B
JavaScript
40 lines
908 B
JavaScript
import {
|
|
appendContextPath,
|
|
blockParams,
|
|
createFrame,
|
|
isEmpty,
|
|
isFunction
|
|
} from '../utils';
|
|
import Exception from '../exception';
|
|
|
|
export default function(instance) {
|
|
instance.registerHelper('with', function(context, options) {
|
|
if (arguments.length != 2) {
|
|
throw new Exception('#with requires exactly one argument');
|
|
}
|
|
if (isFunction(context)) {
|
|
context = context.call(this);
|
|
}
|
|
|
|
let fn = options.fn;
|
|
|
|
if (!isEmpty(context)) {
|
|
let data = options.data;
|
|
if (options.data && options.ids) {
|
|
data = createFrame(options.data);
|
|
data.contextPath = appendContextPath(
|
|
options.data.contextPath,
|
|
options.ids[0]
|
|
);
|
|
}
|
|
|
|
return fn(context, {
|
|
data: data,
|
|
blockParams: blockParams([context], [data && data.contextPath])
|
|
});
|
|
} else {
|
|
return options.inverse(this);
|
|
}
|
|
});
|
|
}
|