Files
ss-tools/frontend/src/lib/ui/Icon.svelte
busya 67ba04d4ff feat: implement LLM table translation service with searchable datasource dropdown, i18n, sidebar, and RBAC
- Add backend plugin modules: preview, executor, orchestrator, events, sql_generator, superset_executor, dictionary, scheduler, metrics
- Add API routes for translate jobs, runs, dictionaries, preview, schedule, metrics, corrections
- Add ORM models (12 tables) and Pydantic schemas (15 DTOs)
- Register translate router in app.py with RBAC permission guards
- Add frontend pages: job list, job config, dictionary list/editor, history
- Add 7 reusable Svelte 5 components: Preview, RunProgress, RunResult, TermCorrection, BulkCorrection, ScheduleConfig, MetricsDashboard
- Add searchable datasource dropdown with Superset API integration
- Add i18n (en/ru) with ~300 keys across common, config, jobs, dictionaries, preview namespaces
- Add Translation sidebar category with Jobs/Dictionaries/History sub-items
- Hide health monitor error toast via suppressToast API option
- Add 69 backend tests and 44 frontend test files
- Fix: SupersetClient env resolution (string -> Environment object)
- Fix: Dataset detail API returns proper database dict
- Fix: Database dialect extraction fallback when metadata incomplete
2026-05-09 19:34:25 +03:00

111 lines
3.4 KiB
Svelte

<!-- [DEF:Icon:Component] -->
<!--
@COMPLEXITY: 2
@SEMANTICS: icon, ui-atom, svg
@PURPOSE: Render the shared inline SVG icon set with consistent sizing and stroke props.
@LAYER: Atom
@UX_STATE: Ready -> Requested icon path set is rendered as a decorative SVG.
@UX_STATE: Fallback -> Unknown icon names resolve to the dashboard glyph.
@INVARIANT: Icon output remains aria-hidden because labels belong to the interactive parent.
-->
<script>
let {
name = "circle",
size = 20,
className = "",
strokeWidth = 1.9,
} = $props();
const iconPaths = {
home: ["M3 11l9-7 9 7", "M5 10v9h14v-9", "M10 19v-5h4v5"],
dashboard: ["M4 4h16v16H4z", "M4 10h16", "M10 4v16"],
database: [
"M4 7c0-1.7 3.6-3 8-3s8 1.3 8 3-3.6 3-8 3-8-1.3-8-3z",
"M4 12c0 1.7 3.6 3 8 3s8-1.3 8-3",
"M4 17c0 1.7 3.6 3 8 3s8-1.3 8-3",
"M4 7v10",
"M20 7v10",
],
storage: ["M3 8l9-4 9 4-9 4-9-4z", "M3 13l9 4 9-4", "M3 17l9 4 9-4"],
reports: ["M5 5h14v14H5z", "M8 9h8", "M8 13h8", "M8 17h5"],
translate: [
"M2 12h20",
"M12 2a15.3 15.3 0 014 10 15.3 15.3 0 01-4 10",
"M12 2a15.3 15.3 0 00-4 10 15.3 15.3 0 004 10",
"M4 6H2",
"M22 6h-2",
"M9 18l-3 4",
"M15 18l3 4",
],
admin: [
"M12 3l8 4v5c0 5.2-3.4 8.6-8 9.9C7.4 20.6 4 17.2 4 12V7l8-4z",
"M9 12l2 2 4-4",
],
chevronDown: ["M6 9l6 6 6-6"],
chevronLeft: ["M15 6l-6 6 6 6"],
chevronRight: ["M9 6l6 6-6 6"],
menu: ["M4 7h16", "M4 12h16", "M4 17h16"],
activity: [
"M12 3v3",
"M12 18v3",
"M4.9 4.9l2.1 2.1",
"M17 17l2.1 2.1",
"M3 12h3",
"M18 12h3",
"M4.9 19.1L7 17",
"M17 7l2.1-2.1",
"M12 15a3 3 0 100-6 3 3 0 000 6z",
],
layers: ["M12 4l8 4-8 4-8-4 8-4z", "M4 12l8 4 8-4", "M4 16l8 4 8-4"],
back: ["M19 12H5", "M12 5l-7 7 7 7"],
close: ["M18 6L6 18", "M6 6l12 12"],
list: [
"M8 7h12",
"M8 12h12",
"M8 17h12",
"M4 7h.01",
"M4 12h.01",
"M4 17h.01",
],
clipboard: [
"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2",
"M9 5a2 2 0 002 2h2a2 2 0 002-2",
"M9 5a2 2 0 012-2h2a2 2 0 012 2",
],
settings: [
"M12 8.5a3.5 3.5 0 100 7 3.5 3.5 0 000-7z",
"M19.4 15a1 1 0 00.2 1.1l.1.1a1 1 0 010 1.4l-1.1 1.1a1 1 0 01-1.4 0l-.1-.1a1 1 0 00-1.1-.2 1 1 0 00-.6.9V20a1 1 0 01-1 1h-1.6a1 1 0 01-1-1v-.2a1 1 0 00-.6-.9 1 1 0 00-1.1.2l-.1.1a1 1 0 01-1.4 0l-1.1-1.1a1 1 0 010-1.4l.1-.1a1 1 0 00.2-1.1 1 1 0 00-.9-.6H4a1 1 0 01-1-1v-1.6a1 1 0 011-1h.2a1 1 0 00.9-.6 1 1 0 00-.2-1.1l-.1-.1a1 1 0 010-1.4l1.1-1.1a1 1 0 011.4 0l.1.1a1 1 0 001.1.2 1 1 0 00.6-.9V4a1 1 0 011-1h1.6a1 1 0 011 1v.2a1 1 0 00.6.9 1 1 0 001.1-.2l.1-.1a1 1 0 011.4 0l1.1 1.1a1 1 0 010 1.4l-.1.1a1 1 0 00-.2 1.1 1 1 0 00.9.6H20a1 1 0 011 1v1.6a1 1 0 01-1 1h-.2a1 1 0 00-.9.6z",
],
trash: [
"M3 6h18",
"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",
"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",
"M10 11v6",
"M14 11v6",
],
};
let paths = $derived(iconPaths[name] || iconPaths.dashboard);
</script>
<svg
xmlns="http://www.w3.org/2000/svg"
width={size}
height={size}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width={strokeWidth}
stroke-linecap="round"
stroke-linejoin="round"
class={className}
aria-hidden="true"
>
{#each paths as d}
<path {d} />
{/each}
</svg>
<!-- [/DEF:Icon:Component] -->