feat(ui): add breadcrumb icons, fix alignment, and remove duplicate form headers

- add section icons to all breadcrumbs across every page
- fix breadcrumb nav display:flex so icons align vertically with buttons
- wrap all page breadcrumbs in pageToolbar div for consistent layout
- add Breadcrumbs to AllRunsPage which previously used a plain h1
- fix envCardHeader flex:1 so settings button hugs the right edge
- remove card header from environment create/edit forms (duplicated breadcrumb)
This commit is contained in:
2026-04-10 19:58:33 +03:00
parent de0cbeef7c
commit 99da7ac891
37 changed files with 224 additions and 84 deletions
@@ -1,6 +1,7 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { X, Save, Braces } from 'lucide-react';
import { snippets } from '../../api';
import { Breadcrumbs, Button, Card, Input, CodeEditor } from '../../ui';
import styles from '../Page.module.css';
@@ -50,7 +51,7 @@ export function CreateSnippetPage() {
<div className={styles.pageToolbar}>
<Breadcrumbs
items={[
{ label: t('snippets.title'), onClick: () => navigate('/snippets') },
{ label: t('snippets.title'), icon: <Braces size={14} />, onClick: () => navigate('/snippets') },
{ label: t('snippets.create_title') },
]}
/>
@@ -98,9 +99,11 @@ export function CreateSnippetPage() {
</div>
<div className={styles.formActions}>
<Button type="button" variant="secondary" onClick={() => navigate('/snippets')}>
<X size={14} />
{t('snippets.action_cancel')}
</Button>
<Button type="submit" disabled={saving}>
<Save size={14} />
{t('snippets.action_save')}
</Button>
</div>
+4 -1
View File
@@ -1,6 +1,7 @@
import { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { X, Save, Braces } from 'lucide-react';
import { snippets } from '../../api';
import type { Snippet } from '../../api';
import { Breadcrumbs, Button, Card, Input, CodeEditor } from '../../ui';
@@ -68,7 +69,7 @@ export function EditSnippetPage() {
<div className={styles.pageToolbar}>
<Breadcrumbs
items={[
{ label: t('snippets.title'), onClick: () => navigate('/snippets') },
{ label: t('snippets.title'), icon: <Braces size={14} />, onClick: () => navigate('/snippets') },
{
label: snippet?.name ?? `#${id}`,
onClick: () => navigate(`/snippets/${id}`),
@@ -122,9 +123,11 @@ export function EditSnippetPage() {
</div>
<div className={styles.formActions}>
<Button type="button" variant="secondary" onClick={() => navigate(`/snippets/${id}`)}>
<X size={14} />
{t('snippets.action_cancel')}
</Button>
<Button type="submit" disabled={saving}>
<Save size={14} />
{t('snippets.action_update')}
</Button>
</div>
@@ -1,7 +1,7 @@
import { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Upload, Pencil, Trash2 } from 'lucide-react';
import { Upload, Pencil, Trash2, Braces } from 'lucide-react';
import { CodeBlock } from '../../ui';
import { stringify as yamlStringify } from 'yaml';
import { snippets } from '../../api';
@@ -57,7 +57,7 @@ export function SnippetDetailPage() {
<div className={styles.pageToolbar}>
<Breadcrumbs
items={[
{ label: t('snippets.title'), onClick: () => navigate('/snippets') },
{ label: t('snippets.title'), icon: <Braces size={14} />, onClick: () => navigate('/snippets') },
{ label: snippet?.name ?? `#${id}` },
]}
/>
@@ -96,9 +96,9 @@ export function SnippetDetailPage() {
{snippet && (
<>
<div className={styles.detailMeta}>
<Card>
<DescriptionList
layout="comfortable"
layout="grid"
items={[
{ term: t('snippets.field_id'), detail: <UuidBadge id={snippet.id} /> },
{ term: t('snippets.field_name'), detail: snippet.name },
@@ -116,7 +116,7 @@ export function SnippetDetailPage() {
},
]}
/>
</div>
</Card>
<div className={styles.stepsSection}>
<div className={styles.sectionHeader}>
+2 -2
View File
@@ -1,7 +1,7 @@
import { useEffect, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { Code, Pencil, Trash2, Plus, Download } from 'lucide-react';
import { Code, Pencil, Trash2, Plus, Download, Braces } from 'lucide-react';
import { parse as yamlParse } from 'yaml';
import { snippets } from '../../api';
import type { Snippet } from '../../api';
@@ -116,7 +116,7 @@ export function SnippetsPage() {
return (
<div>
<div className={styles.pageToolbar}>
<Breadcrumbs items={[{ label: t('snippets.title') }]} />
<Breadcrumbs items={[{ label: t('snippets.title'), icon: <Braces size={14} /> }]} />
<div className={styles.toolbarActions}>
<input
ref={fileInputRef}