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 intoApr 30, 2026
Conversation
…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
Contributor
Quality Report — ConductionNL/mydash @
|
| 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
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.