feat(web): migrate Items page to React with UI improvements
Phase 2 of frontend migration (epic #6, issue #8). Rebuild the Items page (4,243 lines of vanilla JS) as 16 React components with full feature parity plus UI improvements. UI improvements: - Footer stats bar (28px fixed bottom) replacing top stat cards - Compact row density (28-32px) with alternating background colors - Right-click column configuration via reusable ContextMenu component - Resizable horizontal/vertical split panel layout (persisted) - In-pane CRUD forms replacing modal dialogs (Infor-style) Components (web/src/components/items/): - ItemTable: sortable columns, alternating rows, column config - ItemsToolbar: search with scope (All/PN/Desc), filters, actions - SplitPanel: drag-resizable horizontal/vertical container - FooterStats: fixed bottom bar with reactive item counts - ItemDetail: 5-tab detail pane (Main, Properties, Revisions, BOM, Where Used) with header actions - MainTab: metadata, inline project tag editor, file download - PropertiesTab: form/JSON dual-mode editor, save as new revision - RevisionsTab: comparison diff, status management, rollback - BOMTab: inline CRUD, cost calculations, CSV export - WhereUsedTab: parent assemblies table - CreateItemPane: in-pane form with schema category properties - EditItemPane: in-pane edit form for basic fields - DeleteItemPane: in-pane confirmation with warning - ImportItemsPane: CSV upload with dry-run validation flow Shared components: - ContextMenu: positioned right-click menu with checkbox support Hooks: - useItems: items fetching with search, filters, pagination, debounce - useLocalStorage: typed localStorage state hook Extended api/types.ts with request/response types for search, BOM, revisions, CSV import, schema properties, and revision comparison.
This commit is contained in:
@@ -3,7 +3,7 @@ export interface User {
|
||||
username: string;
|
||||
display_name: string;
|
||||
email: string;
|
||||
role: 'admin' | 'editor' | 'viewer';
|
||||
role: "admin" | "editor" | "viewer";
|
||||
auth_source: string;
|
||||
}
|
||||
|
||||
@@ -127,3 +127,104 @@ export interface ErrorResponse {
|
||||
error: string;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
// Search
|
||||
export interface FuzzyResult extends Item {
|
||||
score: number;
|
||||
}
|
||||
|
||||
// Where Used
|
||||
export interface WhereUsedEntry {
|
||||
id: string;
|
||||
parent_part_number: string;
|
||||
parent_description: string;
|
||||
rel_type: string;
|
||||
quantity: number | null;
|
||||
unit?: string;
|
||||
reference_designators?: string[];
|
||||
}
|
||||
|
||||
// CSV Import
|
||||
export interface CSVImportResult {
|
||||
total_rows: number;
|
||||
success_count: number;
|
||||
error_count: number;
|
||||
errors?: CSVImportError[];
|
||||
created_items?: string[];
|
||||
}
|
||||
|
||||
export interface CSVImportError {
|
||||
row: number;
|
||||
field?: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
// Request types
|
||||
export interface CreateItemRequest {
|
||||
schema?: string;
|
||||
category: string;
|
||||
description: string;
|
||||
projects?: string[];
|
||||
properties?: Record<string, unknown>;
|
||||
sourcing_type?: string;
|
||||
sourcing_link?: string;
|
||||
long_description?: string;
|
||||
standard_cost?: number;
|
||||
}
|
||||
|
||||
export interface UpdateItemRequest {
|
||||
part_number?: string;
|
||||
item_type?: string;
|
||||
description?: string;
|
||||
properties?: Record<string, unknown>;
|
||||
comment?: string;
|
||||
sourcing_type?: string;
|
||||
sourcing_link?: string;
|
||||
long_description?: string;
|
||||
standard_cost?: number;
|
||||
}
|
||||
|
||||
export interface CreateRevisionRequest {
|
||||
properties: Record<string, unknown>;
|
||||
comment: string;
|
||||
}
|
||||
|
||||
export interface AddBOMEntryRequest {
|
||||
child_part_number: string;
|
||||
rel_type?: string;
|
||||
quantity?: number;
|
||||
unit?: string;
|
||||
reference_designators?: string[];
|
||||
child_revision?: number;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface UpdateBOMEntryRequest {
|
||||
rel_type?: string;
|
||||
quantity?: number;
|
||||
unit?: string;
|
||||
reference_designators?: string[];
|
||||
child_revision?: number;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
// Schema properties
|
||||
export interface PropertyDef {
|
||||
type: string;
|
||||
required?: boolean;
|
||||
description?: string;
|
||||
default?: unknown;
|
||||
}
|
||||
|
||||
export type PropertySchema = Record<string, PropertyDef>;
|
||||
|
||||
// Revision comparison
|
||||
export interface RevisionComparison {
|
||||
from: number;
|
||||
to: number;
|
||||
added: Record<string, unknown>;
|
||||
removed: Record<string, unknown>;
|
||||
changed: Record<string, { from: unknown; to: unknown }>;
|
||||
status_changed?: { from: string; to: string };
|
||||
file_changed?: boolean;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user