x-ipe 1.0.23__py3-none-any.whl → 1.0.25__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- x_ipe/app.py +32 -1
- x_ipe/handlers/terminal_handlers.py +6 -0
- x_ipe/handlers/voice_handlers.py +5 -0
- x_ipe/resources/copilot-instructions.md +19 -6
- x_ipe/resources/skills/lesson-learned/SKILL.md +208 -0
- x_ipe/resources/skills/lesson-learned/references/examples.md +238 -0
- x_ipe/resources/skills/project-quality-board-management/SKILL.md +135 -298
- x_ipe/resources/skills/project-quality-board-management/references/evaluation-principles.md +213 -0
- x_ipe/resources/skills/project-quality-board-management/references/evaluation-procedures.md +214 -0
- x_ipe/resources/skills/project-quality-board-management/templates/quality-report.md +70 -18
- x_ipe/resources/skills/task-execution-guideline/SKILL.md +2 -2
- x_ipe/resources/skills/task-execution-guideline/templates/task-record.yaml +1 -1
- x_ipe/resources/skills/task-type-code-implementation/SKILL.md +72 -270
- x_ipe/resources/skills/task-type-code-implementation/references/implementation-guidelines.md +432 -0
- x_ipe/resources/skills/task-type-code-refactor-v2/SKILL.md +127 -353
- x_ipe/resources/skills/task-type-code-refactor-v2/references/refactoring-techniques.md +373 -0
- x_ipe/resources/skills/task-type-feature-breakdown/SKILL.md +31 -243
- x_ipe/resources/skills/task-type-feature-breakdown/references/breakdown-guidelines.md +330 -0
- x_ipe/resources/skills/task-type-feature-refinement/SKILL.md +27 -180
- x_ipe/resources/skills/task-type-feature-refinement/references/specification-writing-guide.md +267 -0
- x_ipe/resources/skills/task-type-idea-mockup/SKILL.md +38 -276
- x_ipe/resources/skills/task-type-idea-mockup/references/mockup-guidelines.md +299 -0
- x_ipe/resources/skills/task-type-idea-to-architecture/SKILL.md +20 -218
- x_ipe/resources/skills/task-type-idea-to-architecture/references/architecture-patterns.md +342 -0
- x_ipe/resources/skills/task-type-ideation/SKILL.md +10 -266
- x_ipe/resources/skills/task-type-ideation/references/folder-naming-guide.md +55 -0
- x_ipe/resources/skills/task-type-ideation/references/tool-usage-guide.md +236 -0
- x_ipe/resources/skills/task-type-ideation-v2/SKILL.md +488 -0
- x_ipe/resources/skills/task-type-ideation-v2/references/examples.md +377 -0
- x_ipe/resources/skills/task-type-ideation-v2/references/folder-naming-guide.md +74 -0
- x_ipe/resources/skills/task-type-ideation-v2/references/tool-usage-guide.md +145 -0
- x_ipe/resources/skills/task-type-ideation-v2/references/visualization-guide.md +160 -0
- x_ipe/resources/skills/task-type-ideation-v2/templates/idea-summary.md +86 -0
- x_ipe/resources/skills/task-type-refactoring-analysis/SKILL.md +83 -145
- x_ipe/resources/skills/task-type-refactoring-analysis/references/output-schema.md +172 -0
- x_ipe/resources/skills/task-type-technical-design/SKILL.md +28 -214
- x_ipe/resources/skills/task-type-technical-design/references/design-templates.md +422 -0
- x_ipe/resources/skills/task-type-test-generation/SKILL.md +47 -332
- x_ipe/resources/skills/task-type-test-generation/references/test-patterns.md +368 -0
- x_ipe/resources/skills/tool-tracing-creator/SKILL.md +312 -0
- x_ipe/resources/skills/tool-tracing-creator/references/examples.md +324 -0
- x_ipe/resources/skills/tool-tracing-instrumentation/SKILL.md +373 -0
- x_ipe/resources/skills/tool-tracing-instrumentation/references/examples.md +264 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/SKILL.md +486 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/references/10. example-gate-conditions.md +73 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/references/11. reference-quality-standards.md +127 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/references/2. reference-section-order.md +127 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/references/3. example-step-based-code-review.md +84 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/references/4. example-step-based-feature-implementation.md +113 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/references/5. example-function-based-validation.md +73 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/references/6. example-function-based-analysis.md +94 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/references/7. example-task-io-code-implementation.md +36 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/references/8. example-structured-summary.md +43 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/references/9. example-dor-dod.md +77 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/references/examples.md +429 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/references/skill-general-guidelines-v2.md +611 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/skill-meta-x-ipe-meta.md +153 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/skill-meta-x-ipe-task-based.md +324 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/skill-meta-x-ipe-task-category.md +109 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/skill-meta-x-ipe-tool.md +205 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/x-ipe-meta.md +334 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/x-ipe-task-based.md +279 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/x-ipe-tool.md +175 -0
- x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/x-ipe-workflow-orchestration.md +329 -0
- x_ipe/resources/skills/x-ipe-task-based-ideation/SKILL.md +487 -0
- x_ipe/resources/skills/x-ipe-task-based-ideation/references/examples.md +377 -0
- x_ipe/resources/skills/x-ipe-task-based-ideation/references/folder-naming-guide.md +74 -0
- x_ipe/resources/skills/x-ipe-task-based-ideation/references/tool-usage-guide.md +145 -0
- x_ipe/resources/skills/x-ipe-task-based-ideation/references/visualization-guide.md +160 -0
- x_ipe/resources/skills/x-ipe-task-based-ideation/templates/idea-summary.md +86 -0
- x_ipe/routes/__init__.py +2 -0
- x_ipe/routes/ideas_routes.py +289 -0
- x_ipe/routes/kb_routes.py +80 -0
- x_ipe/routes/main_routes.py +18 -0
- x_ipe/routes/project_routes.py +7 -0
- x_ipe/routes/proxy_routes.py +10 -2
- x_ipe/routes/quality_evaluation_routes.py +193 -0
- x_ipe/routes/settings_routes.py +6 -0
- x_ipe/routes/tools_routes.py +6 -0
- x_ipe/routes/tracing_routes.py +232 -0
- x_ipe/routes/uiux_feedback_routes.py +50 -0
- x_ipe/services/__init__.py +5 -0
- x_ipe/services/config_service.py +6 -0
- x_ipe/services/file_service.py +20 -0
- x_ipe/services/homepage_service.py +160 -0
- x_ipe/services/ideas_service.py +535 -2
- x_ipe/services/kb_service.py +378 -0
- x_ipe/services/proxy_service.py +37 -7
- x_ipe/services/settings_service.py +13 -0
- x_ipe/services/skills_service.py +4 -0
- x_ipe/services/terminal_service.py +24 -0
- x_ipe/services/themes_service.py +4 -0
- x_ipe/services/tools_config_service.py +4 -0
- x_ipe/services/tracing_service.py +333 -0
- x_ipe/services/uiux_feedback_service.py +148 -1
- x_ipe/services/voice_input_service_v2.py +11 -0
- x_ipe/static/css/base.css +7 -0
- x_ipe/static/css/homepage-infinity.css +330 -0
- x_ipe/static/css/kb-core.css +301 -0
- x_ipe/static/css/quality-evaluation.css +345 -0
- x_ipe/static/css/sidebar.css +14 -4
- x_ipe/static/css/terminal.css +23 -0
- x_ipe/static/css/tracing-dashboard.css +796 -0
- x_ipe/static/css/uiux-feedback.css +7 -1
- x_ipe/static/css/workplace.css +636 -0
- x_ipe/static/img/homepage-infinity-loop.png +0 -0
- x_ipe/static/js/features/confirm-dialog.js +169 -0
- x_ipe/static/js/features/folder-view.js +742 -0
- x_ipe/static/js/features/homepage-infinity.js +314 -0
- x_ipe/static/js/features/kb-core.js +371 -0
- x_ipe/static/js/features/quality-evaluation.js +387 -0
- x_ipe/static/js/features/sidebar.js +255 -12
- x_ipe/static/js/features/tracing-dashboard.js +855 -0
- x_ipe/static/js/features/tracing-graph.js +1031 -0
- x_ipe/static/js/features/tree-drag.js +227 -0
- x_ipe/static/js/features/tree-search.js +228 -0
- x_ipe/static/js/features/workplace.js +661 -33
- x_ipe/static/js/init.js +76 -0
- x_ipe/static/js/terminal-v2.js +45 -14
- x_ipe/static/js/terminal.js +50 -49
- x_ipe/static/js/uiux-feedback.js +75 -16
- x_ipe/templates/base.html +24 -0
- x_ipe/templates/index.html +10 -1
- x_ipe/templates/knowledge-base.html +110 -0
- x_ipe/templates/workplace.html +4 -0
- x_ipe/tracing/__init__.py +37 -0
- x_ipe/tracing/buffer.py +135 -0
- x_ipe/tracing/context.py +125 -0
- x_ipe/tracing/decorator.py +288 -0
- x_ipe/tracing/middleware.py +197 -0
- x_ipe/tracing/parser.py +235 -0
- x_ipe/tracing/redactor.py +111 -0
- x_ipe/tracing/writer.py +122 -0
- {x_ipe-1.0.23.dist-info → x_ipe-1.0.25.dist-info}/METADATA +2 -2
- {x_ipe-1.0.23.dist-info → x_ipe-1.0.25.dist-info}/RECORD +138 -65
- x_ipe/app.py.bak +0 -1333
- x_ipe/resources/skills/x-ipe-skill-creator/SKILL.md +0 -329
- x_ipe/resources/skills/x-ipe-skill-creator/references/output-patterns.md +0 -169
- x_ipe/resources/skills/x-ipe-skill-creator/references/skill-structure.md +0 -162
- x_ipe/resources/skills/x-ipe-skill-creator/references/workflows.md +0 -110
- x_ipe/resources/skills/x-ipe-skill-creator/templates/references/examples.md +0 -113
- x_ipe/resources/skills/x-ipe-skill-creator/templates/skill-category-skill.md +0 -296
- x_ipe/resources/skills/x-ipe-skill-creator/templates/task-type-skill.md +0 -269
- {x_ipe-1.0.23.dist-info → x_ipe-1.0.25.dist-info}/WHEEL +0 -0
- {x_ipe-1.0.23.dist-info → x_ipe-1.0.25.dist-info}/entry_points.txt +0 -0
- {x_ipe-1.0.23.dist-info → x_ipe-1.0.25.dist-info}/licenses/LICENSE +0 -0
|
@@ -16,6 +16,12 @@ class ProjectSidebar {
|
|
|
16
16
|
this.changedPaths = new Set();
|
|
17
17
|
this.previousPathMtimes = new Map(); // Map<path, mtime> for content change detection
|
|
18
18
|
|
|
19
|
+
// Track expanded/pinned state to preserve across re-renders
|
|
20
|
+
this.pinnedSections = new Set(); // Set of section IDs
|
|
21
|
+
this.pinnedFolders = new Set(); // Set of folder paths
|
|
22
|
+
this.expandedSections = new Set(); // Set of section IDs
|
|
23
|
+
this.expandedFolders = new Set(); // Set of folder paths
|
|
24
|
+
|
|
19
25
|
this._startPolling();
|
|
20
26
|
}
|
|
21
27
|
|
|
@@ -225,6 +231,9 @@ class ProjectSidebar {
|
|
|
225
231
|
return;
|
|
226
232
|
}
|
|
227
233
|
|
|
234
|
+
// Save current expanded/pinned state before re-rendering
|
|
235
|
+
this._saveExpandedState();
|
|
236
|
+
|
|
228
237
|
let html = '';
|
|
229
238
|
|
|
230
239
|
for (const section of this.sections) {
|
|
@@ -233,6 +242,95 @@ class ProjectSidebar {
|
|
|
233
242
|
|
|
234
243
|
this.container.innerHTML = html;
|
|
235
244
|
this.bindEvents();
|
|
245
|
+
|
|
246
|
+
// Restore expanded/pinned state after re-rendering
|
|
247
|
+
this._restoreExpandedState();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Save current expanded and pinned state from DOM
|
|
252
|
+
*/
|
|
253
|
+
_saveExpandedState() {
|
|
254
|
+
// Save expanded sections
|
|
255
|
+
this.container.querySelectorAll('.nav-section-content.show').forEach(content => {
|
|
256
|
+
const sectionId = content.id.replace('section-', '');
|
|
257
|
+
this.expandedSections.add(sectionId);
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
// Save pinned sections
|
|
261
|
+
this.container.querySelectorAll('.nav-section-header.pinned').forEach(header => {
|
|
262
|
+
const target = header.dataset.bsTarget;
|
|
263
|
+
if (target) {
|
|
264
|
+
const sectionId = target.replace('#section-', '');
|
|
265
|
+
this.pinnedSections.add(sectionId);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// Save expanded folders
|
|
270
|
+
this.container.querySelectorAll('.nav-folder-content.show').forEach(content => {
|
|
271
|
+
const folderHeader = this.container.querySelector(`[data-bs-target="#${content.id}"]`);
|
|
272
|
+
if (folderHeader && folderHeader.dataset.path) {
|
|
273
|
+
this.expandedFolders.add(folderHeader.dataset.path);
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Save pinned folders
|
|
278
|
+
this.container.querySelectorAll('.nav-folder.pinned').forEach(folder => {
|
|
279
|
+
if (folder.dataset.path) {
|
|
280
|
+
this.pinnedFolders.add(folder.dataset.path);
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Restore expanded and pinned state after render
|
|
287
|
+
*/
|
|
288
|
+
_restoreExpandedState() {
|
|
289
|
+
// Restore expanded sections
|
|
290
|
+
this.expandedSections.forEach(sectionId => {
|
|
291
|
+
const content = document.getElementById(`section-${sectionId}`);
|
|
292
|
+
const header = this.container.querySelector(`[data-bs-target="#section-${sectionId}"]`);
|
|
293
|
+
if (content && header) {
|
|
294
|
+
content.classList.add('show');
|
|
295
|
+
header.classList.remove('collapsed');
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
// Restore pinned sections (also expand them)
|
|
300
|
+
this.pinnedSections.forEach(sectionId => {
|
|
301
|
+
const content = document.getElementById(`section-${sectionId}`);
|
|
302
|
+
const header = this.container.querySelector(`[data-bs-target="#section-${sectionId}"]`);
|
|
303
|
+
if (content && header) {
|
|
304
|
+
content.classList.add('show');
|
|
305
|
+
header.classList.remove('collapsed');
|
|
306
|
+
header.classList.add('pinned');
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// Restore expanded folders
|
|
311
|
+
this.expandedFolders.forEach(folderPath => {
|
|
312
|
+
const folder = this.container.querySelector(`.nav-folder[data-path="${folderPath}"]`);
|
|
313
|
+
if (folder) {
|
|
314
|
+
const targetSelector = folder.dataset.bsTarget;
|
|
315
|
+
const content = document.querySelector(targetSelector);
|
|
316
|
+
if (content) {
|
|
317
|
+
content.classList.add('show');
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// Restore pinned folders (also expand them)
|
|
323
|
+
this.pinnedFolders.forEach(folderPath => {
|
|
324
|
+
const folder = this.container.querySelector(`.nav-folder[data-path="${folderPath}"]`);
|
|
325
|
+
if (folder) {
|
|
326
|
+
folder.classList.add('pinned');
|
|
327
|
+
const targetSelector = folder.dataset.bsTarget;
|
|
328
|
+
const content = document.querySelector(targetSelector);
|
|
329
|
+
if (content) {
|
|
330
|
+
content.classList.add('show');
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
});
|
|
236
334
|
}
|
|
237
335
|
|
|
238
336
|
/**
|
|
@@ -243,6 +341,8 @@ class ProjectSidebar {
|
|
|
243
341
|
const hasChildren = section.children && section.children.length > 0;
|
|
244
342
|
|
|
245
343
|
// CR-004: Special handling for Workplace section - show submenu with Ideation and UIUX Feedbacks
|
|
344
|
+
// FEATURE-023-B: Added Tracing submenu item
|
|
345
|
+
// FEATURE-024: Added Quality Evaluation submenu item
|
|
246
346
|
if (section.id === 'workplace') {
|
|
247
347
|
return `
|
|
248
348
|
<div class="nav-section" data-section-id="${section.id}">
|
|
@@ -260,6 +360,14 @@ class ProjectSidebar {
|
|
|
260
360
|
<i class="bi bi-chat-square-text"></i>
|
|
261
361
|
<span>UIUX Feedbacks</span>
|
|
262
362
|
</div>
|
|
363
|
+
<div class="nav-section-header sidebar-child nav-tracing" data-section-id="tracing">
|
|
364
|
+
<i class="bi bi-graph-up"></i>
|
|
365
|
+
<span>Application Tracing</span>
|
|
366
|
+
</div>
|
|
367
|
+
<div class="nav-section-header sidebar-child nav-quality-evaluation" data-section-id="quality-evaluation">
|
|
368
|
+
<i class="bi bi-clipboard-check"></i>
|
|
369
|
+
<span>Quality Evaluation</span>
|
|
370
|
+
</div>
|
|
263
371
|
</div>
|
|
264
372
|
</div>
|
|
265
373
|
`;
|
|
@@ -267,7 +375,7 @@ class ProjectSidebar {
|
|
|
267
375
|
|
|
268
376
|
let html = `
|
|
269
377
|
<div class="nav-section" data-section-id="${section.id}">
|
|
270
|
-
<div class="nav-section-header collapsed" data-bs-
|
|
378
|
+
<div class="nav-section-header collapsed" data-bs-target="#section-${section.id}">
|
|
271
379
|
<i class="bi ${icon}"></i>
|
|
272
380
|
<span>${section.label}</span>
|
|
273
381
|
<i class="bi bi-chevron-down chevron"></i>
|
|
@@ -328,7 +436,6 @@ class ProjectSidebar {
|
|
|
328
436
|
let html = `
|
|
329
437
|
<div class="nav-item nav-folder${isChanged ? ' has-changes' : ''}"
|
|
330
438
|
style="padding-left: ${paddingLeft}rem"
|
|
331
|
-
data-bs-toggle="collapse"
|
|
332
439
|
data-bs-target="#folder-${folderId}"
|
|
333
440
|
data-path="${folder.path}">
|
|
334
441
|
${isChanged ? '<span class="change-indicator"></span>' : ''}
|
|
@@ -505,6 +612,88 @@ class ProjectSidebar {
|
|
|
505
612
|
});
|
|
506
613
|
}
|
|
507
614
|
|
|
615
|
+
// FEATURE-023-B: Tracing click handler - render Tracing Dashboard in content area
|
|
616
|
+
const tracingHeader = this.container.querySelector('.nav-tracing');
|
|
617
|
+
if (tracingHeader) {
|
|
618
|
+
tracingHeader.addEventListener('click', () => {
|
|
619
|
+
// Clear file selection
|
|
620
|
+
fileItems.forEach(f => f.classList.remove('active'));
|
|
621
|
+
this.selectedFile = null;
|
|
622
|
+
|
|
623
|
+
// Update sidebar-child active state
|
|
624
|
+
const sidebarChildren = this.container.querySelectorAll('.sidebar-child');
|
|
625
|
+
sidebarChildren.forEach(child => child.classList.remove('active'));
|
|
626
|
+
tracingHeader.classList.add('active');
|
|
627
|
+
|
|
628
|
+
// Clear contentRenderer.currentPath to prevent auto-refresh
|
|
629
|
+
if (window.contentRenderer) {
|
|
630
|
+
window.contentRenderer.currentPath = null;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// Hide Create Idea button
|
|
634
|
+
const createIdeaBtn = document.getElementById('btn-create-idea');
|
|
635
|
+
if (createIdeaBtn) {
|
|
636
|
+
createIdeaBtn.classList.add('d-none');
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// Update breadcrumb
|
|
640
|
+
const breadcrumb = document.getElementById('breadcrumb');
|
|
641
|
+
breadcrumb.innerHTML = '<li class="breadcrumb-item active">Application Tracing</li>';
|
|
642
|
+
|
|
643
|
+
// Render Tracing Dashboard in content area
|
|
644
|
+
const container = document.getElementById('content-body');
|
|
645
|
+
if (window.TracingDashboard) {
|
|
646
|
+
// Clean up any existing dashboard
|
|
647
|
+
if (window._tracingDashboardInstance) {
|
|
648
|
+
window._tracingDashboardInstance.destroy();
|
|
649
|
+
}
|
|
650
|
+
window._tracingDashboardInstance = new window.TracingDashboard(container);
|
|
651
|
+
window._tracingDashboardInstance.init();
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// FEATURE-024: Quality Evaluation submenu click handler
|
|
657
|
+
const qualityEvalHeader = this.container.querySelector('.nav-quality-evaluation');
|
|
658
|
+
if (qualityEvalHeader) {
|
|
659
|
+
qualityEvalHeader.addEventListener('click', () => {
|
|
660
|
+
// Clear file selection
|
|
661
|
+
fileItems.forEach(f => f.classList.remove('active'));
|
|
662
|
+
this.selectedFile = null;
|
|
663
|
+
|
|
664
|
+
// Update sidebar-child active state
|
|
665
|
+
const sidebarChildren = this.container.querySelectorAll('.sidebar-child');
|
|
666
|
+
sidebarChildren.forEach(child => child.classList.remove('active'));
|
|
667
|
+
qualityEvalHeader.classList.add('active');
|
|
668
|
+
|
|
669
|
+
// Clear contentRenderer.currentPath to prevent auto-refresh
|
|
670
|
+
if (window.contentRenderer) {
|
|
671
|
+
window.contentRenderer.currentPath = null;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// Hide Create Idea button
|
|
675
|
+
const createIdeaBtn = document.getElementById('btn-create-idea');
|
|
676
|
+
if (createIdeaBtn) {
|
|
677
|
+
createIdeaBtn.classList.add('d-none');
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// Update breadcrumb
|
|
681
|
+
const breadcrumb = document.getElementById('breadcrumb');
|
|
682
|
+
breadcrumb.innerHTML = '<li class="breadcrumb-item active">Quality Evaluation</li>';
|
|
683
|
+
|
|
684
|
+
// Render Quality Evaluation view in content area
|
|
685
|
+
const container = document.getElementById('content-body');
|
|
686
|
+
if (window.QualityEvaluationView) {
|
|
687
|
+
// Clean up any existing view
|
|
688
|
+
if (window._qualityEvaluationInstance) {
|
|
689
|
+
window._qualityEvaluationInstance.destroy();
|
|
690
|
+
}
|
|
691
|
+
window._qualityEvaluationInstance = new window.QualityEvaluationView(container);
|
|
692
|
+
window._qualityEvaluationInstance.init();
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
|
|
508
697
|
// CR-004: Prevent parent item click action
|
|
509
698
|
const parentItems = this.container.querySelectorAll('.sidebar-parent[data-no-action="true"]');
|
|
510
699
|
parentItems.forEach(item => {
|
|
@@ -548,7 +737,9 @@ class ProjectSidebar {
|
|
|
548
737
|
|
|
549
738
|
let collapseTimeout = null;
|
|
550
739
|
let expandTimeout = null;
|
|
551
|
-
|
|
740
|
+
// Initialize isPinned from persisted state
|
|
741
|
+
const sectionId = targetSelector.replace('#section-', '');
|
|
742
|
+
let isPinned = this.pinnedSections.has(sectionId);
|
|
552
743
|
const section = header.closest('.nav-section');
|
|
553
744
|
|
|
554
745
|
// Click to pin/unpin
|
|
@@ -568,15 +759,17 @@ class ProjectSidebar {
|
|
|
568
759
|
if (isPinned) {
|
|
569
760
|
// Unpin and collapse
|
|
570
761
|
isPinned = false;
|
|
762
|
+
this.pinnedSections.delete(sectionId);
|
|
763
|
+
this.expandedSections.delete(sectionId);
|
|
571
764
|
header.classList.remove('pinned');
|
|
572
765
|
bootstrap.Collapse.getOrCreateInstance(target).hide();
|
|
573
766
|
} else {
|
|
574
|
-
// Pin and expand
|
|
767
|
+
// Pin and expand - always show to ensure it stays open
|
|
575
768
|
isPinned = true;
|
|
769
|
+
this.pinnedSections.add(sectionId);
|
|
770
|
+
this.expandedSections.add(sectionId);
|
|
576
771
|
header.classList.add('pinned');
|
|
577
|
-
|
|
578
|
-
bootstrap.Collapse.getOrCreateInstance(target).show();
|
|
579
|
-
}
|
|
772
|
+
bootstrap.Collapse.getOrCreateInstance(target).show();
|
|
580
773
|
}
|
|
581
774
|
});
|
|
582
775
|
|
|
@@ -633,7 +826,9 @@ class ProjectSidebar {
|
|
|
633
826
|
|
|
634
827
|
let collapseTimeout = null;
|
|
635
828
|
let expandTimeout = null;
|
|
636
|
-
|
|
829
|
+
// Initialize isPinned from persisted state
|
|
830
|
+
const folderPath = folder.dataset.path;
|
|
831
|
+
let isPinned = this.pinnedFolders.has(folderPath);
|
|
637
832
|
|
|
638
833
|
// Click to pin/unpin
|
|
639
834
|
folder.addEventListener('click', (e) => {
|
|
@@ -652,15 +847,17 @@ class ProjectSidebar {
|
|
|
652
847
|
if (isPinned) {
|
|
653
848
|
// Unpin and collapse
|
|
654
849
|
isPinned = false;
|
|
850
|
+
this.pinnedFolders.delete(folderPath);
|
|
851
|
+
this.expandedFolders.delete(folderPath);
|
|
655
852
|
folder.classList.remove('pinned');
|
|
656
853
|
bootstrap.Collapse.getOrCreateInstance(target).hide();
|
|
657
854
|
} else {
|
|
658
|
-
// Pin and expand
|
|
855
|
+
// Pin and expand - always show to ensure it stays open
|
|
659
856
|
isPinned = true;
|
|
857
|
+
this.pinnedFolders.add(folderPath);
|
|
858
|
+
this.expandedFolders.add(folderPath);
|
|
660
859
|
folder.classList.add('pinned');
|
|
661
|
-
|
|
662
|
-
bootstrap.Collapse.getOrCreateInstance(target).show();
|
|
663
|
-
}
|
|
860
|
+
bootstrap.Collapse.getOrCreateInstance(target).show();
|
|
664
861
|
}
|
|
665
862
|
});
|
|
666
863
|
|
|
@@ -773,6 +970,52 @@ class ProjectSidebar {
|
|
|
773
970
|
document.dispatchEvent(event);
|
|
774
971
|
}
|
|
775
972
|
|
|
973
|
+
/**
|
|
974
|
+
* FEATURE-026: Expand a sidebar section by ID
|
|
975
|
+
* @param {string} sectionId - Section ID to expand
|
|
976
|
+
*/
|
|
977
|
+
expandSection(sectionId) {
|
|
978
|
+
const sectionHeader = document.querySelector(`[data-section="${sectionId}"] .section-header`);
|
|
979
|
+
if (sectionHeader) {
|
|
980
|
+
const section = sectionHeader.closest('.sidebar-section');
|
|
981
|
+
if (section && !section.classList.contains('expanded')) {
|
|
982
|
+
sectionHeader.click();
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
/**
|
|
988
|
+
* FEATURE-026: Highlight a sidebar item
|
|
989
|
+
* @param {string} selector - CSS selector for target item
|
|
990
|
+
* @param {Object} options - Highlight options
|
|
991
|
+
* @param {number} options.duration - Highlight duration in ms (default 3000)
|
|
992
|
+
*/
|
|
993
|
+
highlightItem(selector, options = {}) {
|
|
994
|
+
const duration = options.duration || 3000;
|
|
995
|
+
const item = document.querySelector(selector);
|
|
996
|
+
|
|
997
|
+
if (!item) {
|
|
998
|
+
console.warn(`Sidebar item not found: ${selector}`);
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// Remove any existing highlights
|
|
1003
|
+
document.querySelectorAll('.homepage-highlight').forEach(el => {
|
|
1004
|
+
el.classList.remove('homepage-highlight');
|
|
1005
|
+
});
|
|
1006
|
+
|
|
1007
|
+
// Add highlight class
|
|
1008
|
+
item.classList.add('homepage-highlight');
|
|
1009
|
+
|
|
1010
|
+
// Scroll into view
|
|
1011
|
+
item.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
1012
|
+
|
|
1013
|
+
// Remove highlight after delay
|
|
1014
|
+
setTimeout(() => {
|
|
1015
|
+
item.classList.remove('homepage-highlight');
|
|
1016
|
+
}, duration);
|
|
1017
|
+
}
|
|
1018
|
+
|
|
776
1019
|
/**
|
|
777
1020
|
* Show toast notification
|
|
778
1021
|
*/
|