Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

546 lines
16 KiB
Markdown

# SCRATCHPAD: UI Kit Showcase Extension
## Key Discoveries
### Extension Structure (from softwareone-ext)
- Extensions live in `ee/extensions/` directory
- Sample extensions go in `ee/extensions/samples/`
- Manifest requires: `name`, `publisher`, `version`, `runtime: "wasm-js@1"`, `ui` config
- UI iframe entry point: `ui/index.html`
- Build output goes to `ui/dist/iframe/main.js`
### UI Kit Location
- Package: `packages/ui-kit/`
- Import as: `@alga/ui-kit` (via vite alias)
- Vite alias required: `'@alga/ui-kit': path.resolve(__dirname, '..', '..', 'server', 'packages', 'ui-kit', 'src')`
### Theme Variable Inconsistency (CRITICAL)
UI Kit uses `--alga-*` variables, but main app uses `--color-*` variables:
| UI Kit Variable | Main App Equivalent |
|-----------------|---------------------|
| `--alga-bg` | `--color-background` |
| `--alga-fg` | `--color-text-900` |
| `--alga-border` | `--color-border-200` |
| `--alga-primary` | `--color-primary-500` |
| `--alga-muted` | `--color-border-100` |
| `--alga-muted-fg` | `--color-text-500` |
| `--alga-danger` | `--color-accent-red` or similar |
| `--alga-warning` | `--color-accent-orange` |
| `--alga-success` | `--color-accent-green` |
| `--alga-radius` | Hardcoded in app (typically 6-8px) |
**Solution**: Create a ThemeBridge component that injects `<style>` with CSS variable mappings.
### Components to Showcase (22 total)
**Core (8):**
- Button (variants: primary/secondary/ghost/danger, sizes: sm/md/lg)
- Input
- CustomSelect
- Card
- Alert (tones: info/success/warning/danger)
- Text (as, size, weight)
- Stack (direction, gap, align, justify)
- Badge (tones: default/success/warning/danger/info)
**Data (1):**
- DataTable (columns, pagination, sorting, responsiveColumns, custom render)
**Dialogs (2):**
- Dialog
- ConfirmDialog (danger variant)
**Feedback (5):**
- Spinner (sizes)
- LoadingIndicator
- Tooltip (positions: top/bottom/left/right)
- Progress (variants: default/striped/animated, sizes, indeterminate)
- Skeleton, SkeletonText, SkeletonCircle, SkeletonRectangle
**Form (5):**
- Checkbox (indeterminate, label, disabled)
- Switch (sizes: sm/md/lg, disabled)
- TextArea (rows, resize)
- Label (required, sizes)
- SearchInput (debounce, loading, showClear, sizes)
**Navigation (3):**
- Tabs (variants: default/pills/underline, disabled tabs)
- Drawer (positions: left/right/top/bottom, sizes: sm/md/lg/full)
- DropdownMenu (items, dividers, disabled, danger, align)
### Vite Config Notes (from softwareone-ext)
```ts
// Key settings for iframe bundle
build: {
lib: {
entry: 'src/iframe/main.tsx',
formats: ['es'],
fileName: () => 'main.js',
},
rollupOptions: {
external: [], // Bundle everything including React
output: {
inlineDynamicImports: true,
},
},
outDir: 'ui/dist/iframe',
}
// React deduplication
resolve: {
alias: {
'react': path.resolve(__dirname, 'node_modules/react'),
'react-dom': path.resolve(__dirname, 'node_modules/react-dom'),
'@alga/ui-kit': path.resolve(__dirname, '..', '..', 'server', 'packages', 'ui-kit', 'src'),
},
dedupe: ['react', 'react-dom'],
}
```
### Package.json Dependencies
```json
{
"dependencies": {
"react": "^19.2.3",
"react-dom": "^19.2.3",
"@alga/ui-kit": "file:../../server/packages/ui-kit"
}
}
```
## Decisions
1. **Extension location**: `ee/extensions/samples/ui-kit-showcase/` (alongside other samples)
2. **Theme bridge approach**: Inject CSS variables via `<style>` element in ThemeBridge component
3. **Navigation**: Use UI Kit's own Tabs component for category navigation
4. **No routing needed**: Single-page demo, tabs handle navigation
5. **Demo data**: Inline mock data for DataTable, no API calls needed
## Commands
```bash
# Create extension directory
mkdir -p ee/extensions/samples/ui-kit-showcase/{src/{iframe,components,demos},ui}
# Install dependencies
cd ee/extensions/samples/ui-kit-showcase && npm install
# Build extension
npm run build
# Check build output
ls -la ui/dist/iframe/
```
## Open Items
- [ ] Verify exact color mappings from globals.css
- [ ] Test theme bridge in both light and dark modes
- [ ] Confirm iframe sandbox doesn't block injected styles
## Updates
- F001: Added extension manifest at `ee/extensions/samples/ui-kit-showcase/manifest.json` with iframe UI entry and app menu hook for UI Kit Showcase.
- F002: Added `ee/extensions/samples/ui-kit-showcase/package.json` with React + @alga/ui-kit dependencies and build script.
- F003: Added `ee/extensions/samples/ui-kit-showcase/vite.iframe.config.ts` to bundle iframe UI into `ui/dist/iframe/main.js` with @alga/ui-kit aliasing.
- F004: Added `ee/extensions/samples/ui-kit-showcase/ui/index.html` with root div and iframe bundle script.
- F005: Added `ee/extensions/samples/ui-kit-showcase/tsconfig.json` with React JSX and module settings for the iframe app.
- F006: Added `ee/extensions/samples/ui-kit-showcase/src/components/ThemeBridge.tsx` to inject CSS variable bridge for --alga-* tokens.
- F007: ThemeBridge defines light-mode --color-* defaults and maps them to --alga-* tokens.
- F008: ThemeBridge includes dark-mode overrides via `data-alga-theme="dark"` selector.
- F009: Implemented theme toggle button in `src/iframe/App.tsx` to switch light/dark modes.
- F010: Header layout with title and theme toggle in App.
- F011: Tabbed navigation for categories uses UI kit Tabs in App.
- F012: Content area renders category demo panels via Tabs content.
- F013: DemoSection wrapper provides title, description, and demo container styling.
- F014: Button demo shows primary/secondary/ghost/danger variants in .
- F015: Button demo includes sm/md/lg size examples.
- F016: Button demo includes disabled state example.
- F017: Input demo renders basic input with placeholder.
- F018: Input demo renders disabled input state.
- F019: CustomSelect demo renders options with placeholder and selection state.
- F020: CustomSelect demo includes disabled state example.
- F021: Card demo shows card container with content and actions.
- F022: Alert demo shows info/success/warning/danger tones.
- F023: Text demo shows size and weight variants.
- F024: Text demo renders as h1/h2/p/span elements.
- F025: Stack demo shows row and column layouts.
- F026: Stack demo shows gap and alignment options.
- F027: Badge demo shows default/info/success/warning/danger tones.
- F028: DataTable demo enables sortable columns.
- F029: DataTable demo enables pagination and page size selection.
- F030: DataTable demo enables responsive column hiding.
- F031: DataTable demo renders status cells with Badge.
- F032: Dialog demo opens/closes with trigger button.
- F033: Dialog demo includes title and footer actions.
- F034: ConfirmDialog demo shows confirm/cancel actions.
- F035: ConfirmDialog demo includes danger variant.
- F036: Spinner demo renders multiple sizes.
- F037: LoadingIndicator demo shows spinner with text.
- F038: Tooltip demo shows top/bottom/left/right positions.
- F039: Progress demo shows 0/50/100 values.
- F040: Progress demo includes default, striped overlay, and animated examples.
- F041: Progress demo includes sm/md/lg size examples.
- F042: Progress demo includes indeterminate mode example.
- F043: Skeleton demo includes base skeleton block.
- F044: Skeleton demo includes SkeletonText lines.
- F045: Skeleton demo includes SkeletonCircle example.
- F046: Skeleton demo includes SkeletonRectangle example.
- F047: Checkbox demo includes checked/unchecked states.
- F048: Checkbox demo includes indeterminate example.
- F049: Checkbox demo includes labeled checkbox.
- F050: Checkbox demo includes disabled checkbox.
- F051: Switch demo includes on/off states.
- F052: Switch demo includes sm/md/lg sizes.
- F053: Switch demo includes disabled state.
- F054: TextArea demo includes basic textarea.
- F055: TextArea demo includes multiple row counts.
- F056: TextArea demo includes resize options.
- F057: TextArea demo includes disabled state.
- F058: Label demo includes basic label.
- F059: Label demo includes required indicator.
- F060: Label demo includes size variants.
- F061: SearchInput demo includes basic search input.
- F062: SearchInput demo includes clear button behavior.
- F063: SearchInput demo includes loading state example.
- F064: SearchInput demo includes size variants.
- F065: SearchInput demo includes debounce example.
- F066: Tabs demo includes default variant.
- F067: Tabs demo includes pills variant.
- F068: Tabs demo includes underline variant.
- F069: Tabs demo includes disabled tab example.
- F070: Drawer demo supports right position.
- F071: Drawer demo supports left position.
- F072: Drawer demo supports bottom position.
- F073: Drawer demo supports sm/md/lg/full sizes.
- F074: Drawer demo renders title and content.
- F075: DropdownMenu demo includes basic menu items.
- F076: DropdownMenu demo includes divider items.
- F077: DropdownMenu demo includes disabled items.
- F078: DropdownMenu demo includes danger items.
- F079: DropdownMenu demo shows left/right alignment.
- T001: Added vitest setup and scaffolding tests covering manifest required fields.
- T002: Scaffold tests assert iframe UI entry in manifest.
- T003: Scaffold tests assert appMenu hook presence.
- T004: Scaffold tests assert ui-kit dependency in package.json.
- T005: Scaffold tests assert react and react-dom dependencies.
- T006: Scaffold tests assert iframe bundle output path in vite config.
- T007: Scaffold tests assert ui-kit alias in vite config.
- T008: Scaffold tests assert index.html root div and bundle script.
- T009: Theme bridge tests assert alga background mapping.
- T010: Theme bridge tests assert alga foreground mapping.
- T011: Theme bridge tests assert alga primary mapping.
- T012: Theme bridge tests assert alga border mapping.
- T013: Theme bridge tests assert alga danger mapping.
- T014: Theme bridge tests assert dark mode token overrides.
- T015: Theme toggle test asserts mode switch on click.
- T016: Theme change test asserts document theme attribute updates.
- T017: Layout tests assert header title text.
- T018: Layout tests assert theme toggle visibility.
- T019: Layout tests assert six category tabs.
- T020: Layout tests assert tab switching updates content.
- T021: Layout tests assert default tab is Core.
- T022: DemoSection test asserts title render.
- T023: DemoSection test asserts description render.
- T024: DemoSection test asserts children render.
- T025: Button tests assert primary background mapping.
- T026: Button tests assert secondary background mapping.
- T027: Button tests assert ghost button transparency.
- T028: Button tests assert danger background mapping.
- T029: Button tests compare small vs medium sizes.
- T030: Button tests compare large vs medium sizes.
- T031: Button tests assert disabled opacity and disabled attribute.
- T032: Input tests assert text entry.
- T033: Input tests assert placeholder visibility.
- T034: Input tests assert disabled input cannot focus.
- T035: CustomSelect tests assert dropdown opens.
- T036: CustomSelect tests assert selected option shows.
- T037: CustomSelect tests assert disabled select doesn't open.
- T038: Card tests assert border and padding.
- T039: Card tests assert content rendering.
- T040: Alert tests assert info styling.
- T041: Alert tests assert success styling.
- T042: Alert tests assert warning styling.
- T043: Alert tests assert danger styling.
- T044: Text tests assert size changes.
- T045: Text tests assert weight changes.
- T046: Text tests assert element rendering.
- T047: Stack tests assert row direction.
- T048: Stack tests assert column direction.
- T049: Stack tests assert gap spacing.
- T050: Badge tests assert default tone styling.
- T051: Badge tests assert success tone styling.
- T052: Badge tests assert warning/danger styling.
- T053: DataTable tests assert headers render.
- T054: DataTable tests assert sortable header changes order.
- T055: DataTable tests assert pagination controls visible.
- T056: DataTable tests assert page size selector updates row count.
- T057: DataTable tests assert responsive column hiding when narrow.
- T058: DataTable tests assert badge render in custom cell.
- T059: Dialog tests assert open on trigger.
- T060: Dialog tests assert close on cancel.
- T061: Dialog tests assert title render.
- T062: ConfirmDialog tests assert confirm action.
- T063: ConfirmDialog tests assert cancel action.
- T064: ConfirmDialog tests assert danger button styling.
- T065: Spinner tests assert animation present.
- T066: Spinner tests assert size variants.
- T067: LoadingIndicator tests assert text renders.
- T068: Tooltip tests assert hover shows tooltip.
- T069: Tooltip tests assert multiple positions render.
- T070: Progress tests assert fill width for values.
- T071: Progress tests assert striped overlay style.
- T072: Progress tests assert animated transition.
- T073: Progress tests assert size height changes.
- T074: Progress tests assert indeterminate animation.
- T075: Skeleton tests assert pulse animation.
- T076: Skeleton tests assert multiple text lines.
- T077: Skeleton tests assert circular shape.
- T078: Skeleton tests assert rectangle dimensions.
- T079: Checkbox tests assert toggling state.
- T080: Checkbox tests assert indeterminate property.
- T081: Checkbox tests assert label click toggles.
- T082: Checkbox tests assert disabled checkbox doesn't toggle.
- T083: Switch tests assert toggle behavior.
- T084: Switch tests assert size variants.
- T085: Switch tests assert disabled switch doesn't toggle.
- T086: TextArea tests assert multi-line input.
- T087: TextArea tests assert rows prop.
- T088: TextArea tests assert resize styles.
- T089: TextArea tests assert disabled behavior.
- T090: Label tests assert label text rendering.
- T091: Label tests assert required indicator.
- T092: Label tests assert size variants.
- T093: SearchInput tests assert search icon.
- T094: SearchInput tests assert clear button appears.
- T095: SearchInput tests assert clear button clears value.
- T096: SearchInput tests assert loading spinner state.
- T097: SearchInput tests assert size variants.
- T098: SearchInput tests assert debounce behavior.
- T099: Tabs tests assert default indicator.
- T100: Tabs tests assert pills variant style.
- T101: Tabs tests assert underline variant style.
- T102: Tabs tests assert disabled tab state.
- T103: Tabs tests assert content changes on selection.
- T104: Drawer tests assert right position.
- T105: Drawer tests assert left position.
- T106: Drawer tests assert bottom position.
- T107: Drawer tests assert size changes.
- T108: Drawer tests assert title renders.
- T109: Drawer tests assert close button closes drawer.
- T110: Drawer tests assert escape closes drawer.
- T111: Drawer tests assert overlay click closes drawer.
- T112: DropdownMenu tests assert menu opens.
- T113: DropdownMenu tests assert item clicks update state.
- T114: DropdownMenu tests assert divider elements present.
- T115: DropdownMenu tests assert disabled items not clickable.
- T116: DropdownMenu tests assert danger item styling.
- T117: DropdownMenu tests assert right alignment.
- T118: DropdownMenu tests assert menu closes on item click.
- T119: DropdownMenu tests assert menu closes on outside click.
- F080: Fixed ui-kit path aliases and dependency, then ran `npm run build` successfully for iframe bundle.
- F081: Added iframe integration checks and ensured App renders all component demos without runtime errors.
## Test Stabilization Updates (2026-02-04)
- Fixed React hook errors in Vitest by aliasing `react`/`react-dom` to extension-local `node_modules`, enabling `preserveSymlinks`, and installing `@radix-ui/react-select` locally.
- Added JSDOM polyfills for Radix Select (`hasPointerCapture`, `setPointerCapture`, `releasePointerCapture`, `scrollIntoView`).
- Updated CustomSelect tests to use role-based queries (`combobox`, `option`) and avoid duplicate text matches.
- Adjusted layout/integration tests to target `tab` roles and navigate categories before asserting component titles.
- Tightened DataTable, Progress, Spinner, and Skeleton test queries to reflect actual DOM structure and inline styles.
- Full `vitest --run` completes with passing assertions but the process can linger (open handles); per-file runs exit cleanly.
## Commands
- `npx vitest -c vitest.config.ts --run test/core-demos.test.tsx`
- `npx vitest -c vitest.config.ts --run test/data-dialog-feedback.test.tsx`
- `npx vitest -c vitest.config.ts --run` (times out after completion; see note above)
- Marked T120-T124 as implemented after build/integration coverage was stabilized.