/primary-sidebar
Complete guide for adding, updating, and removing tabs in the Primary Sidebar of OrcaQ. Covers the full flow — ActivityBarItemType enum → useActivityBarStore → PrimarySideBar component → Management panel component. Load this skill for any task involving the left sidebar,
$ npx -y skills add cin12211/orca-q --skill primary-sidebar --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/primary-sidebar
Context preview
The summary Claude sees to decide when to auto-load this skill.
Complete guide for adding, updating, and removing tabs in the Primary Sidebar of OrcaQ. Covers the full flow — ActivityBarItemType enum → useActivityBarStore → PrimarySideBar component → Management panel component. Load this skill for any task involving the left sidebar,
SKILL.md
primary-sidebar.SKILL.mdname: primary-sidebar
description: Complete guide for adding, updating, and removing tabs in the Primary Sidebar of OrcaQ. Covers the full flow — ActivityBarItemType enum → useActivityBarStore → PrimarySideBar component → Management panel component. Load this skill for any task involving the left sidebar, activity bar tabs, or management panels (Explorer, Schemas, ERD, Roles, Export, Agent).
Primary Sidebar Flow — OrcaQ
Architecture Overview
The Primary Sidebar is driven by a single active tab value in a Pinia store. The flow is:
ActivityBarItemType (enum) ← Tab identity
useActivityBarStore.activityActive ← Which tab is currently active (persisted)
PrimarySideBar.vue ← Watches activityActive, renders the matching component
Management***.vue ← The actual panel content (KeepAlive'd)
The Activity Bar (the narrow icon strip on the far left) calls `setActivityActive(type)`. The Primary Sidebar reacts to the change and swaps the rendered panel — all panels are wrapped in `<KeepAlive>` so their state is preserved when the user switches tabs.
---
File Locations
| Purpose | File | | ------------------------ | ----------------------------------------------------------------------------- | | Tab type enum + store | `core/stores/useActivityBarStore.ts` | | Sidebar shell (switcher) | `components/modules/app-shell/primary-side-bar/components/PrimarySideBar.vue` | | Sidebar public API | `components/modules/app-shell/primary-side-bar/index.ts` | | All management panels | `components/modules/management/` | | Management public API | `components/modules/management/index.ts` | | Shared header component | `components/modules/management/shared/components/ManagementSidebarHeader.vue` |
Management panel locations
| Tab | Panel component file | | ------------- | -------------------------------------------------------------------------------- | | Explorer | `components/modules/management/explorer/ManagementExplorer.vue` | | Schemas | `components/modules/management/schemas/ManagementSchemas.vue` | | ERD Diagram | `components/modules/management/erd-diagram/ManagementErdDiagram.vue` | | Users & Roles | `components/modules/management/role-permission/ManagementUsersAndPermission.vue` | | Export | `components/modules/management/export/ManagementExport.vue` | | Agent | `components/modules/management/agent/ManagementAgent.vue` |
---
How the Switcher Works (`PrimarySideBar.vue`)
<script setup lang="ts">
const activityStore = useActivityBarStore();
const current = shallowRef();
watch(
() => activityStore.activityActive,
() => {
if (activityStore.activityActive === ActivityBarItemType.Explorer)
current.value = ManagementExplorer;
if (activityStore.activityActive === ActivityBarItemType.Schemas)
current.value = ManagementSchemas;
// ... one branch per tab
},
{ immediate: true }
);
</script>
<template>
<div class="w-full h-full flex flex-col" v-if="appConfigStore.layoutSize[0]">
<KeepAlive>
<component :is="current" />
</KeepAlive>
</div>
</template>Key points:
- Uses `shallowRef` (not `ref`) for the component — avoids deep reactivity on component objects.
- `immediate: true` so the correct panel is rendered on first mount.
- `<KeepAlive>` preserves scroll position and internal state when switching tabs.
- The panel is only mounted when the sidebar is open (`layoutSize[0] > 0`).
---
How to Add a New Sidebar Tab
Step 1 — Add enum value
In `core/stores/useActivityBarStore.ts`:
export enum ActivityBarItemType {
Explorer = 'Explorer',
Schemas = 'Schemas',
ErdDiagram = 'ERDiagram',
UsersRoles = 'UsersRoles',
DatabaseExport = 'DatabaseExport',
Agent = 'Agent',
MyNewTab = 'MyNewTab', // ← new
}Step 2 — Create the management panel module
Create the folder `components/modules/management/my-new-tab/` with this structure:
my-new-tab/
├── index.ts ← exports ManagementMyNewTab
├── ManagementMyNewTab.vue ← entry component
├── components/ ← sub-components (optional)
├── hooks/ ← business logic composables (optional)
└── services/ ← API calls (optional)
**`ManagementMyNewTab.vue`** minimum template:
<script setup lang="ts">
import { ManagementSidebarHeader } from '../shared';
</script>
<template>
<div class="flex flex-col h-full w-full overflow-y-auto">
<ManagementSidebarHeader title="My New Tab" />
<!-- panel content here -->
</div>
</template>**`index.ts`**:
export { default as ManagementMyNewTab } from './ManagementMyNewTab.vue';Step 3 — Export from the management module
In `components/modules/management/index.ts`:
export * from './my-new-tab'; // ← add this line
Step 4 — Register in PrimarySideBar
In `components/modules/app-shell/primary-side-bar/components/PrimarySideBar.vue`:
// 1. Import the component
import { ManagementMyNewTab } from '#components';
// 2. Add a branch in the watch
watch(
() => activityStore.activityActive,
() => {
// ... existing branches ...
if (activityStore.activityActive === ActivityBarItemType.MyNewTab)
current.value = ManagementMyNewTab;
},
{ immediate: true }
);Step 5 — Add Activity Bar button
The Activity Bar icon strip that calls `setActivityActive` is separate from the management module. Find the component that renders the icon list and add a button:
activityStore.setActivityActive(A
Read more
name: primary-sidebar description: Complete guide for adding, updating, and removing tabs in the Primary Sidebar of OrcaQ. Covers the full flow — ActivityBarItemType enum → useActivityBarStore → PrimarySideBar component → Management panel component. Load this skill for any task involving the left sidebar, activity bar tabs, or management panels (Explorer, Schemas, ERD, Roles, Export, Agent).
Primary Sidebar Flow — OrcaQ
Architecture Overview
The Primary Sidebar is driven by a single active tab value in a Pinia store. The flow is:
ActivityBarItemType (enum) ← Tab identity useActivityBarStore.activityActive ← Which tab is currently active (persisted) PrimarySideBar.vue ← Watches activityActive, renders the matching component Management***.vue ← The actual panel content (KeepAlive'd)
The Activity Bar (the narrow icon strip on the far left) calls `setActivityActive(type)`. The Primary Sidebar reacts to the change and swaps the rendered panel — all panels are wrapped in `<KeepAlive>` so their state is preserved when the user switches tabs.
---
File Locations
| Purpose | File | | ------------------------ | ----------------------------------------------------------------------------- | | Tab type enum + store | `core/stores/useActivityBarStore.ts` | | Sidebar shell (switcher) | `components/modules/app-shell/primary-side-bar/components/PrimarySideBar.vue` | | Sidebar public API | `components/modules/app-shell/primary-side-bar/index.ts` | | All management panels | `components/modules/management/` | | Management public API | `components/modules/management/index.ts` | | Shared header component | `components/modules/management/shared/components/ManagementSidebarHeader.vue` |
Management panel locations
| Tab | Panel component file | | ------------- | -------------------------------------------------------------------------------- | | Explorer | `components/modules/management/explorer/ManagementExplorer.vue` | | Schemas | `components/modules/management/schemas/ManagementSchemas.vue` | | ERD Diagram | `components/modules/management/erd-diagram/ManagementErdDiagram.vue` | | Users & Roles | `components/modules/management/role-permission/ManagementUsersAndPermission.vue` | | Export | `components/modules/management/export/ManagementExport.vue` | | Agent | `components/modules/management/agent/ManagementAgent.vue` |
---
How the Switcher Works (`PrimarySideBar.vue`)
<script setup lang="ts">
const activityStore = useActivityBarStore();
const current = shallowRef();
watch(
() => activityStore.activityActive,
() => {
if (activityStore.activityActive === ActivityBarItemType.Explorer)
current.value = ManagementExplorer;
if (activityStore.activityActive === ActivityBarItemType.Schemas)
current.value = ManagementSchemas;
// ... one branch per tab
},
{ immediate: true }
);
</script>
<template>
<div class="w-full h-full flex flex-col" v-if="appConfigStore.layoutSize[0]">
<KeepAlive>
<component :is="current" />
</KeepAlive>
</div>
</template>Key points:
- Uses `shallowRef` (not `ref`) for the component — avoids deep reactivity on component objects.
- `immediate: true` so the correct panel is rendered on first mount.
- `<KeepAlive>` preserves scroll position and internal state when switching tabs.
- The panel is only mounted when the sidebar is open (`layoutSize[0] > 0`).
---
How to Add a New Sidebar Tab
Step 1 — Add enum value
In `core/stores/useActivityBarStore.ts`:
export enum ActivityBarItemType {
Explorer = 'Explorer',
Schemas = 'Schemas',
ErdDiagram = 'ERDiagram',
UsersRoles = 'UsersRoles',
DatabaseExport = 'DatabaseExport',
Agent = 'Agent',
MyNewTab = 'MyNewTab', // ← new
}Step 2 — Create the management panel module
Create the folder `components/modules/management/my-new-tab/` with this structure:
my-new-tab/ ├── index.ts ← exports ManagementMyNewTab ├── ManagementMyNewTab.vue ← entry component ├── components/ ← sub-components (optional) ├── hooks/ ← business logic composables (optional) └── services/ ← API calls (optional)
**`ManagementMyNewTab.vue`** minimum template:
<script setup lang="ts">
import { ManagementSidebarHeader } from '../shared';
</script>
<template>
<div class="flex flex-col h-full w-full overflow-y-auto">
<ManagementSidebarHeader title="My New Tab" />
<!-- panel content here -->
</div>
</template>**`index.ts`**:
export { default as ManagementMyNewTab } from './ManagementMyNewTab.vue';Step 3 — Export from the management module
In `components/modules/management/index.ts`:
export * from './my-new-tab'; // ← add this line
Step 4 — Register in PrimarySideBar
In `components/modules/app-shell/primary-side-bar/components/PrimarySideBar.vue`:
// 1. Import the component
import { ManagementMyNewTab } from '#components';
// 2. Add a branch in the watch
watch(
() => activityStore.activityActive,
() => {
// ... existing branches ...
if (activityStore.activityActive === ActivityBarItemType.MyNewTab)
current.value = ManagementMyNewTab;
},
{ immediate: true }
);Step 5 — Add Activity Bar button
The Activity Bar icon strip that calls `setActivityActive` is separate from the management module. Find the component that renders the icon list and add a button:
activityStore.setActivityActive(A
Repo: cin12211/orca-q
Other skills on orca-q.
- /accessibility-expert
WCAG 2.1/2.2 compliance, WAI-ARIA implementation, screen reader optimization, keyboard navigation, and accessibility testing expert. Use PROACTIVELY for accessibility violations, ARIA errors, keyboard navigation issues, screen reader compatibility problems, or accessibility
Open skill - /css-expert
CSS architecture and styling expert with deep knowledge of modern CSS features, responsive design, CSS-in-JS optimization, performance, accessibility, and design systems. Use PROACTIVELY for CSS layout issues, styling architecture, responsive design problems, CSS-in-JS
Open skill - /database-expert
Database performance optimization, schema design, query analysis, and connection management across PostgreSQL, MySQL, MongoDB, and SQLite with ORM integration. Use this skill for queries, indexes, connection pooling, transactions, and database architecture decisions.
Open skill - /documentation-expert
Expert in documentation structure, cohesion, flow, audience targeting, and information architecture. Use PROACTIVELY for documentation quality issues, content organization, duplication, navigation problems, or readability concerns. Detects documentation anti-patterns and
Open skill - /git-expert
Git expert with deep knowledge of merge conflicts, branching strategies, repository recovery, performance optimization, and security patterns. Use PROACTIVELY for any Git workflow issues including complex merge conflicts, history rewriting, collaboration patterns, and repository
Open skill - /graphify
Use for any question about a codebase, its architecture, file relationships, or project content — especially when graphify-out/ exists, where the question should be treated as a graphify query first. Turns any input (code, docs, papers, images, videos) into a persistent
Open skill

