- 27 Jul, 2026 1 commit
-
-
Administrator authored
Adds a checkbox to the TaskView filter panel that, when checked, attaches completion_percent_lte=99 to the /api/tasks/ query — i.e. tasks with completion_percent < 100% (not_started + in_progress). Bug fix: TaskView.fetchTasks built its query inline and bypassed useTaskFilters.toApiParams(), so any future field added to the composable's params mapping would silently no-op. Route the call through toApiParams() to make the composable the single source of truth. Coverage: extend useTaskFilters.spec toApiParams suite with both branches of onlyIncomplete. Co-Authored-By:Claude <noreply@anthropic.com>
-
- 19 Jul, 2026 4 commits
-
-
Administrator authored
Extract src/composables/useCrudList.js: owns list state + dialog state machine + applySaved/applyDeleted + 5 toggle methods. Config: { list, create, update, deleteFn, idKey, mapRow?, loadErrorKey? }. Decompose 4 master-data views into table + edit-dialog + delete-dialog SFCs (11 new files), mirroring the StoryView pattern proven in Candidate B. View shrinks to pure wiring of useCrudList + useFlashMessage + child SFCs. Structural fixes (now composition-enforced, not patch-enforced): - D5: applySaved merges backend response into local list, so audit fields (created_by, creation_date, last_updated_by, last_update_date) are visible immediately after save, no refresh required. - D7: useCrudList owns deleteError; only *DeleteDialog.vue reads it. Cross-dialog delete-error bug fixed by composition. Net change: SubjectView 763 → 85 TermView 619 → 95 StudentView 1312 → 115 StoryView 173 → 85 Total 2867 → 380 (-2487 lines) Tests: useCrudList.spec.js covers fetch (success/error/auto-clear/ mapRow/non-array fallback), applySaved (create/update/audit-preservation/ no-id/null-undefined), applyDeleted, 5 toggle methods, clearDeleteError, idKey+mapRow together. 23 new tests, 214 total passing. Other quality wins: ~30 console.log calls in the 3 large views removed; view-owned reference data (R2) keeps useCrudList agnostic of students/ subjects/terms. Co-Authored-By:Claude <noreply@anthropic.com>
-
Administrator authored
StoryView was the last "master-data" god-view whose script section still owned state, fetch, CRUD methods, table config, and three dialog templates in one file. Mirrors the Candidate 2 TaskView decomposition pattern. - src/components/story/StoryTable.vue — v-data-table + three Map<id, name> computeds for O(1) display lookup (replaces O(n^2) find); emits @edit / @delete - src/components/story/StoryEditDialog.vue — create+edit merged via nullable `story` prop; owns save flow + inline error alert - src/components/story/StoryDeleteDialog.vue — owns deleteStory call, isDeleting, inline error; preserves the existing 48-line UX - src/composables/useFlashMessage.js — { message, show, clear } with built-in 3s auto-dismiss - src/__tests__/composables/useFlashMessage.spec.js — 13 tests (fake timers) Key design choices (settled via /grilling before implementation): 1. Dialog seam shape is explicit props+events — :open, :story, @close, @saved, @deleted. Not v-model. Keeps multiple emits semantically distinct. 2. Lookup data (students/subjects/terms) lives in StoryView as raw refs and is passed down to children. No useMasterData composable — that scope belongs to Candidate A (useCrudList). 3. StoryEditDialog handles create+edit (TaskEditDialog pattern), with @saved carrying the backend response so the parent can do { ...existing, ...updated } merge and pick up audit fields (created_at, last_updated_at, etc.). 4. StoryDeleteDialog owns the delete flow internally — parent just wires @deleted(id) to a list splice. The existing "close-edit-after-delete" contract is preserved via the parent's onStoryDeleted handler. 5. Row-level delete is now in StoryTable (mdi-delete icon next to edit). Replaces the awkward "open edit -> click delete inside edit dialog -> confirm" three-click path with a two-click one. 6. console.log calls in StoryView removed (match TaskEditDialog's console.error-only pattern; CLAUDE.md says services log heavily, not components). StoryView is now a thin orchestrator: refs, two fetch functions, open/close handlers, two merge handlers. fetchStories still depends on fetchRelatedData completing first (sequential await, NOT Promise.all — see comment in onMounted). Tests 178 -> 191. Co-Authored-By:Claude <noreply@anthropic.com>
-
Administrator authored
The router beforeEach guard was a 40-line inline function mixing auth state checks, LAN bypass, and route resolution. Pulled the decision logic into src/utils/authGuard.js — a pure function checkAuth(to, authState) → {allowed, reason, redirect?} — that takes the auth store as a plain object and returns a verdict. No Pinia, no vue-router, no DOM imports. Trivially testable (21 spec covering LAN bypass, already-authed-on-login, refresh-failed, etc.). Router guard shrinks to 5 lines; AppLayout drops a redundant router.push('/login') (auth.logout already navigates internally); 5 master-data views drop redundant onMounted initializeAuth() calls (initializeAuth now runs once in main.js at boot). Co-Authored-By:Claude <noreply@anthropic.com>
-
Administrator authored
TaskView was a god-view doing filter wiring, calendar rendering, edit-dialog state, image carousel, and image grid all inline. Pulled into focused modules: - src/components/task/TaskFilters.vue — filter panel + emits update:*-id - src/components/task/TaskCalendar.vue — FullCalendar wrapper - src/components/task/TaskEditDialog.vue — create/edit dialog - src/components/task/TaskImageCarousel.vue — full-screen carousel - src/components/task/TaskImageGrid.vue — thumbnail grid + upload - src/composables/useTaskFilters.js — pure filter state + apply logic - src/utils/taskDisplay.js — completion/status display helpers Filter state now lives in useTaskFilters (covered by 20-test spec); TaskView is an orchestrator that mounts the children and forwards events. Closes the longest-standing "this file is too big to review" pain point. Co-Authored-By:Claude <noreply@anthropic.com>
-
- 18 Jul, 2026 1 commit
-
-
Administrator authored
Task images were stored as a JSON-ish field on stdt_tasks. Spec 0004 (see docs/task-images-migration.md) splits them into a dedicated sub-resource stdt_task_images so each image is its own row with mime_type / file_name / etag / size_bytes, accessed via /api/tasks/<id>/images/. Frontend changes: - new useTaskImages composable owning image state per edit dialog, with eager-load priming in load() so thumbnails render and are clickable in the grid (fixes v-if branch gated on populated imageCache). - taskService refactored: listTaskImages / createTaskImage / deleteTaskImage / getTaskImageContent (blob fetch with responseType: 'blob' to dodge 406s). - apiEndpoints.TASKS.IMAGES added for documentation purposes only — services still hardcode paths (CLAUDE.md flags apiEndpoints as stale). - TaskView.vue: switched from inline task.images to useTaskImages(); image upload / preview / delete / carousel wired to the new composable. Explicit taskId passed to load() and commit() since useTaskImages is instantiated without a taskIdRef at module scope. - locales en/zh-CN: new image keys (addImage, pendingUpload, clickToLoad, imagePartialFailure, imageLimitReached, etc.). Tests: - src/__tests__/api/taskService.test.js - src/__tests__/composables/useTaskImages.test.js - src/__tests__/composables/useTaskImages.network.test.js Also: .claude/ added to .gitignore (Claude Code local permissions, per-dev). Co-Authored-By:Claude <noreply@anthropic.com>
-
- 15 Jul, 2026 1 commit
-
-
Administrator authored
-
- 06 Jul, 2026 1 commit
-
-
Administrator authored
-
- 04 Jul, 2026 1 commit
-
-
Administrator authored
UI: add Settings skeleton page with v-tabs + 6 categories UI: enlarge TaskView event fonts and replace progress bar with SVG ring UI: add native title tooltip on TaskView events UI: convert filter panel toggle to floating icon button with slide animation UI: set browser tab title to "学生管理系统"
-
- 02 Jul, 2026 1 commit
-
-
Administrator authored
-
- 04 Sep, 2025 1 commit
-
-
Administrator authored
-
- 03 Sep, 2025 1 commit
-
-
Administrator authored
-
- 02 Sep, 2025 1 commit
-
-
Administrator authored
-
- 01 Sep, 2025 1 commit
-
-
Administrator authored
-
- 30 Aug, 2025 1 commit
-
-
Administrator authored
-
- 29 Aug, 2025 1 commit
-
-
Administrator authored
-
- 28 Aug, 2025 1 commit
-
-
Administrator authored
-
- 26 Aug, 2025 2 commits
-
-
Administrator authored
moved endpoints to /src/api; moved menu items to /src/components/constants/menuItems.js; added breadcrumbs; added Student page
-
Administrator authored
-
- 19 Aug, 2025 2 commits
-
-
Administrator authored
-
Administrator authored
-