2.0.0 - #255
Open
volarname wants to merge 69 commits into
Open
Conversation
Added: - Internal image flag support for asset licences (DamAssetLicenceExtended type, internalRule config, override/internal flag switches in asset metadata) - Two new job types: jobAssetFileReprocessInternalFlag and jobSynchronizeImageChanged with full create/detail UI
Co-authored-by: Tomas Hermanek <tomas.hermanek@petitpress.sk>
added `mainFileOverrideInternal` and `mainFileInternal` boolean fields in `AssetMetadataBulkItem` for asset metadata updates
… eslint, watch-common-admin, browserslist:update
…rWrapper to layouts/
Reorganize src/ into src/domains/<system>/<entity>/{api,components,
composables,factory,filter,store,types,valueObject} per entity. Three
top-level systems: system/ (auth, app shell, system views), common/
(anzuUser, log, permission, permissionConfig, permissionGroup),
coreDam/ (17 DAM entities + shared/ slot for cross-entity DAM code:
anzutap, ColorBox, FileUpload, customMetadata, ABtnAdvanced,
CachedDamUserChip, FilterClosestColor, distribution helpers,
assetFileRoute, upload service).
Cross-system generics moved to src/shared/ (apiClients/, types/,
utils/, EnvConfigService.ts, ErrorHandlerApiService.ts,
BetaTestFeaturesService.ts, systems.ts, configurationApi.ts).
Old top-level folders src/{components,composables,services,stores,
types,model,views,utils}/ deleted entirely. Every move via git mv so
git log --follow traces full history. layouts/, pages/, plugins/,
styles/, locales/, router/ stay at root.
system/auth/Auth.ts -> simpleLogin.ts (Linux case-sensitive collision
with sibling auth.ts composable rejected by TS forceConsistentCasing
InFileNames). Affects only the import path; SimpleLoginForm export
unchanged.
views/coreDam/externalProviderAsset/ consolidated into
domains/coreDam/externalProvider/components/.
eslint.config.mjs: anzu/no-deprecated-imports toggled warn -> off to
keep CI signal clean during restructure; re-enable in dedicated
cleanup PR.
common-admin chunk dropped from 1,113 kB to 4 parts (all <500 kB): - common-admin (main, 415 kB) - common-admin-internals (index-*.mjs, 461 kB) - common-admin-autocomplete (AFormRemoteAutocomplete async chunk, 176 kB) - common-admin-labs (labs.js, only loaded when used) vue-i18n + @intlify/* pulled out of vue-core (49 kB own chunk). New vendor-utils chunk (115 kB) for axios, @vuelidate, @floating-ui, jwt-decode, universal-cookie, uuid, rusha, sortablejs. No more "chunks larger than 500 kB" Rollup warning.
added 4 commits
June 17, 2026 00:00
…mputed Replace the one-off type alias (added to keep the TS union out of the template binding, where oxfmt strips the parens and vue-eslint-parser then misreads `|` as a deprecated Vue filter) with a computed that does the same narrowing in script. Cleaner and self-explanatory; template binding stays `|`-free so oxfmt and eslint are both stable.
…in-cms parity) These are auto-generated by the vite plugins (unplugin-vue-router / unplugin-auto-import) and regenerated by `generate:dts`, which runs first in `yarn ci`. Tracking them just produces churn (e.g. ~900-line typed-router diffs) on every regeneration. admin-cms already gitignores both; match that.
Routine version bumps (already present in the working tree): @anzusystems/common-admin dev build, @tiptap/* 3.27, axios 1.18, vue 3.5.38, vuetify 4.1.2, @sentry/vue, vue-i18n; dev tooling oxfmt 0.55, oxlint 1.70, eslint 10.5, vite, vue-tsc, cypress, @types/node. yarn.lock regenerated to match.
volarname
force-pushed
the
feature/#85491/upgrade
branch
from
June 17, 2026 09:50
3b3c9a9 to
89f5aed
Compare
a8da3a0 migrated to props that don't exist in the labs v2 API (item-factory/manage-delete/update-position/@added/@add). Vue treats unknown props/events as silent fall-through, so it type-checked but the Add actions in podcast export-data and asset distributions were dead at runtime, and none of the consumer recipe was applied. - podcast: drop dead props, restore add via external button + dialog (cancel removes the new row), sort exportData by position at ingress, renumber + adopt response + commit() to re-baseline on save, gate form on !detailLoading - asset distributions: hide built-in add, add external button opening the type-select dialog - distributionCategorySelect: migrate off raw useSortable to inline ASortableListEditor; validateAll() save gate, position sort at ingress, renumber + temp-id strip (id stays '' for new in the payload) + response adopt + commit() on save yarn ci green.
New export-data rows carry a negative temp id for the list-editor key, but core-dam's deserializer treats a non-zero unknown id as a reference to an existing entity (Doctrine then fails with a cascade-persist error on Podcast#exportData). Map negative temp ids to 0 in the save payload so the backend creates them, matching the pre-migration convention and the DistributionCategoryOption handling. Verified end-to-end: add export-data -> save -> 200.
Author ids are UUIDs (DocId), so sorting by id produced an arbitrary order. Both the author list (useAuthorListActions) and the author select autocomplete (useAuthorSelectActions) hard-set pagination.sortBy to 'id' on non-text fetches; default them to createdAt so the newest authors show first, while keeping relevance ordering for fulltext search.
…ted-at fix(author): order author list by createdAt instead of id
Route pluralization in #85491 left many singular cy.visit/urlContains targets that now 404 (no redirect layer). Update asset, podcast, video-show, user, public-export and distribution-category-select detail paths plus nav hrefs to the plural routes. API URLs are left unchanged.
The "Najkratšia dimenzia" (shortestDimensionFrom/Until) filter was sent to the search API but core-dam's AssetQueryFactory never applies it (no ES clause, field not indexed), so it silently did nothing. Remove the dead field from the asset list filter config, form and locales.
Conflict in author/composables/authorActions.ts (moved to src/domains on this branch): kept the new labs-API version. Preserved main's PR #257 intent (order author lists by createdAt): AuthorDatatable.vue now usePagination('createdAt') instead of SORT_BY_ID. Author select autocomplete sort stays on common-admin default (pagination built there, not controllable from admin-dam).
… dev-1782073999 Mirror the admin-cms no-restricted-syntax guard — a bare validateAll() (incl. the awaited form) reveals row errors but does NOT block the save, letting a collapsed invalid row slip through (QA 85050). Bump the @anzusystems/common-admin dev pin to the current labs build (widened ListEditorValidationScope). Audit found no validate-gate bug in admin-dam's list-editor consumers (DistributionCategorySelect gates via the callback; Podcast + asset Distribution are dialog-based).
- BUG-01: serve index.html for the exact /assets path so the main grid no longer returns 403 on hard load / refresh / deep-link (the SPA route collided with the Vite dist/assets/ build dir under nginx try_files) - BUG-02: distribution-category create dialog no longer hangs on an infinite spinner when the category-select fetch fails; the loader clears and the standard error alert is shown (finally reset in prepareData) - BUG-03: add missing sk/en coreDam.*.meta.create i18n keys for podcastEpisode, authorCleanPhrase and publicExport (dialog titles no longer render the raw key) - BUG-05: provide DatatablePaginationKey in VoiceBindingsList so the voice bindings sub-list no longer throws "Incorrect provide/inject config." on the voice-family detail - Disable filter URL-hash population and localStorage persistence on all lists (useFilterHelpers populateUrlParams:false, storeFiltersLocalStorage:false); bookmarking/URL-restoring filter state is unsafe in admin-dam because the ext-system/licence context lives outside the filter and is not serialized
- Render active-filter chips (common-admin FiltersSelected) in a bar under the toolbar on /assets, teleported from the sidebar filter's provide scope - Exclude the `type` filter from the chips (render.selected: false, it has the dedicated toolbar type toggles) - Wire the sidebar reset button to also clear the chips Bump @anzusystems/common-admin to 1.47.0-beta.dev-1784059866: adds the FiltersSelected export, the render.selected filter-field option, the AFilterWrapperSidebar reset that clears the selected-filter chips, and Enter-to-submit for the sidebar filter.
…chunks, dev deps)
TomasHermanek
approved these changes
Jul 21, 2026
added 8 commits
August 7, 2026 18:55
…85491) Fixes 8 of the 10 issues from the QA report. #1 and #8 needed no code change (both are intentional: the shortestDimension filter was dead — core-dam's AssetQueryFactory never applied it — and the from/until date pair was consolidated into one AFilterTimeInterval range control that still exposes both bounds via its Custom option). - #5/#6 (blocker): drop the wrong `apiName: 'name'` on the distributionCategorySelect service-slug filter. The entity is filterable by `serviceSlug`, so `filter_*[name]` made core-dam return 500, which broke opening/creating a distribution category and the "Meno" list filter. - #7: give the anzuUser id/email/enabled/lastName filters a `type`. Without it createFilter defaults to 'custom' and FilterDetailItem renders AFilterEmpty — the bare field name with no control. - #3: add `render: { skip: true }` to the field bound in each `#search` slot, so it is no longer auto-rendered a second time in the advanced panel (11 configs). - #4: add a `#search` slot to the 7 list filters that had none, so they get a main filter bar again instead of only the "More" button; restore enable-top/#top for the mandatory `type` on both distribution-category pages, and hide-more on assetLicenceGroup. - #9: build the distribution filter store per call instead of sharing one module-level singleton. DistributionBlockedBy writes distributionServicesIn/NotIn into it and never clears them, so the create dialog's refetch emitted a self-contradictory `eq X + notIn X` query, and the sidebar list reusing the same store came back empty until a full page reload. - #10: guard JobResourceChip against an unregistered job resource — getJobResourceOption is a plain .find() and returns undefined, so `option.title` threw on /jobs. - #2: re-tint the active-filter chips from the Vuetify theme tokens in dark theme; common-admin hardcodes a white chip on a light container with no dark variant. Also updates dependencies (common-admin, vuetify, vue, tiptap, oxlint/oxfmt, cypress, vue-tsc) and applies the resulting lint/format fixes.
- distribution-category-selects: put `serviceSlug` ("Meno") in the main filter
bar instead of `id`. `id` is a hidden datatable column
(datatableHiddenColumns = ['id']), so the restored search bar was filtering by
a field the user cannot see, and it was inconsistent with the sibling
distribution-categories page which searches by `name`. `id` stays available
under "More".
- asset detail distribution panel: wrap getList in try/catch/finally. A failing
fetch left showLoader() on forever — the panel span forever with no error —
and the rejection propagated out of the component unhandled. Reproduced
against devel by forcing the endpoint to 500.
…rs (#85491) - DistributionCategoryWidget: wrap the category fetch in try/catch/finally. Same defect as the distribution sidebar — a failed request left the widget loading forever and swallowed the error. - en/common/model.json: override common-admin's filterPlaceholder, which ships Slovak strings in its English bundle. Can be dropped once a common-admin release carrying the upstream fix is picked up. - Trim the two comments added earlier down to one line each.
common-admin 1.47.0-beta.dev-1784059874 ships both fixes, so the local shadows are dead weight: the dark-theme chip stylesheet and the English filterPlaceholder override. Verified on devel that the library rules apply on their own.
…ield (#85491) QA reported the jobs "Ukončenie" filter as removed (#8) and the assets date filter as reduced to a single field (#1). Neither bound was actually lost: startedAtFrom/startedAtUntil (and createdAtFrom/Until) are the two ends of one range and are both reachable through the control's Custom option. The merged control just kept the "from" label, which hid that. Relabel both to the "od - do" wording admin-cms already uses for every range filter. Also drop the `licences` asset filter field. Same dead-filter trap that #1 was about: core-dam's AssetQueryFactory never reads it, so the API silently returns unfiltered results (verified: an unknown licence id changes nothing, while codecName correctly narrows to zero). It has no UI today, so removing it only prevents someone from wiring up a control that would quietly do nothing.
Audit of both locales. Key parity, ordering and nesting are now identical
across all 35 sk/en file pairs (809 keys each).
User-visible breakage:
- en/error/*: 15 API error messages were placeholder text (the key name plus
" error") and were shown to users on every forbidden-operation response.
- en asset list: all 8 table headers were raw lowercase field names.
- en distribution: showAdvanced and hideAdvanced both read "Create distribution",
so the toggle never changed its label.
- sk assetLicence: the internal-rule labels were half English and ungrammatical
("Aktívny processing interné", "Procesuj príznak interné od").
Also fixed: leftover English inside Slovak strings (request, Chunky, Similarity
boost); Slovak diacritics and grammar (Klúčové→Kľúčové, Systémova→Systémová,
kontaktuje→kontaktujte, plural endings); English labels that were raw field or
PHP class names, normalised to sentence case; and inconsistent wording where one
concept had two names.
"Meno" now means a person's given name only — entities use "Názov"; author and
user first name intentionally keep "Meno". The login failure alert no longer
claims a specific cause, because it is raised from a catch-all block.
Deliberately left alone: "Appka" and "Video relácie", both consistent across the
app and judged intentional style.
…491) The ordering dropdown was migrated to @anzusystems/common-admin/labs, whose `variant` prop defaults to 'id' where the previous non-labs component defaulted to 'default' (= createdAt). Lists that pass no variant therefore silently switched from ordering by creation date to ordering by id, which QA saw as "Najstaršie" not sorting by date and as the two options being swapped. Sorting by id stays the convention where it is meaningful — it is the indexed primary key and a higher id means a newer row. Only lists where id is provably not chronological move to createdAt: - imported data, where createdAt comes from the source system and does not follow the id sequence (user, anzuUser, assetLicence, assetLicenceGroup, extSystem) — verified against the API, id order and createdAt order differ - UUID ids, where the data mixes UUIDv6 and UUIDv7 so lexical order is not chronological at all (distributionCategory, distributionCategorySelect, author, keyword) permissionGroup, job, publicExport, authorCleanPhrase and podcastEpisode keep id: their id order matches createdAt and they are already self-consistent. Also fixed: - keyword: every fetch overwrote the sort with a hardcoded createdAt ASC, so the list ignored the dropdown and could never show newest first. The sort is now dropped only while a text search is active, and the user's choice is restored when the search is cleared. - author: the same relevance behaviour had been lost entirely in the migration, so a text search still ordered by date instead of by score. - videoShowEpisode: the list loads by position but the dropdown offered only id, so its label claimed something the list did not do. Added a "by position" option matching the actual initial sort. - ttsNarrationRequest: started with no sort while showing an id-based label. - distributionCategory: the id filter was typed as integer although the entity id is a UUID, and a second category-select fetch path still pinned id. Also bumps common-admin and dev dependencies.
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Added
/assets(reuses common-adminFiltersSelected, teleported from the sidebar scope). Thetypefilter is excluded (it has the dedicated toolbar toggles); the reset button clears the chips; pressing Enter in any sidebar field submits the filter.mainFileInternalasset filter + internal-image support (#73441, #84581)..oxlintrc.json,.oxfmtrc.json,format/lint:oxlintscripts)..browserslistrc,browserslist:update),build.target: es2019.flat/recommended-v4).vue/vue-router/pinia/useI18n/useVuelidate+ a curated set of common-admin helpers/types; generatedsrc/auto-imports.d.ts. Removed ~6.6k lines of import boilerplate across ~530 files.vue-router/vite, generatedsrc/typed-router.d.ts,scripts/generate-dts.mjs+generate:dts) + local ESLint ruleanzu-local/valid-route-namevalidating route-name literals against the typed map.anzu/no-fatal-error-axios-check,anzu/url-params-match-template,anzu/no-deprecated-imports— the last set towarn, 391 hits, cleanup PR pending).validateAll()(no-restricted-syntax) — a bare call discards its boolean and does not block save (QA 85050); callers must gate on it (if (x.validateAll() === false) return) or pass:validation-scope.vue-core,vue-i18n,vuetify,common-admin,tiptap,realtime,sentry,vendor-utilschunks with readable filenames (the 1.6 MB monolith chunk is gone).watch-common-adminVite plugin for local-linked common-admin HMR;build:dev(unminified) script;lint:tscswitched tovue-tsc --build(project references, incremental).<ActionbarWrapper :breadcrumbs>+defineBreadcrumbs(...)(restores multi-level chains, e.g.Podcasts → Podcast detail → Episode).Changed
dark/containprops removed, theme-color alpha syntax changed (rgb(var(--v-theme-X), 0.Y)→rgb(var(--v-theme-X) / Y%)). A@layer vuetify-core.reset { … }block restores the v3-style universal/form-element reset that v4 dropped. Breaking.src/router/routes/(19 files) +ROUTEconstants replaced by a file-basedsrc/pages/tree ((coreDam)/(common)groups, per-pagedefinePage({ meta })); router guards migrated fromnext()callbacks to return values. Breaking./asset→/assets,/user→/users,/author→/authors,/podcast→/podcasts, … (all entities). Breaking: existing bookmarks to old singular URLs now 404 — no redirect layer was added./labsAPI). Imports migrated off the deprecated barrel to@anzusystems/common-admin/labs; filters, datatables, pagination, list-editors and API helpers now use the v2 labs API. Breaking.src/restructure. Newsrc/domains/<system>/<entity>/{api,components,composables,factory,filter,store,types,valueObject}layout (systems:system/,common/,coreDam/) + cross-system generics insrc/shared/. Top-levelsrc/{components,composables,services,stores,types,model,views,utils}/deleted. ~800 filesgit mv-moved (history preserved), ~700 import sites rewritten. Breaking.?.+?? fallback) where it previously could throw on missingDamExtSystemConfig(Item)fields.createdAtinstead ofid.useFilterHelpers(…, { populateUrlParams: false, storeFiltersLocalStorage: false })on all 22 datatables. URL-hash / bookmark restoration is unsafe in admin-dam because the ext-system / licence context lives outside the serialized filter (a bookmark can restore filter values from a different ext-system/licence). (admin-cms keeps it on because its scope is a filter field; admin-dam's isn't.)ROUTE.X.Yreferences (274 spots) replaced with raw route-name literals;ActionbarWrapperuses the strict typed-router types.@vueuse/core/integrationspinned to exact14.2.1;Auth.ts→simpleLogin.ts(case-collision fix);@tsconfig/node22→node24; many files reformatted viaoxfmt.cy.visit()/cy.urlContains()across 33 spec files).^3.11.8→^4.1.5, vue-router^5.0.2→^5.2.0, pinia^3.0.4→^4.0.2, vue3.5.28→3.5.40, vue-i18n^11.2.8→^11.4.7, @anzusystems/common-admin1.47.0-beta.354→1.47.0-beta.dev-1784059866, @tiptap/vue-3^3.19.0→^3.28.0, @sentry/vue^10.38.0→^10.67.0. Dev tooling also bumped (cypress, sass, vue-tsc, @vitejs/plugin-vue, @stylistic/eslint-plugin, @intlify/unplugin-vue-i18n, eslint-plugin-vue) +dotenvadded.Fixed
/assets403 on hard load / refresh / deep-link. The SPA route/assetscollided with the Vite build dirdist/assets/under nginxtry_files; nginx now servesindex.htmlfor/assets(docker/app/local/bin/start-command). Production (Cloudflare Pages) was unaffected.500for the category-select fetch the dialog hung on a loader; it now clears the loader and shows the standard error alert (distributionCategoryActions.ts). (The underlying core-dam 500 is a separate backend task.)coreDam.*.meta.createkeys forpodcastEpisode/authorCleanPhrase/publicExport(they rendered raw keys).VoiceBindingsListnow providesDatatablePaginationKey(fixesIncorrect provide/inject config.thrown on the detail view).distributionCategoryActions/assetLicenceGroupActionsfixed (wrong list/domain route — uncovered by the route-reference audit).Removed
prettier,@vue/eslint-config-prettier) — replaced byoxfmt.src/router/routes/(19 files) +ROUTEconstants;AEmptyRouterViewwrappers.src/{components,composables,services,stores,types,model,views,utils}/(relocated intosrc/domains//src/shared/).dark/containprop usages.shortestDimensionasset filter.