UFAL/Release 2026 july 02#1342
Merged
Merged
Conversation
* used stahnout instead of odstranit * Update confirmation text for withdrawal action * removed two empty lines * added empty lines as in origin * removed spaces --------- Co-authored-by: Kasinhou <129340513+Kasinhou@users.noreply.github.com>
…on (#1209) * renamed dspace-import to dspace-import-clarin * removed unwanted changes
* Preserve parameters when creating similar process * Extract duplicate deep copy logic into helper * Fix redundant parameter logic prevent empty accumulation
* Override pagesize and display all versions * Changed hardcoded variable --------- Co-authored-by: Matus Kasak <matus.kasak@dataquest.sk>
(cherry picked from commit 5465283)
#1189) * Rewrite OAI links in static page HTML with rest.baseUrl Updated StaticPageComponent to rewrite OAI links in loaded HTML content to use the configured rest.baseUrl, ensuring correct API endpoint references. Added comprehensive tests to verify link rewriting, handling of missing baseUrl, avoidance of double slashes, and cases with no OAI links. * Remove unused ComponentFixture import in test Cleaned up the static-page.component.spec.ts file by removing the unused ComponentFixture import to improve code clarity. * Fix OAI URL construction and improve test coverage Corrects the construction of the OAI URL in StaticPageComponent to avoid double slashes by removing the extra slash in the base URL. Also updates the unit test to properly instantiate the component and check its creation. (cherry picked from commit cb86d07) Co-authored-by: Amad Ul Hassan <hassan@ufal.mff.cuni.cz>
Use dspace-import-clarin path instead of dspace-import
Removed unnecessary comments and improved logging for volume removal.
#1222) * Use `dspace:dspace` permissions for the assetstore - not ubuntu:ubuntu * Change permissions as root
…dpoint (#1215) * fix: generate correct curl download URLs using backend handle endpoint Updates the curl command generation to use the new backend endpoint GET /api/core/bitstreams/handle/{prefix}/{suffix}/{filename} instead of the non-existent /api/bitstream/{handle}/{seq}/{filename}. Key changes: - Uses correct backend endpoint path: /core/bitstreams/handle/{handle}/ - Removes unnecessary sequence index from URLs (uses filename only) - Quotes the URL to prevent shell brace expansion - For single file, uses -o with explicit filename Fixes: #1210 * Fixed formatting of the file names * fix: use -o with real filename to avoid percent-encoded names from curl -O curl -O uses the URL path as the saved filename, so percent-encoded characters (e.g. %20, %2B, %28) stay encoded in the output file. Now generates separate 'curl -o realname url' for each file joined with &&, ensuring files are saved with their actual names. * fix: use curl -OJ with brace expansion for compact download command * removed duplicates logic * fix: use curl -o instead of -OJ to fix non-ASCII filenames on Windows curl -J (Content-Disposition) cannot create files with non-ASCII characters on Windows because it interprets the header bytes using the console code page. Changed to curl -o filename url format where the shell passes the filename directly to the OS, correctly handling Unicode on all platforms. Also added tests for UTF-8 filenames and double-quote escaping. * fix: use inline encodeURIComponent instead of encodeRFC3986URIComponent encodeRFC3986URIComponent calls decodeURIComponent first, which throws URIError on filenames containing a literal percent sign (e.g. '100% done.txt') because '%' followed by non-hex chars is not a valid escape sequence. Replaced with inline encodeURIComponent() + parentheses encoding directly on the raw filename. Added test for literal percent sign in filenames. * fix: restore brace expansion {} in curl URL with -o for filenames curl command now uses brace expansion for compact URL: curl -o file1 -o file2 baseUrl{/encoded1,/encoded2} This combines: - {} brace expansion in the URL (compact, one URL for all files) - -o flags with real filenames (handles UTF-8 correctly via shell) * test: add complex filename test (diacritics, plus, hash, unmatched paren) New FE test for 'Media (+)#9) ano' verifying correct URL encoding in brace expansion and real filename in -o flag. * fix: use separate -o url pairs instead of curl brace expansion curl URL globbing ({}) does NOT support per-file -o flags. When using curl -o f1 -o f2 url{/a,/b} curl maps the -o flags to URL arguments, not to globbed expansions, resulting in 'Got more output options than URLs' and only one file saved. Changed to separate -o + URL pairs per file: curl -o file1 url/file1 -o file2 url/file2 Updated all 12 test expectations to match. * feat: show curl command in modal dialog with copy button Replace inline command display with a centered NgbModal (size: lg) that shows the curl command in a scrollable pre block. Includes a copy-to-clipboard button with visual feedback (checkmark + 'Copied!' for 2s). - Added NgbModal injection and openCommandModal()/copyCommand() methods - Removed old isCommandLineVisible toggle and #command-div hover styles - Added i18n keys for en, cs, de (copy/copied/close) - Updated spec to import NgbModalModule * Revert unnecessary changes * Address Copilot review suggestions: accessibility, security, test fixes - Reset canShowCurlDownload at start of generateCurlCommand() - Add aria-labelledby to modal for screen reader accessibility - Add .catch() to navigator.clipboard.writeText() for error handling - Escape dollar signs and backticks in filenames for shell safety - Fix ConfigurationDataService mock to return RemoteData-shaped object - Add tests for canShowCurlDownload reset and shell injection protection * fix: add fakeAsync/tick to CC license test for debounced getCcLicenseLink --------- Co-authored-by: Paurikova2 <michaela.paurikova@dataquest.sk>
* fix: resolve duplicate HTML element IDs across pages * fix: use [attr.*] binding syntax for aria-* attributes in templates * fix: revert dynamic form ID changes to fix e2e test failures Reverts DsDynamicFormLayoutService and all form template changes that were appending _N suffixes to form element IDs, breaking Cypress e2e selectors like input#dc_title and label[for=local_hasCMDI]. Only static HTML duplicate ID fixes are retained (pagination, ds-select, epeople-registry, etc.) along with aria-* attribute binding fixes. * fix: address Copilot review comments - sanitize bundleName for IDs, remove invalid file-tree ID, fix conditional aria-describedby --------- Co-authored-by: Matus Kasak <matus.kasak@dataquest.sk>
…ding (#1231) * Force fresh bitstream fetch to avoid stale SSR 404s * Separate bundle follow links to prevent invalid bundle/item/primaryBitstream path * removed unwanted changes
* Resolve duplicate HTML IDs in submission form. * refactor for unique ID registry * fix: remove unused baseId param from release in UniqueIdRegistry * fix: propagate unique ID from container to child form controls for accessibility * fix: recycle released suffixes in UniqueIdRegistry to preserve stable IDs across re-renders * refactor: deduplicate UniqueIdRegistry usage, store instanceKey, and add unit tests * Refactored the code to make this fix more simple * Updated components to make IT pass * refactor: replace UniqueIdRegistry with inline static counter for unique form IDs * Add tests to verify _idState cleanup and reuse of base id after ngOnDestroy --------- Co-authored-by: Matus Kasak <matus.kasak@dataquest.sk> Co-authored-by: milanmajchrak <milan.majchrak@dataquest.sk>
…lling UFAL/Refactor running rest tests in deploy
* fix: include dc_identifier in ViewTrackerResolverService event properties for Matomo custom dimensions * Fixed linting error
Co-authored-by: Matus Kasak <matus.kasak@dataquest.sk>
Co-authored-by: Matus Kasak <matus.kasak@dataquest.sk>
* Improve back navigation logic in ItemComponent (ufal#80) * Improve back navigation logic in ItemComponent Enhances the navigation logic to use window.history.back() when the previous URL does not match the expected route pattern. Also updates the back button visibility filter to allow empty URLs. * Fix back button visibility logic in ItemComponent Updated the showBackButton observable to correctly determine when the back button should be shown based on the previous route. Also added ngOnInit call in the related test to ensure proper initialization. * Remove unused 'filter' import from item.component.ts The 'filter' operator from 'rxjs/operators' was imported but not used in item.component.ts. This commit cleans up the import statements. * Add session storage for previous URL in item page Introduces generic methods in RouteService to store and retrieve URLs in session storage. ItemComponent now uses session storage to persist and retrieve the previous URL for improved back navigation, falling back to browser history if no valid URL is found. * Add session URL helpers to RouteService stubs in tests Extended RouteService stubs in test files to include storeUrlInSession and getUrlFromSession methods, matching the interface used by ItemComponent and related tests. This ensures test mocks are up-to-date with the service's API. * Simplify back navigation logic in ItemComponent Removed conditional check for previous URL and always navigate using router.navigateByUrl with storedPreviousUrl. (cherry picked from commit 5dfb106) * Treat /home as previous route and add tests Include "/home" in ItemComponent's previousRoute regex so the back button is shown for home. Add unit tests to verify the back button appears for a home previous URL and that a home previous URL is prioritized over a session-stored URL (ensuring the session is updated and navigation uses the home URL). (cherry picked from commit 3eb32e5) --------- Co-authored-by: Amad Ul Hassan <hassan@ufal.mff.cuni.cz>
Reset pagination on search term change (cherry picked from commit aa495d3) Co-authored-by: amadulhaxxani <hassan@ufal.mff.cuni.cz>
…scription.abstract` (#1291) * Updated components to display `dc.description` instead of `dc.description.abstract` * fix(search-results): use dc.description for item description + align tests
* fix(submission): separate CLARIN license payload from sections.license * fix(clarin-license): rename step path to /select, rename DataClarinLicense to ClarinDataLicense, and clean up comments * Updated submission-ui test which check the clarin-license
ufal#124) (#1275) * show ISO code on selection for language field Ensure language autocomplete displays ISO codes consistently after selection and after form reload by handling string values in the input formatter. * removing unnecessary comments removing unnecessary comments * Normalize autocomplete values and add tests Normalize autocomplete values and add tests (cherry picked from commit 940861d) Co-authored-by: Amad Ul Hassan <hassan@ufal.mff.cuni.cz>
… (#1274) * re-evaluate type-bind visibility when bind model loads late Prevent duplicate language fields after hard refresh by running an initial type-bind visibility evaluation and re-evaluating when type bind models are registered later. * handle late type-bind model updates without duplicate setup evaluation Improve type-bind relation subscriptions to attach listeners when bind models register late and avoid double evaluation during initialization. Add tests for late model registration, late value-change reactivity, and single setup evaluation behavior. (cherry picked from commit e5c2c6e) Co-authored-by: Amad Ul Hassan <hassan@ufal.mff.cuni.cz>
* add New version action for archived submission items (ufal#130) * add New version action for archived submission items add New version action for archived submission items * Use shareReplay to cache version draft observable Import shareReplay and apply .pipe(shareReplay(1)) to the version draft observable in ItemActionsComponent. This shares the subscription and caches the latest emission so multiple subscribers won't trigger duplicate work or requests. * Derive new-version tooltip from disable state Use the disableNewVersion$ observable to compute newVersionTooltip$ (with map) and apply shareReplay to disableNewVersion$, instead of calling getVersioningTooltipMessage unconditionally. This avoids invoking the tooltip service when the button is disabled. Added map import and updated unit test to assert the tooltip is derived from the disabled state and that getVersioningTooltipMessage is not called. (cherry picked from commit 3fb57f1) * Use service to get versioning tooltip Replace the inline mapping of disableNewVersion$ to compute the tooltip with dsoVersioningModalService.getVersioningTooltipMessage(this.object, 'item.page.version.hasDraft', 'item.page.version.create'), centralizing tooltip logic in the service. Also remove the now-unused rxjs 'map' import; shareReplay usage for disableNewVersion$ is preserved. * test: update tooltip key expectation for versioning draft state --------- Co-authored-by: Amad Ul Hassan <hassan@ufal.mff.cuni.cz>
…r bitstream upload (#1280) * Refresh file listings on breadcrumb navigation after bitstream upload (ufal#112) * Refresh file listings on breadcrumb navigation after bitstream upload Refresh file listings on breadcrumb navigation after bitstream upload * Move refresh logic to ngOnChanges Move refresh logic to ngOnChanges * Set related requests stale instead of removing cache Set related requests stale instead of removing cache * Use setStaleByHrefSubstring for metadatabitstreams cache Use setStaleByHrefSubstring for metadatabitstreams cache * Add null checks for nested RemoteData access Add null checks for nested RemoteData access * Use local bitstream refs and clear caches Replace uses of this.bitstream with the local bitstream observable in edit-bitstream-page to reference the correct stream when computing image/IIIF/enabled flags. After removing bitstreams, clear relevant caches in item-bitstreams: mark bundle bitstreams hrefs stale and invalidate metadatabitstreams search-by-handle (both encoded and raw variants) so file lists, previews and CLARIN file sections refresh correctly. * Fix memory leak, null guard, and style issues from PR review - PreviewSectionComponent: store and unsubscribe configService subscription in ngOnDestroy to prevent memory leak - ItemBitstreamsComponent: add hasValue() null guard before bundles.forEach() for idiomatic style Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Ondrej Kosarko <kosarko@ufal.mff.cuni.cz> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> (cherry picked from commit 45bacd6) * fix(bitstream): prevent combineLatest blocking when bundle is undefined --------- Co-authored-by: Amad Ul Hassan <hassan@ufal.mff.cuni.cz> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add src/static-files to build assets (ufal#103) * Add src/static-files to build assets Update angular.json to include "src/static-files" in the build assets array so files placed there are copied into the build output. This ensures additional static resources are available at runtime without changing code paths. * Support namespaced/SSR HTML loading; add tests Update HtmlContentService to compose namespaced URLs, build runtime absolute URLs when running on the server (REQUEST/PLATFORM_ID), and centralize HTTP text fetching via getHtmlContent. Ensure APP_CONFIG ui.nameSpace is respected and handle absolute URLs and existing namespace prefixes. Add comprehensive unit tests (html-content.service.spec.ts) covering namespaced/default paths, locale fallback, and error handling. Adjust static-page.component.spec.ts to use a RouterMock with configurable route and add a test asserting the service is called with the route's HTML filename. (cherry picked from commit 4eadd8b) * ufal#93 static pages and not found behavior (ufal#97) * Show 404 error for missing static pages Updated StaticPageComponent to display an inline 404 error message when a static page is not found, matching the PageNotFoundComponent design. Added translations for the new 404 messages in both English and Czech, and set the server response status to 404 for SSR. Removed legacy error page loading logic and updated tests to mock the new ServerResponseService dependency. * Improve static page loading and error handling Refactors static page loading to use a new contentState property ('loading', 'found', 'not-found') for clearer UI state management and error handling. Enhances HtmlContentService with cache-busting and robust fallback logic for localized HTML content. Updates tests and template to reflect new state handling and ensures change detection is triggered after content load or error. * Use any-cast for changeDetector spies Replace bracket-indexing (component['changeDetector']) with (component as any).changeDetector in static-page.component.spec.ts. This updates three occurrences in the change-detection tests so TypeScript accepts spying on detectChanges without index-signature errors. * Make cache-bust deterministic & refactor tests Use a deterministic cache-bust parameter in HtmlContentService.appendCacheBust (avoid Date.now()) and avoid adding the param if it already exists — this keeps the behavior SSR-safe and cache-friendly. Refactor StaticPageComponent unit tests: allow setupTest to accept undefined HTML, return the mocked responseService, and simplify tests by reusing setupTest to remove duplicated test setup code. * Add loading indicator and error logging Show a loading spinner while static page content is fetched and add console.error logging on load failures (includes fileName and URL) to aid debugging. Also simplify HtmlContentService by removing a redundant refetch-on-empty response path that caused an extra network request and special-case 404 handling; a 200 now consistently returns the response body (or empty string). UI behavior for not-found responses remains unchanged. * Use hourly cache-busting query param Replace the fixed cache-bust value ('1') with a dynamic hourly value computed from Date.now()/3600000. This appends a changing query parameter so responses are refreshed hourly (reducing stale content) while keeping the existing query-separator logic intact. Removed the prior comment about a deterministic SSR-safe value. * We don't need to manually duplicate static files when fallback is working correctly * Refactor HTML loading, add loading state & tests Remove cache-busting retry logic from HtmlContentService and simplify loadHtmlContent to a single fetch attempt (returning content on 200, undefined otherwise). Update service unit tests to expect fewer HTTP calls and to not rely on cacheBust query params. Add loading-state handling in StaticPageComponent (reset stale not-found to loading, clear htmlContent at init) and adjust template to avoid rendering the 404 block while async content is pending. Enhance component tests: introduce a createDeferred helper, use fixture.whenStable/detectChanges instead of awaiting ngOnInit directly, and add tests for delayed content resolution and resetting stale not-found state. * Trigger CI rebuild * Use fakeAsync and tick in cc-license spec Wrap the 'getCcLicenseLink' unit test in fakeAsync, add tick(350) and fixture.detectChanges() so the debounced observable has time to emit before the assertion. This ensures the async debounce behavior is handled reliably in the spec. * fixed failing test repeat the pattern that the other tests have --------- Co-authored-by: Ondrej Kosarko <kosarko@ufal.mff.cuni.cz> (cherry picked from commit 4a00c7d) * Fix broken contract link on static about page (ufal#116) * [wip] copilot proposed fix for broken contract link There's an issue with the /static/about page. The underlying html is @src/static-files/about.html ; when I click the link `<a id="distribution-link" href="contract">"Distribution License Agreement"</a>` in a browser (links) with disabled js. It works correctly. But in chrome based browsers something interferes. To give a concrete example https://dspace-dev.ufal.mff.cuni.cz/repository/static/about and clicking the link takes me to https://dspace-dev.ufal.mff.cuni.cz/static/contract (but when I hover over the link I see the correct https://dspace-dev.ufal.mff.cuni.cz/repository/contract). * The no_static_ links don't work without javascript * remove the `no_static_` feature Now all non-fragment, non-dot-relative, non-external links on static pages use the normal app-root internal-link flow * Intercept dot-relative static links StaticPageComponent: simplify link handling to only intercept dot-relative links and resolve them against the static page base URL; removed fragment/external/internal redirection helpers and related code paths. Updated unit tests to reflect the new interception behavior (dot-relative under static route, nested relative resolution, and no interception for fragments or explicit app routes). Updated multiple static HTML files (English and Czech) to prefix internal anchors and links with the static/ path so they resolve correctly when served via the static route. * Fix static page internal links Normalize internal links across static HTML pages to use consistent paths and avoid broken relative references. Replaced occurrences of leading ./ and ../ for routes like discover and contract, and updated fragment links to use static/... (e.g. item-lifecycle, metadata, hplt-dataset-license-1.0). Affected files: src/static-files/cs/deposit.html, src/static-files/cs/faq.html, src/static-files/cs/metadata.html, src/static-files/deposit.html, src/static-files/faq.html, src/static-files/hplt-dataset-license-1.0.html, src/static-files/metadata.html. * Up to date links --------- Co-authored-by: amadulhaxxani <hassan@ufal.mff.cuni.cz> (cherry picked from commit 99e2e71) --------- Co-authored-by: Amad Ul Hassan <hassan@ufal.mff.cuni.cz>
…larin-dspace#114) (#1260) * Display contract even if no collectionId given lists all authorized collections and their licenses * Proper cleanup replaced the nested manual subscriptions in license-contract-page.component.ts with a single RxJS pipeline using tap(...), switchMap(...), and takeUntil(this.destroy$), then completed cleanup in ngOnDestroy(). * fix non unique ids * Guard license stream with EMPTY and stricter check Guard license stream with EMPTY and stricter check * Refactor license contract page and improve collection display (ufal#115) * Initial plan * Add error/loading handling for bogus collectionId in single-collection mode --------- --------- (cherry picked from commit 0ca1429) Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: amadulhaxxani <hassan@ufal.mff.cuni.cz> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: kosarko <1842385+kosarko@users.noreply.github.com>
Deleted the ClarinMatomoStatisticsComponent and its related files, removed its route and module declaration, and cleaned up i18n keys associated with Matomo statistics. This streamlines the codebase by eliminating unused statistics functionality. (cherry picked from commit 1167e19) (cherry picked from commit 812c6e1) Co-authored-by: amadulhaxxani <hassan@ufal.mff.cuni.cz>
Co-authored-by: Matus Kasak <matus.kasak@dataquest.sk>
…#1309) * Make Solr heap tunable via SOLR_HEAP env var Default stays 4g, so no behavior change unless SOLR_HEAP is set. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Add Solr params into quotes Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: milanmajchrak <90026355+milanmajchrak@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Matus Kasak <matus.kasak@dataquest.sk>
…1319) * fix(bitstream): restore item UUID in edit redirect fix(bitstream): restore item UUID in edit redirect * fix(bitstream): improve fallback navigation and error handling fix(bitstream): improve fallback navigation and error handling * proper cleanup on destroy (cherry picked from commit b4d2fac) Co-authored-by: Amad Ul Hassan <hassan@ufal.mff.cuni.cz>
…tems (#1269) * Add 'Add URL bitstream' feature to workspace items Introduce an "Add bitstream from URL" action for workspace items: add a conditional button and modal UI to input a file URL and optional name. Implement component support using ScriptDataService to call the 'file-downloader' script, manage processing state, show success/error notifications, and navigate to the created process detail on success. Add related unit tests (scriptDataService stub, UI visibility, invocation params, success/failure flows) and update English and Czech i18n strings. (cherry picked from commit 65c3a5c) * fix(accessibility): mark decorative icon as aria-hidden --------- Co-authored-by: amadulhaxxani <hassan@ufal.mff.cuni.cz>
* 141 lost license in workflow edit (ufal/clarin-dspace#144) * fix(license): use route aware submission service to crash on workflow item * Remove test-output.log Delete the generated binary test-output.log from the repository to avoid committing test artifacts and reduce repository noise. The file has been removed from the index and will no longer be tracked. * reverting accidental changes reverting accidental changes (cherry picked from commit fb97ec9) * Fix section-license spec for getActualSubmissionItem backport The dtq-dev 'sendRequest should PATCH /sections/<sectionId>/select' spec spied on getActualWorkspaceItem(), which the #144 backport replaced with getActualSubmissionItem() (PATCHing the submission object's self link). Update the spy and href assertion accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Amad Ul Hassan <hassan@ufal.mff.cuni.cz> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* Add lang attributes to description fields Set HTML lang attributes based on metadata language for various description and metadata display elements to improve i18n and accessibility. Updated templates to bind [attr.lang] on spans, links and browse links; metadata-values now passes mdValue.language into render templates; clarin description component now emits per-entry language and value pairs; ClarinItemBoxView stores itemDescriptionLang; SidebarSearchListElement supports descriptionLang with a getDescriptionLang() hook and OrgUnit implementation returns the description language. These changes ensure displayed metadata uses the correct language attribute when available. * Improve accessibility: add ARIA labels & i18n keys Add ARIA attributes and move icon markup to improve screen-reader support across several components. Updated templates to include aria-label on interactive buttons (info, calendar, remove/save/delete/clear actions) and aria-hidden on decorative <i> icons. Adjusted calendar button markup to place the calendar icon inside the button element. Added corresponding i18n keys in many locale JSON5 files so the new labels are translatable (English provided and placeholder entries added across locales; some locales include TODO notes for translation). These changes are focused on accessibility and localization support. * Improve accessibility and semantic headings Replace several presentational heading tags with semantically appropriate heading levels (convert h4/h3/h5/h6 to h2/h3 with existing styling classes) across home, footer and item templates to improve document structure. Add aria-hidden to the hidden repository link and aria-live/aria-atomic to the pagination info for better accessibility. Update footer markup to group links into separate ULs (removing BRs) and adjust SCSS selectors to target both heading elements and .h4 class, plus spacing for stacked lists. Also add TranslateModule.forRoot() to an existing-relation-list-element spec to satisfy translations in tests. * Update cs translations: relation group, license Replace English strings with Czech translations in src/assets/i18n/cs.json5 for the following keys: form.relation-group.save, form.relation-group.delete, form.relation-group.clear, and submission.cc-license.field-info. Improves localization for relation-group actions and the CC license field. * Mark decorative paperclip icon aria-hidden Accessibility tweak: add aria-hidden="true" to the Font Awesome paperclip icon so screen readers ignore the decorative icon. Also replace the non-breaking space inside the <i> tag with a regular space between the icon and the heading text in clarin-files-section.component.html. * Normalize metadata language to BCP 47 for HTML lang attributes PR ufal#139 binds [attr.lang] straight from the DSpace metadata language field, which is stored as Java-style locales (en_US, cs_CZ) or the wildcard *. None of those are valid BCP 47 / HTML lang values, so assistive technology ignores them and the accessibility improvement is inert for the common stored values. Add a single shared metadataLangToBcp47() helper (*/empty/nullish -> null, "_" -> "-") and a thin dsLang pipe that delegates to it. Route all of PR #139's lang bindings through it: the pipe in the seven templates, the helper directly in the three .ts sites. Declare DsLangPipe in the specs that render the pipe (NO_ERRORS_SCHEMA does not suppress missing pipes), including the shared grid element test factory. Add unit specs for the helper and pipe plus a DOM assertion that en_US renders as lang="en-US". * Translate remaining English strings to Czech in cs.json5 --------- (cherry picked from commit cd1c617) Co-authored-by: Amad Ul Hassan <hassan@ufal.mff.cuni.cz> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
* 84 license labels management (ufal#134) * Add PUT and DELETE to ClarinLicenseLabel service Replace BaseDataService with IdentifiableDataService and add PutData/DeleteData support for ClarinLicenseLabel. Wire PutDataImpl and DeleteDataImpl in the constructor, expose put(), delete() and deleteByHref() methods, and update imports (remove BaseDataService, add PutData, DeleteData, IdentifiableDataService and NoContent). Enables updating and deleting Clarin License Labels via the data service. * Add license labels table and placeholders Introduce a new License Labels section in the Clarin license table UI with a table, empty-state row, aria labels, and a ds-loading indicator (src/...component.html). Add CSS rule to size the actions column (src/...component.scss). In the component (src/...component.ts) add placeholder Observables (labels$, loading$) and stub methods editLabel and confirmDeleteLabel that log actions; data loading and wiring will be implemented in a follow-up task. * Add label selection and refresh logic Add selectable labels UI and wiring for label management: - Template: add a radio column with aria labels, mark selected row, disable Edit/Delete unless a label is selected, and adjust colspan for empty state. Edit/Delete buttons now call no-arg handlers. - Component: introduce selectedLabel, labels$ and loading$ BehaviorSubjects, refreshLabels() to fetch all labels via clarinLicenseLabelService.findAll (with loading/error handling), selectLabel() and isSelected() helpers, and call refreshLabels() on init and after label creation. Add ngUnsubscribe and ngOnDestroy to clean up subscriptions (takeUntil). Update scan initial state to use a defaultListState and import SortOptions. - Tests: update spec to provide mockLicenseLabelListRD$ and spy findAll. These changes enable selecting a license label for future edit/delete actions and keep the label list in sync with the backend. * Add license labels management and i18n Replace the static license-labels table with a paginated, RemoteData-driven table and translated headers; add loading state and accessible SR-only labels. Wire up edit and delete flows: open DefineLicenseLabelFormComponent for edits (convert file input, call PUT, notify and refresh) and ConfirmationModalComponent for deletes (call DELETE, notify and refresh). Introduce labelsRD$ stream, pagination options, labelsRefresh$ trigger and initializeLabelsPaginationStream to reactively fetch pages. Enhance DefineLicenseLabelFormComponent to support edit mode (prefill form, boolean extended options, aria/id fixes) and update serializer to accept booleans and legacy string values. Update and extend unit tests to cover edit/delete flows and template changes. Add new English and Czech i18n keys for the labels UI and actions. * Use dedicated i18n key for label load errors Introduce a specific i18n key for license label load failures and use it in the labels pagination stream. Added a labelsLoadErrorKey constant in ClarinLicenseTableComponent and replaced usages of the create-error key when handling load failures. Also added the new "clarin.license.label.load.error" translations to en.json5 and cs.json5. * Refresh licenses after label update Call loadAllLicenses() when a label PUT succeeds so dependent license lists are refreshed. The component now only calls refreshLabels() and loadAllLicenses() if the RemoteData indicates success. Updated unit test to spy on loadAllLicenses and assert it is called on modal submit; adjusted method comment accordingly. * Reload licenses after label deletion When a license label is successfully deleted, also reload the full license list to ensure UI reflects the change. Call loadAllLicenses() alongside refreshLabels() in the component, and update the spec to assert loadAllLicenses() is invoked (adding a spy and expectation). * Hide empty table row while loading Prevent the "no licenses" message from appearing while data is being fetched by adding a loading$ | async check to the empty-row *ngIf in clarin-license-table.component.html. The empty message now only shows when not loading and cLicenseLabels.page is empty, avoiding a flash of the empty state during load. * Disable delete for labels in use with tooltip Prevent deleting license labels that are referenced by any license: template changes wrap the delete button in a span that conditionally shows an ngbTooltip and uses dsBtnDisabled with a conditional click handler. Component logic now loads all licenses (paged) on init, builds a Set of in-use label IDs (inUseLabelIds) and exposes isLabelInUse to drive the UI; helper methods fetchAllLicensePages, rebuildLabelUsageSet and loadAllLicensesForUsage were added along with an allLicensesRD$ stream. Unit tests were extended to cover linked vs unlinked label behavior (disabled state, tooltip, and preventing the confirmation modal), and i18n entries for the disabled-tooltip were added for English and Czech. * Show labels empty row only on successful load Update clarin-license-table template to only render the labels empty-state row when the labels request has succeeded ((labelsRD$ | async)?.hasSucceeded). This prevents the empty message from appearing during failed or pending label requests. Add a unit test that simulates a failed labels request to verify the empty-state row is not shown, and import the needed createFailedRemoteDataObject helper for the test. * Optimize license usage loading and tests Add caching and locking around the expensive full license-usage crawl to avoid redundant requests. Introduce licenseUsageLoaded and licenseUsageLoading flags, a new ensureLicenseUsageLoaded(forceReload) helper, and a forceUsageReload parameter to loadAllLicenses so callers can explicitly invalidate the cache. Update create/edit/delete flows to force a usage reload, and set/clear the loading flags in the usage fetch success/error handlers. Add unit tests to verify that the full usage dataset is loaded only once across repeated reloads and that forcing a reload triggers a new fetch. * F1: disable label Delete until usage crawl completes The in-use set (inUseLabelIds) is empty until the async license usage crawl finishes, so during that window an in-use label's Delete button was briefly enabled. Add a usageReady$ stream that only emits true once the crawl succeeds and gate every row's Delete button on it: all Delete buttons stay disabled (with a "checking usage" tooltip) until usage resolves, after which in-use labels stay disabled and unused ones enable. On failure the buttons stay disabled so there is no unsafe window. Frontend-only mitigation; the usage crawl itself is unchanged. * F2: de-wrap double-nested modal in both license forms Both define-license-form and define-license-label-form nested their own .modal > .modal-dialog > .modal-content inside ng-bootstrap's NgbModalWindow, which already provides those wrappers. The duplicate chrome collapsed ngb's .modal-content and pinned the inner position:fixed .modal to the top of the viewport instead of centering. Remove the redundant inner wrappers so ngb owns the modal chrome, delete the now-dead `.modal { display: ... }` scss workarounds in both forms, fix the `modal-boy` -> `modal-body` typo in define-license-form, and open all four form modals with { centered: true } so the dialog is centered. * F3: surface newly created label without manual paging The labels endpoint lists labels in ascending insertion order and ignores the sort param, so a freshly created label received the highest id and landed on the last pagination page, invisible to the admin after Save. After a successful create, jump the labels table to the last page (derived from the current total plus the one just added) so the new row is shown immediately. * F4: allow clearing a label icon on edit and preview the current icon The label edit form could keep or replace an icon but never remove one, and gave no indication of the current icon. Add a "Remove current icon" checkbox and a small preview (reusing secureImageData) shown in edit mode when the label has an icon. When clear is requested and no new file is chosen, the table sends an empty icon array through the existing PUT path to remove it; selecting a new file still takes precedence. * F5: center the delete-confirmation modal and complete cs.json5 label parity Pass { centered: true } when opening ConfirmationModalComponent from confirmDeleteLabel() so the delete-confirmation dialog is vertically centered like the four license/label form dialogs, removing the top-aligned visual inconsistency. Also add the three Czech translations that were missing from cs.json5 (table.delete.checking-tooltip, edit.icon.preview, edit.icon.clear) so the en/cs label key sets are back in parity. * test: expect centered option in delete-confirmation modal spec The F5 change passes { centered: true } to modalService.open; update the assertion to match so the label delete flow spec passes. --------- Co-authored-by: kosarko <ko_ok@centrum.cz> (cherry picked from commit 87cb7a7) * Disable delete for in-use licenses, add tooltip (ufal#137) * Disable delete for in-use licenses, add tooltip Prevent deleting licenses that are attached to bitstreams by disabling the Delete button and showing a tooltip explaining why. Adds UI markup (ngbTooltip wrapper, aria-label, dsBtnDisabled and guarded click), a new isSelectedLicenseInUse() helper and a check in deleteLicense(). Adds unit tests covering disabled/enabled states and click behavior, and provides i18n strings for English and Czech for the disabled-tooltip. * Use hasNoValue for license id check Replace isNull with hasNoValue when validating selectedLicense.id in deleteLicense to correctly handle undefined/null values. Also add hasNoValue to the imports from shared/empty.util. * Use NgbTooltip instance in delete button spec Update clarin-license-table component spec to import NgbTooltip and retrieve the tooltip instance from the delete wrapper's injector. Replace the previous assertion that inspected the DOM's ng-reflect-ngb-tooltip attribute with an assertion on deleteTooltip.ngbTooltip to verify the expected translation key. This makes the test more robust by avoiding reliance on Angular's rendered reflection attribute. (cherry picked from commit 42c4fcc) * Fix license label issues flagged in code review - Change label icon fallback from selectedLabel.icon to undefined to avoid sending a base64 string when the icon is unchanged - Correct 0‑based page parameter to 1‑based in fetchAllLicensePages - Replace hard‑coded aria-label on modal close button with a translatable key for accessibility --------- Co-authored-by: Amad Ul Hassan <hassan@ufal.mff.cuni.cz>
…) (#1326) * add search icon to community and collection add search icon to community and collection, click should navigate to community/collection pre-selected advance search page add tests to confirm the new navigation * Remove redundant wrapper div from collection/community page Remove redundant wrapper div from collection/community page (cherry picked from commit 385b33d) Co-authored-by: Amad Ul Hassan <hassan@ufal.mff.cuni.cz>
…1338) * test: fix flaky DSDynamicTypeBindRelationService spec (double spyOn) The FormBuilderService mock (getMockFormBuilderService) is a jasmine.createSpyObj, so getTypeBindModel / getTypeBindModelUpdates are already spies. Several specs then call spyOn(...) on them again, which Jasmine rejects with "<spyOn> : getTypeBindModel has already been spied upon". Under Karma/Jasmine's randomized spec order this surfaced intermittently, so the same commit passed some CI runs and failed others. Reconfigure the existing spies via (spy as jasmine.Spy).and.returnValue/callFake(...) instead of re-spying them (the standard idiom for a createSpyObj mock). The spy behaviour per test is identical, so all assertions are unchanged; the illegal double-spyOn is removed, making "already been spied upon" impossible in any order. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test: await TestBed setup in DSDynamicTypeBindRelationService spec Per review: the first beforeEach did `TestBed.configureTestingModule({...}).compileComponents().then();` — the promise was never returned/awaited, so nothing guaranteed the module (and its fresh getMockFormBuilderService() spy mock) was fully set up before each spec, which is the kind of async setup slop that makes the same commit pass some CI runs and fail others. Return the promise so Jasmine awaits it and every spec starts from a fresh, fully-configured module. Complements the spy-reconfiguration fix. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test: reword beforeEach comment (address Copilot review) Replace the colloquial "async setup slop" wording with a clearer description ("letting asynchronous module setup leak between specs"). Comment-only change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…l#157) (#1336) * fix(submission): keep dc.type dropdown display after change (ufal/clarin-dspace#1377 -> ufal#156) The "type of resource" scrollable dropdown blanked out after changing its value when the backend was slow: the reloaded model value came back with an empty display but populated value/authority, so currentValue rendered ''. Fall back to the underlying value when display is empty, matching the existing inputFormatter convention. Add a fakeAsync regression test that drives an empty-display value through group.valueChanges (the real reload entry point) and asserts the rendered input keeps its text, reproducing the original blank-after-latency bug. * test(submission): make empty-display init test deterministic Address Copilot PR review: the init-path test previously relied on isNotEmpty(new VocabularyEntry()) being false so getInitValueFromModel would fall back to the raw model.value. That couples the test to VocabularyEntry having no initialized fields. Stub getInitValueFromModel directly to emit an empty-display value (built bypassing the FFMVO constructor, which would otherwise fill display via `display || value`), so the test deterministically exercises the setCurrentValue fallback it is meant to guard. * test(type-bind): stop re-spying mock methods that are already spies The DSDynamicTypeBindRelationService spec called spyOn() on formBuilderService.getTypeBindModel / getTypeBindModelUpdates, but the mock (getMockFormBuilderService) already creates those as jasmine spies via createSpyObj. Because src/test.ts runs with teardown.destroyAfterEach:false and karma randomizes spec order, certain orderings hit the second spy installation and threw "getTypeBindModel has already been spied upon", failing 6 tests non-deterministically (green on clarin-v7, red here only due to a different random ordering). Reconfigure the existing spies with .and.* instead of re-spying, which is order-independent. (cherry picked from commit 8580e90)
…ular into customer/lindat
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Problem description
Analysis
(Write here, if there is needed describe some specific problem. Erase it, when it is not needed.)
Problems
(Write here, if some unexpected problems occur during solving issues. Erase it, when it is not needed.)
Sync verification
If en.json5 or cs.json5 translation files were updated:
yarn run sync-i18n -t src/assets/i18n/cs.json5 -ito synchronize messages, and changes are included in this PR.Manual Testing (if applicable)
Copilot review