Skip to content

Consolidate top bar#71

Merged
ScriptSmith merged 2 commits into
mainfrom
consolidate-top-bar
Jul 2, 2026
Merged

Consolidate top bar#71
ScriptSmith merged 2 commits into
mainfrom
consolidate-top-bar

Conversation

@ScriptSmith

Copy link
Copy Markdown
Member

No description provided.

@greptile-apps

greptile-apps Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR consolidates the top navigation bar by introducing a NavEntry union type (NavItem | NavGroup) that allows groups of related links to be collapsed into a single dropdown, and adds two new self-service pages — Skills and Templates — with their routes, PageGuard registrations, and matching Rust config fields.

  • Skills (/skills) and Templates (/templates) are added as lazily-loaded routes behind PageGuard, with templates and skills keys wired through PagesConfig in both TypeScript and Rust.
  • SkillFormModal and SkillImportModal have ownerOverride relaxed from required to optional; the server falls back to deriving ownership from the caller's auth scope when it is omitted.
  • The header's flat nav list is replaced with navEntries: NavEntry[]; groups with all items disabled are dropped before render, and navItems is re-exported as the flattened list for the mobile menu.

Confidence Score: 5/5

The change is safe to merge; the new pages and nav restructuring are additive and well-guarded.

All new routes are behind PageGuard with proper defaults, the ownerOverride change is backward-compatible, and query invalidation is handled consistently. The one flagged item (imperative navigation in dropdown items) is a UX limitation with no data or auth impact.

ui/src/components/Header/Header.tsx — NavGroupMenu renders dropdown items without real anchor elements.

Important Files Changed

Filename Overview
ui/src/components/Header/Header.tsx Consolidates flat nav list into NavEntry (NavItem
ui/src/pages/SkillsPage.tsx New self-service Skills page; modals are always mounted unconditionally, ownerOverride is derived from user?.id and can be undefined, query invalidation is handled by SkillFormModal internally.
ui/src/pages/TemplatesPage.tsx New self-service Templates page; mirrors SkillsPage structure and correctly invalidates template queries in onSaved.
ui/src/components/PageGuard/PageGuard.tsx Adds "templates" and "skills" to mainPageOrder and mainPageRoutes; straightforward and consistent with existing entries.
src/config/ui.rs Adds templates and skills PageConfig fields to PagesConfig struct; correct and consistent with the Rust serde defaults pattern.
ui/src/routes/AppRoutes.tsx Lazily imports and registers /templates and /skills routes behind PageGuard; consistent with existing route patterns.
ui/src/components/Admin/SkillFormModal/SkillFormModal.tsx ownerOverride made optional (was required); the prop is only used at skill creation time so the change is safe and the JSDoc comment is clear.
ui/src/components/SkillImportModal/SkillImportModal.tsx ownerOverride made optional with the same pattern as SkillFormModal; no other functional changes.
ui/src/config/types.ts Adds templates and skills to PagesConfig interface; aligned with defaults.ts and the Rust config struct.
ui/src/config/defaults.ts Both new page keys default to enabledPage, consistent with existing pages.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    NE["navEntries: NavEntry[]"]
    NE --> NG["NavGroup (Resources dropdown)"]
    NE --> NI["NavItem (Chat, Studio, Projects…)"]
    NG --> VF["visibleNavEntries filter\n(drop group if all items disabled)"]
    NI --> VF
    VF --> AALL["allNavEntries\n(+ adminNavItem if admin)"]
    AALL -->|isNavGroup| NGM["NavGroupMenu\n(Dropdown with navigate())"]
    AALL -->|NavItem| NL["NavLink"]
    NGM --> RES["Resources items:\nAPI Keys, Containers, Knowledge,\nProviders, Skills, Templates"]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    NE["navEntries: NavEntry[]"]
    NE --> NG["NavGroup (Resources dropdown)"]
    NE --> NI["NavItem (Chat, Studio, Projects…)"]
    NG --> VF["visibleNavEntries filter\n(drop group if all items disabled)"]
    NI --> VF
    VF --> AALL["allNavEntries\n(+ adminNavItem if admin)"]
    AALL -->|isNavGroup| NGM["NavGroupMenu\n(Dropdown with navigate())"]
    AALL -->|NavItem| NL["NavLink"]
    NGM --> RES["Resources items:\nAPI Keys, Containers, Knowledge,\nProviders, Skills, Templates"]
Loading

Reviews (3): Last reviewed commit: "Review fixes" | Re-trigger Greptile

Comment thread ui/src/pages/SkillsPage.tsx
@ScriptSmith

Copy link
Copy Markdown
Member Author

@greptile-apps

Comment on lines +139 to +144
onSaved={() => {
toast({
title: editingSkill ? "Skill updated" : "Skill created",
type: "success",
});
}}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Skills list not refreshed after save

The onSaved callback only fires a toast but never calls queryClient.invalidateQueries. After creating or editing a skill the table will silently show stale data until a hard reload. TemplatesPage (added in the same PR) correctly calls invalidateTemplates() in its onSaved. Add the same invalidation here — at minimum queryKey: [{ _id: "skillList" }], and any other query key that useUserSkills subscribes to.

Prompt To Fix With AI
This is a comment left during a code review.
Path: ui/src/pages/SkillsPage.tsx
Line: 139-144

Comment:
**Skills list not refreshed after save**

The `onSaved` callback only fires a toast but never calls `queryClient.invalidateQueries`. After creating or editing a skill the table will silently show stale data until a hard reload. `TemplatesPage` (added in the same PR) correctly calls `invalidateTemplates()` in its `onSaved`. Add the same invalidation here — at minimum `queryKey: [{ _id: "skillList" }]`, and any other query key that `useUserSkills` subscribes to.

How can I resolve this? If you propose a fix, please make it concise.

@ScriptSmith
ScriptSmith merged commit 1cde10b into main Jul 2, 2026
18 of 20 checks passed
@ScriptSmith
ScriptSmith deleted the consolidate-top-bar branch July 2, 2026 10:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant