Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

feat(dashboard-icons): IconPicker (built-in + upload)#58

Merged
rubenvdlinde merged 2 commits into
developmentfrom
feature/impl-custom-icon-upload-pattern
Apr 30, 2026
Merged

feat(dashboard-icons): IconPicker (built-in + upload)#58
rubenvdlinde merged 2 commits into
developmentfrom
feature/impl-custom-icon-upload-pattern

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Implements REQ-ICON-008..009 per spec. New IconPicker.vue combining built-in select + file upload, both updating v-model, with live 24x24 preview via IconRenderer. Uses resourceService.uploadDataUrl from PR #55. Tests cover switching modes and error handling. Verified REQ-ICON-005..007 already implemented.

…8..009

- Add isCustomIconUrl discriminator to dashboardIcons.js (REQ-ICON-005)
- Update getIconComponent to return null for URL inputs (REQ-ICON-006)
- Update IconRenderer with alt prop support for URL images (REQ-ICON-007)
- New IconPicker.vue combining built-in select + file upload (REQ-ICON-008)
  * Both update the same v-model
  * 24x24 live preview via IconRenderer
  * Inline error display with value preservation on failure
  * Uses resourceService.uploadDataUrl from PR #55
- Vitest tests covering mode switching and error handling (REQ-ICON-009)
  * Switching between built-in and custom URLs
  * Upload success/failure scenarios
  * Previous value preservation on error
- All quality gates pass: ESLint, Stylelint, Vitest
@rubenvdlinde rubenvdlinde added the ready-for-code-review Build complete — awaiting code reviewer label Apr 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/mydash @ aa47192

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 103/103
npm ✅ 342/342
PHPUnit ⏭️
Newman ⏭️
Playwright ⏭️

Quality workflow — 2026-04-30 19:08 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde rubenvdlinde merged commit 89171dc into development Apr 30, 2026
4 checks passed
@rubenvdlinde rubenvdlinde deleted the feature/impl-custom-icon-upload-pattern branch April 30, 2026 19:12
rubenvdlinde added a commit that referenced this pull request May 3, 2026
Promotes the existing `dashboard-icons` frontend registry (introduced
in PR #58) to a fully wired capability: Dashboard entity now carries
a typed `?string $icon` field with the registry-key/URL/NULL
convention, a new migration (Version001006) adds the column on
`mydash_dashboards`, the API controller and DashboardService
plumb the value end-to-end, and DashboardConfigModal grows a
registry-driven `<select>` icon picker so the create/edit form stays
in lock-step with `Object.keys(DASHBOARD_ICONS)`. DashboardConfigMenu
now resolves the per-dashboard icon through the shared
`IconRenderer`. Adds 20 vitest cases covering the resolver's
null/undefined/empty/unknown tolerance and the URL discriminator.
Spec delta merged into the canonical `dashboard-icons` capability;
proposal archived under `2026-05-02-dashboard-icons`.
rubenvdlinde added a commit that referenced this pull request May 3, 2026
Locks the dual-mode field convention so a single column may hold a
built-in registry name OR a `/apps/mydash/resource/...` URL OR NULL,
discriminated at render time by `isCustomIconUrl()`. Builds on the
`dashboard-icons` foundation (PR #58 dropped the `IconRenderer` and
the helper) and the `resource-uploads` upload pipeline.

Frontend:
- `dashboardIcons.js`: `getIconComponent` returns `null` for URL
  inputs (REQ-ICON-006); registry/null/empty inputs still resolve to
  `DEFAULT_ICON` so REQ-ICON-001 holds.
- `IconRenderer.vue`: gains an `alt` prop wired into the `<img>`
  branch with a non-empty fallback (REQ-ICON-007).
- `IconPicker.vue` (new): shared picker with both a registry
  `<select>` and an `<input type="file" accept="image/*">` visible
  simultaneously, 24x24 live preview through `IconRenderer`,
  inline error display, and previous-value preservation on upload
  failure (REQ-ICON-008).
- `services/resourceService.js` (new): thin wrapper around
  `POST /apps/mydash/api/resources` that normalises the
  `{status, error, message}` envelope into a typed
  `ResourceUploadError` carrying the stable enum (`forbidden`,
  `file_too_large`, `invalid_image_format`, `mime_mismatch`,
  `network_error`, ...).

Backend:
- `WidgetPlacement.tileIcon` docblock documents the
  registry-name | URL | NULL convention (REQ-ICON-009).
  `Dashboard.icon` docblock update is deferred until the parallel
  `dashboard-icons` proposal lands the column (the entity field
  doesn't exist on this branch yet).

Tests:
- 9 IconPicker, 6 IconRenderer, 9 dashboardIcons, 4 resourceService
  vitest cases covering the discriminator truth table, both render
  branches, the upload happy/error paths, and value preservation.
- Total: 75/75 vitest passing.
- ESLint clean (only pre-existing widgetBridge JSDoc warnings).
- `composer check:strict` ALL CHECKS PASSED (16 PHPUnit
  Doctrine\DBAL\ParameterType errors in DashboardShareServiceFollowupsTest
  pre-existing per commit de061cd).
- `npm run build` OK.

i18n: 5 new strings (`Failed to upload icon`, `Icon preview`,
`Select icon...`, `Upload icon`, `Uploading...`) added to all four
l10n files (en.js/json + nl.js/json).

Refactor scope: `DashboardSwitcher`, admin CRUD UI, and link-button
widget all DEFERRED — none currently render a Dashboard.icon field
(switcher is label-only, admin manages templates not per-dashboard
icons, link-button widget belongs to its own proposal). `IconPicker`
is exported and ready for those integrations.

Spec delta merged into canonical `openspec/specs/dashboard-icons/spec.md`;
proposal archived under `2026-05-02-custom-icon-upload-pattern`.
`openspec validate --all --strict`: 35 passed, 0 failed.
rubenvdlinde added a commit that referenced this pull request May 3, 2026
* feat(dashboard-icons): IconPicker (built-in + upload) per REQ-ICON-008..009

- Add isCustomIconUrl discriminator to dashboardIcons.js (REQ-ICON-005)
- Update getIconComponent to return null for URL inputs (REQ-ICON-006)
- Update IconRenderer with alt prop support for URL images (REQ-ICON-007)
- New IconPicker.vue combining built-in select + file upload (REQ-ICON-008)
  * Both update the same v-model
  * 24x24 live preview via IconRenderer
  * Inline error display with value preservation on failure
  * Uses resourceService.uploadDataUrl from PR #55
- Vitest tests covering mode switching and error handling (REQ-ICON-009)
  * Switching between built-in and custom URLs
  * Upload success/failure scenarios
  * Previous value preservation on error
- All quality gates pass: ESLint, Stylelint, Vitest

* chore: update SBOM

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

ready-for-code-review Build complete — awaiting code reviewer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant