Add side panels, task selection, graph animation, and project docs

- 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>
This commit is contained in:
Alvis
2026-04-08 11:23:06 +00:00
parent 5c7edd4bbc
commit f1d51b8cc8
23998 changed files with 3242708 additions and 0 deletions

63
frontend/node_modules/@jest/schemas/build/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,63 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {Static} from '@sinclair/typebox';
import {TBoolean} from '@sinclair/typebox';
import {TNull} from '@sinclair/typebox';
import {TNumber} from '@sinclair/typebox';
import {TObject} from '@sinclair/typebox';
import {TReadonlyOptional} from '@sinclair/typebox';
import {TString} from '@sinclair/typebox';
declare const RawSnapshotFormat: TObject<{
callToJSON: TReadonlyOptional<TBoolean>;
compareKeys: TReadonlyOptional<TNull>;
escapeRegex: TReadonlyOptional<TBoolean>;
escapeString: TReadonlyOptional<TBoolean>;
highlight: TReadonlyOptional<TBoolean>;
indent: TReadonlyOptional<TNumber>;
maxDepth: TReadonlyOptional<TNumber>;
maxWidth: TReadonlyOptional<TNumber>;
min: TReadonlyOptional<TBoolean>;
printBasicPrototype: TReadonlyOptional<TBoolean>;
printFunctionName: TReadonlyOptional<TBoolean>;
theme: TReadonlyOptional<
TObject<{
comment: TReadonlyOptional<TString<string>>;
content: TReadonlyOptional<TString<string>>;
prop: TReadonlyOptional<TString<string>>;
tag: TReadonlyOptional<TString<string>>;
value: TReadonlyOptional<TString<string>>;
}>
>;
}>;
export declare const SnapshotFormat: TObject<{
callToJSON: TReadonlyOptional<TBoolean>;
compareKeys: TReadonlyOptional<TNull>;
escapeRegex: TReadonlyOptional<TBoolean>;
escapeString: TReadonlyOptional<TBoolean>;
highlight: TReadonlyOptional<TBoolean>;
indent: TReadonlyOptional<TNumber>;
maxDepth: TReadonlyOptional<TNumber>;
maxWidth: TReadonlyOptional<TNumber>;
min: TReadonlyOptional<TBoolean>;
printBasicPrototype: TReadonlyOptional<TBoolean>;
printFunctionName: TReadonlyOptional<TBoolean>;
theme: TReadonlyOptional<
TObject<{
comment: TReadonlyOptional<TString<string>>;
content: TReadonlyOptional<TString<string>>;
prop: TReadonlyOptional<TString<string>>;
tag: TReadonlyOptional<TString<string>>;
value: TReadonlyOptional<TString<string>>;
}>
>;
}>;
export declare type SnapshotFormat = Static<typeof RawSnapshotFormat>;
export {};

60
frontend/node_modules/@jest/schemas/build/index.js generated vendored Normal file
View File

@@ -0,0 +1,60 @@
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
exports.SnapshotFormat = void 0;
function _typebox() {
const data = require('@sinclair/typebox');
_typebox = function () {
return data;
};
return data;
}
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const RawSnapshotFormat = _typebox().Type.Partial(
_typebox().Type.Object({
callToJSON: _typebox().Type.Readonly(_typebox().Type.Boolean()),
compareKeys: _typebox().Type.Readonly(_typebox().Type.Null()),
escapeRegex: _typebox().Type.Readonly(_typebox().Type.Boolean()),
escapeString: _typebox().Type.Readonly(_typebox().Type.Boolean()),
highlight: _typebox().Type.Readonly(_typebox().Type.Boolean()),
indent: _typebox().Type.Readonly(
_typebox().Type.Number({
minimum: 0
})
),
maxDepth: _typebox().Type.Readonly(
_typebox().Type.Number({
minimum: 0
})
),
maxWidth: _typebox().Type.Readonly(
_typebox().Type.Number({
minimum: 0
})
),
min: _typebox().Type.Readonly(_typebox().Type.Boolean()),
printBasicPrototype: _typebox().Type.Readonly(_typebox().Type.Boolean()),
printFunctionName: _typebox().Type.Readonly(_typebox().Type.Boolean()),
theme: _typebox().Type.Readonly(
_typebox().Type.Partial(
_typebox().Type.Object({
comment: _typebox().Type.Readonly(_typebox().Type.String()),
content: _typebox().Type.Readonly(_typebox().Type.String()),
prop: _typebox().Type.Readonly(_typebox().Type.String()),
tag: _typebox().Type.Readonly(_typebox().Type.String()),
value: _typebox().Type.Readonly(_typebox().Type.String())
})
)
)
})
);
const SnapshotFormat = _typebox().Type.Strict(RawSnapshotFormat);
exports.SnapshotFormat = SnapshotFormat;