From d54fcdd47f0131303b647f38995d663d7d717340 Mon Sep 17 00:00:00 2001 From: Roma Date: Thu, 18 Sep 2025 17:20:18 +0300 Subject: [PATCH 1/5] fix(global-search): Fixed bugs --- .../filter-chips/filter-chips.component.html | 2 +- .../generic-filter.component.ts | 2 +- .../global-search/global-search.component.ts | 1 - .../resource-card.component.html | 6 + .../reusable-filter.component.html | 4 +- .../reusable-filter.component.ts | 9 - .../shared/mappers/search/search.mapper.ts | 220 +++++++++++------- .../index-card-search-json-api.models.ts | 25 ++ .../shared/models/search/resource.model.ts | 1 + .../shared/services/global-search.service.ts | 21 +- .../global-search/global-search.model.ts | 2 - .../global-search/global-search.selectors.ts | 5 - .../global-search/global-search.state.ts | 5 +- src/assets/i18n/en.json | 3 +- 14 files changed, 177 insertions(+), 129 deletions(-) diff --git a/src/app/shared/components/filter-chips/filter-chips.component.html b/src/app/shared/components/filter-chips/filter-chips.component.html index 0d8091e76..39d424a39 100644 --- a/src/app/shared/components/filter-chips/filter-chips.component.html +++ b/src/app/shared/components/filter-chips/filter-chips.component.html @@ -2,7 +2,7 @@
@for (chip of chips(); track chip.key + chip.value) { option?.label) - .sort((a, b) => a.label.localeCompare(b.label)) + .sort((a, b) => b.cardSearchResultCount - a.cardSearchResultCount) .map((option) => ({ ...option, label: option.label || '', diff --git a/src/app/shared/components/global-search/global-search.component.ts b/src/app/shared/components/global-search/global-search.component.ts index 34921bfc2..7da9c7b40 100644 --- a/src/app/shared/components/global-search/global-search.component.ts +++ b/src/app/shared/components/global-search/global-search.component.ts @@ -87,7 +87,6 @@ export class GlobalSearchComponent implements OnInit, OnDestroy { filters = select(GlobalSearchSelectors.getFilters); filterValues = select(GlobalSearchSelectors.getFilterValues); filterSearchCache = select(GlobalSearchSelectors.getFilterSearchCache); - filterOptionsCache = select(GlobalSearchSelectors.getFilterOptionsCache); sortBy = select(GlobalSearchSelectors.getSortBy); first = select(GlobalSearchSelectors.getFirst); diff --git a/src/app/shared/components/resource-card/resource-card.component.html b/src/app/shared/components/resource-card/resource-card.component.html index e598feca7..57e6968d3 100644 --- a/src/app/shared/components/resource-card/resource-card.component.html +++ b/src/app/shared/components/resource-card/resource-card.component.html @@ -68,6 +68,12 @@

} + @if (resource().context) { +
+

+
+ } + @if ( resource().resourceType === ResourceType.Registration || resource().resourceType === ResourceType.RegistrationComponent diff --git a/src/app/shared/components/reusable-filter/reusable-filter.component.html b/src/app/shared/components/reusable-filter/reusable-filter.component.html index 5cb3ca3fa..7bdbf22f5 100644 --- a/src/app/shared/components/reusable-filter/reusable-filter.component.html +++ b/src/app/shared/components/reusable-filter/reusable-filter.component.html @@ -31,8 +31,8 @@ @if (hasFilterContent(filter)) { obj.id); - return { - absoluteUrl: resourceMetadata['@id'], - resourceType: ResourceType[resourceMetadata.resourceType[0]['@id'] as keyof typeof ResourceType], - name: resourceMetadata.name?.[0]?.['@value'], - title: resourceMetadata.title?.[0]?.['@value'], - fileName: resourceMetadata.fileName?.[0]?.['@value'], - description: resourceMetadata.description?.[0]?.['@value'], + const searchResultItems = searchResultIds.map( + (searchResultId) => + indexCardSearchResponseJsonApi.included!.find( + (item): item is SearchResultJsonApi => item.type === 'search-result' && searchResultId === item.id + )! + ); + const indexCardItems = searchResultItems.map((searchResult) => { + return indexCardSearchResponseJsonApi.included!.find( + (item): item is IndexCardDataJsonApi => + item.type === 'index-card' && item.id === searchResult.relationships.indexCard.data.id + )!; + }); - dateCreated: resourceMetadata.dateCreated?.[0]?.['@value'] - ? new Date(resourceMetadata.dateCreated?.[0]?.['@value']) - : undefined, - dateModified: resourceMetadata.dateModified?.[0]?.['@value'] - ? new Date(resourceMetadata.dateModified?.[0]?.['@value']) - : undefined, - dateWithdrawn: resourceMetadata.dateWithdrawn?.[0]?.['@value'] - ? new Date(resourceMetadata.dateWithdrawn?.[0]?.['@value']) - : undefined, - language: resourceMetadata.language?.[0]?.['@value'], - doi: resourceIdentifier.filter((id) => id.includes('https://doi.org')), - creators: (resourceMetadata.creator ?? []).map((creator) => ({ - absoluteUrl: creator?.['@id'], - name: creator?.name?.[0]?.['@value'], - affiliationAbsoluteUrl: creator.affiliation?.[0]?.['@id'] ?? null, - })), - affiliations: (resourceMetadata.affiliation ?? []).map((affiliation) => ({ - absoluteUrl: affiliation?.['@id'], - name: affiliation?.name?.[0]?.['@value'], - })), - resourceNature: (resourceMetadata.resourceNature ?? null)?.map((r) => r?.displayLabel?.[0]?.['@value'])?.[0], - qualifiedAttribution: (resourceMetadata.qualifiedAttribution ?? []).map((qualifiedAttribution) => ({ - agentId: qualifiedAttribution?.agent?.[0]?.['@id'], - order: +qualifiedAttribution?.['osf:order']?.[0]?.['@value'], - hadRole: qualifiedAttribution.hadRole?.[0]?.['@id'], - })), - identifiers: (resourceMetadata.identifier ?? []).map((obj) => obj['@value']), - provider: (resourceMetadata.publisher ?? null)?.map((publisher) => ({ - absoluteUrl: publisher?.['@id'], - name: publisher.name?.[0]?.['@value'], - }))[0], - isPartOfCollection: (resourceMetadata.isPartOfCollection ?? null)?.map((partOfCollection) => ({ - absoluteUrl: partOfCollection?.['@id'], - name: partOfCollection.title?.[0]?.['@value'], - }))[0], - storageByteCount: resourceMetadata.storageByteCount?.[0]?.['@value'], - storageRegion: resourceMetadata.storageRegion?.[0]?.prefLabel?.[0]?.['@value'], - viewsCount: resourceMetadata.usage?.viewCount?.[0]?.['@value'], - downloadCount: resourceMetadata.usage?.downloadCount?.[0]?.['@value'], - addons: (resourceMetadata.hasOsfAddon ?? null)?.map((addon) => addon.prefLabel?.[0]?.['@value']), - license: (resourceMetadata.rights ?? null)?.map((part) => ({ - absoluteUrl: part?.['@id'], - name: part.name?.[0]?.['@value'], - }))[0], - funders: (resourceMetadata.funder ?? []).map((funder) => ({ - absoluteUrl: funder?.['@id'], - name: funder?.name?.[0]?.['@value'], - })), - isPartOf: (resourceMetadata.isPartOf ?? null)?.map((part) => ({ - absoluteUrl: part?.['@id'], - name: part.title?.[0]?.['@value'], - }))[0], - isContainedBy: (resourceMetadata.isContainedBy ?? null)?.map((isContainedBy) => ({ - absoluteUrl: isContainedBy?.['@id'], - name: isContainedBy?.title?.[0]?.['@value'], - funders: (isContainedBy?.funder ?? []).map((funder) => ({ - absoluteUrl: funder?.['@id'], - name: funder?.name?.[0]?.['@value'], - })), - license: (isContainedBy?.rights ?? null)?.map((part) => ({ - absoluteUrl: part?.['@id'], - name: part.name?.[0]?.['@value'], - }))[0], - creators: (isContainedBy?.creator ?? []).map((creator) => ({ + const resources = []; + for (const indexCard of indexCardItems) { + const resourceMetadata = indexCard.attributes.resourceMetadata; + const resourceIdentifier = indexCard.attributes.resourceIdentifier; + + const searchResultItem = searchResultItems.find( + (searchResult) => searchResult.relationships.indexCard.data.id === indexCard.id + )!; + resources.push({ + absoluteUrl: resourceMetadata['@id'], + resourceType: ResourceType[resourceMetadata.resourceType[0]['@id'] as keyof typeof ResourceType], + name: resourceMetadata.name?.[0]?.['@value'], + title: resourceMetadata.title?.[0]?.['@value'], + fileName: resourceMetadata.fileName?.[0]?.['@value'], + description: resourceMetadata.description?.[0]?.['@value'], + + dateCreated: resourceMetadata.dateCreated?.[0]?.['@value'] + ? new Date(resourceMetadata.dateCreated?.[0]?.['@value']) + : undefined, + dateModified: resourceMetadata.dateModified?.[0]?.['@value'] + ? new Date(resourceMetadata.dateModified?.[0]?.['@value']) + : undefined, + dateWithdrawn: resourceMetadata.dateWithdrawn?.[0]?.['@value'] + ? new Date(resourceMetadata.dateWithdrawn?.[0]?.['@value']) + : undefined, + language: resourceMetadata.language?.[0]?.['@value'], + doi: resourceIdentifier.filter((id) => id.includes('https://doi.org')), + creators: (resourceMetadata.creator ?? []).map((creator) => ({ absoluteUrl: creator?.['@id'], name: creator?.name?.[0]?.['@value'], affiliationAbsoluteUrl: creator.affiliation?.[0]?.['@id'] ?? null, })), - qualifiedAttribution: (isContainedBy?.qualifiedAttribution ?? []).map((qualifiedAttribution) => ({ + affiliations: (resourceMetadata.affiliation ?? []).map((affiliation) => ({ + absoluteUrl: affiliation?.['@id'], + name: affiliation?.name?.[0]?.['@value'], + })), + resourceNature: (resourceMetadata.resourceNature ?? null)?.map((r) => r?.displayLabel?.[0]?.['@value'])?.[0], + qualifiedAttribution: (resourceMetadata.qualifiedAttribution ?? []).map((qualifiedAttribution) => ({ agentId: qualifiedAttribution?.agent?.[0]?.['@id'], order: +qualifiedAttribution?.['osf:order']?.[0]?.['@value'], hadRole: qualifiedAttribution.hadRole?.[0]?.['@id'], })), - }))[0], - statedConflictOfInterest: resourceMetadata.statedConflictOfInterest?.[0]?.['@value'], - registrationTemplate: resourceMetadata.conformsTo?.[0]?.title?.[0]?.['@value'], - hasPreregisteredAnalysisPlan: resourceMetadata.hasPreregisteredAnalysisPlan?.[0]?.['@id'], - hasPreregisteredStudyDesign: resourceMetadata.hasPreregisteredStudyDesign?.[0]?.['@id'], - hasDataResource: resourceMetadata.hasDataResource?.[0]?.['@id'], - hasAnalyticCodeResource: !!resourceMetadata.hasAnalyticCodeResource, - hasMaterialsResource: !!resourceMetadata.hasMaterialsResource, - hasPapersResource: !!resourceMetadata.hasPapersResource, - hasSupplementalResource: !!resourceMetadata.hasSupplementalResource, - }; + identifiers: (resourceMetadata.identifier ?? []).map((obj) => obj['@value']), + provider: (resourceMetadata.publisher ?? null)?.map((publisher) => ({ + absoluteUrl: publisher?.['@id'], + name: publisher.name?.[0]?.['@value'], + }))[0], + isPartOfCollection: (resourceMetadata.isPartOfCollection ?? null)?.map((partOfCollection) => ({ + absoluteUrl: partOfCollection?.['@id'], + name: partOfCollection.title?.[0]?.['@value'], + }))[0], + storageByteCount: resourceMetadata.storageByteCount?.[0]?.['@value'], + storageRegion: resourceMetadata.storageRegion?.[0]?.prefLabel?.[0]?.['@value'], + viewsCount: resourceMetadata.usage?.viewCount?.[0]?.['@value'], + downloadCount: resourceMetadata.usage?.downloadCount?.[0]?.['@value'], + addons: (resourceMetadata.hasOsfAddon ?? null)?.map((addon) => addon.prefLabel?.[0]?.['@value']), + license: (resourceMetadata.rights ?? null)?.map((part) => ({ + absoluteUrl: part?.['@id'], + name: part.name?.[0]?.['@value'], + }))[0], + funders: (resourceMetadata.funder ?? []).map((funder) => ({ + absoluteUrl: funder?.['@id'], + name: funder?.name?.[0]?.['@value'], + })), + isPartOf: (resourceMetadata.isPartOf ?? null)?.map((part) => ({ + absoluteUrl: part?.['@id'], + name: part.title?.[0]?.['@value'], + }))[0], + isContainedBy: (resourceMetadata.isContainedBy ?? null)?.map((isContainedBy) => ({ + absoluteUrl: isContainedBy?.['@id'], + name: isContainedBy?.title?.[0]?.['@value'], + funders: (isContainedBy?.funder ?? []).map((funder) => ({ + absoluteUrl: funder?.['@id'], + name: funder?.name?.[0]?.['@value'], + })), + license: (isContainedBy?.rights ?? null)?.map((part) => ({ + absoluteUrl: part?.['@id'], + name: part.name?.[0]?.['@value'], + }))[0], + creators: (isContainedBy?.creator ?? []).map((creator) => ({ + absoluteUrl: creator?.['@id'], + name: creator?.name?.[0]?.['@value'], + affiliationAbsoluteUrl: creator.affiliation?.[0]?.['@id'] ?? null, + })), + qualifiedAttribution: (isContainedBy?.qualifiedAttribution ?? []).map((qualifiedAttribution) => ({ + agentId: qualifiedAttribution?.agent?.[0]?.['@id'], + order: +qualifiedAttribution?.['osf:order']?.[0]?.['@value'], + hadRole: qualifiedAttribution.hadRole?.[0]?.['@id'], + })), + }))[0], + statedConflictOfInterest: resourceMetadata.statedConflictOfInterest?.[0]?.['@value'], + registrationTemplate: resourceMetadata.conformsTo?.[0]?.title?.[0]?.['@value'], + hasPreregisteredAnalysisPlan: resourceMetadata.hasPreregisteredAnalysisPlan?.[0]?.['@id'], + hasPreregisteredStudyDesign: resourceMetadata.hasPreregisteredStudyDesign?.[0]?.['@id'], + hasDataResource: resourceMetadata.hasDataResource?.[0]?.['@id'], + hasAnalyticCodeResource: !!resourceMetadata.hasAnalyticCodeResource, + hasMaterialsResource: !!resourceMetadata.hasMaterialsResource, + hasPapersResource: !!resourceMetadata.hasPapersResource, + hasSupplementalResource: !!resourceMetadata.hasSupplementalResource, + context: parseContext(searchResultItem), + }); + } + + return resources; +} + +function parseContext(searchResultJsonApi: SearchResultJsonApi) { + const matchEvidence = searchResultJsonApi.attributes?.matchEvidence; + + if (!matchEvidence) return null; + + return matchEvidence + .map((matchEvidence) => { + const propertyLabel = + matchEvidence.propertyPath?.[0]?.displayLabel?.[0]?.['@value'] ?? matchEvidence.propertyPathKey; + + return `${propertyLabel}: ${ + 'matchingHighlight' in matchEvidence ? matchEvidence.matchingHighlight : matchEvidence.matchingIri + }`; + }) + .join('; '); } diff --git a/src/app/shared/models/search/index-card-search-json-api.models.ts b/src/app/shared/models/search/index-card-search-json-api.models.ts index cf8087208..6e5e7e179 100644 --- a/src/app/shared/models/search/index-card-search-json-api.models.ts +++ b/src/app/shared/models/search/index-card-search-json-api.models.ts @@ -42,6 +42,7 @@ export interface SearchResultJsonApi { }; }; attributes?: { + matchEvidence: (IriMatchEvidence | TextMatchEvidence)[]; cardSearchResultCount: number; }; } @@ -116,6 +117,30 @@ interface Creator extends MetadataField { affiliation: MetadataField[]; } +interface IriMatchEvidence { + matchingIri: string; + osfmapPropertyPath: string[]; + propertyPathKey: string; + propertyPath: { + displayLabel: { + '@language': string; + '@value': string; + }[]; + }[]; +} + +interface TextMatchEvidence { + matchingHighlight: string; + osfmapPropertyPath: string[]; + propertyPathKey: string; + propertyPath: { + displayLabel: { + '@language': string; + '@value': string; + }[]; + }[]; +} + interface IsContainedBy extends MetadataField { funder: MetadataField[]; creator: Creator[]; diff --git a/src/app/shared/models/search/resource.model.ts b/src/app/shared/models/search/resource.model.ts index a436b7069..44182fec0 100644 --- a/src/app/shared/models/search/resource.model.ts +++ b/src/app/shared/models/search/resource.model.ts @@ -42,6 +42,7 @@ export interface ResourceModel { hasMaterialsResource: boolean; hasPapersResource: boolean; hasSupplementalResource: boolean; + context: StringOrNull; } export interface IsContainedBy extends AbsoluteUrlName { diff --git a/src/app/shared/services/global-search.service.ts b/src/app/shared/services/global-search.service.ts index b82177089..8dab345a7 100644 --- a/src/app/shared/services/global-search.service.ts +++ b/src/app/shared/services/global-search.service.ts @@ -8,7 +8,6 @@ import { FilterOption, FilterOptionItem, FilterOptionsResponseJsonApi, - IndexCardDataJsonApi, IndexCardSearchResponseJsonApi, ResourcesData, SearchResultJsonApi, @@ -52,7 +51,6 @@ export class GlobalSearchService { options: FilterOption[]; nextUrl?: string; } { - const options: FilterOption[] = []; let nextUrl: string | undefined; const searchResultItems = response.included!.filter( @@ -60,8 +58,7 @@ export class GlobalSearchService { ); const filterOptionItems = response.included!.filter((item): item is FilterOptionItem => item.type === 'index-card'); - options.push(...mapFilterOptions(searchResultItems, filterOptionItems)); - + const options = mapFilterOptions(searchResultItems, filterOptionItems); const searchResultPage = response?.data?.relationships?.['searchResultPage'] as { links?: { next?: { href: string } }; }; @@ -73,20 +70,6 @@ export class GlobalSearchService { } private handleResourcesRawResponse(response: IndexCardSearchResponseJsonApi): ResourcesData { - const searchResultIds = response.data.relationships.searchResultPage.data.map((obj) => obj.id); - - const searchResultItems = searchResultIds.map( - (searchResultId) => - response.included!.find( - (item): item is SearchResultJsonApi => item.type === 'search-result' && searchResultId === item.id - )! - ); - const indexCardItems = searchResultItems.map((searchResult) => { - return response.included!.find( - (item): item is IndexCardDataJsonApi => - item.type === 'index-card' && item.id === searchResult.relationships.indexCard.data.id - )!; - }); const relatedPropertyPathItems = response.included!.filter( (item): item is RelatedPropertyPathItem => item.type === 'related-property-path' ); @@ -94,7 +77,7 @@ export class GlobalSearchService { const appliedFilters: AppliedFilter[] = response.data?.attributes?.cardSearchFilter || []; return { - resources: indexCardItems.map((item) => MapResources(item)), + resources: MapResources(response), filters: CombinedFilterMapper(appliedFilters, relatedPropertyPathItems), count: response.data.attributes.totalResultCount, self: response.data.links.self, diff --git a/src/app/shared/stores/global-search/global-search.model.ts b/src/app/shared/stores/global-search/global-search.model.ts index 98de2e0b3..5f7680772 100644 --- a/src/app/shared/stores/global-search/global-search.model.ts +++ b/src/app/shared/stores/global-search/global-search.model.ts @@ -13,7 +13,6 @@ export interface GlobalSearchStateModel { resourcesCount: number; searchText: StringOrNull; sortBy: string; - self: string; first: StringOrNull; next: StringOrNull; previous: StringOrNull; @@ -36,7 +35,6 @@ export const GLOBAL_SEARCH_STATE_DEFAULTS = { searchText: '', sortBy: '-relevance', resourceType: ResourceType.Null, - self: '', first: null, next: null, previous: null, diff --git a/src/app/shared/stores/global-search/global-search.selectors.ts b/src/app/shared/stores/global-search/global-search.selectors.ts index ec60a0742..f7c3a8a1a 100644 --- a/src/app/shared/stores/global-search/global-search.selectors.ts +++ b/src/app/shared/stores/global-search/global-search.selectors.ts @@ -38,11 +38,6 @@ export class GlobalSearchSelectors { return state.resourceType; } - @Selector([GlobalSearchState]) - static getSelf(state: GlobalSearchStateModel): string { - return state.self; - } - @Selector([GlobalSearchState]) static getFirst(state: GlobalSearchStateModel): StringOrNull { return state.first; diff --git a/src/app/shared/stores/global-search/global-search.state.ts b/src/app/shared/stores/global-search/global-search.state.ts index 78126bc54..3435dd175 100644 --- a/src/app/shared/stores/global-search/global-search.state.ts +++ b/src/app/shared/stores/global-search/global-search.state.ts @@ -254,6 +254,10 @@ export class GlobalSearchState { @Action(SetResourceType) setResourceType(ctx: StateContext, action: SetResourceType) { ctx.patchState({ resourceType: action.type }); + ctx.patchState({ filterOptionsCache: {} }); + ctx.patchState({ filterValues: {} }); + ctx.patchState({ filterSearchCache: {} }); + ctx.patchState({ filterPaginationCache: {} }); } @Action(ResetSearchState) @@ -274,7 +278,6 @@ export class GlobalSearchState { resources: { data: response.resources, isLoading: false, error: null }, filters: filtersWithCachedOptions, resourcesCount: response.count, - self: response.self, first: response.first, next: response.next, previous: response.previous, diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 5a3122a5f..d43d2a21a 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -2614,6 +2614,7 @@ "description": "Description:", "provider": "Provider:", "license": "License:", + "context": "Context", "registrationTemplate": "Registration Template:", "conflictOfInterestResponse": "Conflict of Interest response:", "associatedData": "Associated data:", @@ -2950,4 +2951,4 @@ "software": "Software", "other": "Other" } -} \ No newline at end of file +} From 2ebf9574411656ceaba45a6b6249808bff2bee2f Mon Sep 17 00:00:00 2001 From: Roma Date: Thu, 18 Sep 2025 18:46:19 +0300 Subject: [PATCH 2/5] fix(global-search): Fixed error when no search results --- src/app/shared/services/global-search.service.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/shared/services/global-search.service.ts b/src/app/shared/services/global-search.service.ts index 8dab345a7..335d0fe8c 100644 --- a/src/app/shared/services/global-search.service.ts +++ b/src/app/shared/services/global-search.service.ts @@ -53,10 +53,10 @@ export class GlobalSearchService { } { let nextUrl: string | undefined; - const searchResultItems = response.included!.filter( - (item): item is SearchResultJsonApi => item.type === 'search-result' - ); - const filterOptionItems = response.included!.filter((item): item is FilterOptionItem => item.type === 'index-card'); + const searchResultItems = + response.included?.filter((item): item is SearchResultJsonApi => item.type === 'search-result') ?? []; + const filterOptionItems = + response.included?.filter((item): item is FilterOptionItem => item.type === 'index-card') ?? []; const options = mapFilterOptions(searchResultItems, filterOptionItems); const searchResultPage = response?.data?.relationships?.['searchResultPage'] as { From 29770598cbf988f8cbccd76287d804eb5c4b4166 Mon Sep 17 00:00:00 2001 From: Roma Date: Thu, 18 Sep 2025 18:52:29 +0300 Subject: [PATCH 3/5] fix(submissions-sort): Fixed sorting for registration submissions --- .../moderation/constants/registry-sort-options.const.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/features/moderation/constants/registry-sort-options.const.ts b/src/app/features/moderation/constants/registry-sort-options.const.ts index 7eccf69a8..0e75886a3 100644 --- a/src/app/features/moderation/constants/registry-sort-options.const.ts +++ b/src/app/features/moderation/constants/registry-sort-options.const.ts @@ -13,10 +13,10 @@ export const REGISTRY_SORT_OPTIONS: CustomOption[] = [ }, { value: RegistrySort.RegisteredNewest, - label: 'moderation.sortOption.oldest', + label: 'moderation.sortOption.newest', }, { value: RegistrySort.RegisteredOldest, - label: 'moderation.sortOption.newest', + label: 'moderation.sortOption.oldest', }, ]; From 51738801cf2525eacd0a008ba0c4f53e6065c58e Mon Sep 17 00:00:00 2001 From: Roma Date: Thu, 18 Sep 2025 19:09:45 +0300 Subject: [PATCH 4/5] fix(institution-dashboard): Added overflow ellipsis for long column content --- .../admin-table/admin-table.component.html | 76 +++++++++---------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/src/app/features/admin-institutions/components/admin-table/admin-table.component.html b/src/app/features/admin-institutions/components/admin-table/admin-table.component.html index 5aad43925..6e2ad3182 100644 --- a/src/app/features/admin-institutions/components/admin-table/admin-table.component.html +++ b/src/app/features/admin-institutions/components/admin-table/admin-table.component.html @@ -108,24 +108,20 @@ } @else { @for (col of columns; track col.field) { - -
- @let currentColumnField = rowData[col.field]; - @if (col.isLink && isLink(currentColumnField)) { - - @if (col.dateFormat) { - {{ getCellValue(currentColumnField) | date: col.dateFormat }} - } @else { - {{ getCellValue(currentColumnField) }} - } - - } @else if (col.isLink && col.isArray && isLinkArray(currentColumnField)) { -
- @for (link of currentColumnField; track $index) { + + @let currentColumnField = rowData[col.field]; + @if (col.isLink && isLink(currentColumnField)) { + + @if (col.dateFormat) { + {{ getCellValue(currentColumnField) | date: col.dateFormat }} + } @else { + {{ getCellValue(currentColumnField) }} + } + + } @else if (col.isLink && col.isArray && isLinkArray(currentColumnField)) { +
+ @for (link of currentColumnField; track $index) { +
{{ link.text }}{{ $last ? '' : ',' }} @@ -140,30 +136,32 @@ (onClick)="onIconClick(rowData, col, $index)" /> } - } -
- } @else { - @if (col.dateFormat && currentColumnField) { - {{ getCellValue(currentColumnField) | date: col.dateFormat }} - } @else if (!col.dateFormat && currentColumnField) { - {{ getCellValue(currentColumnField) }} - } @else { - {{ currentColumnField ?? '-' }} +
} +
+ } @else { + @if (col.dateFormat && currentColumnField) { +

+ {{ getCellValue(currentColumnField) | date: col.dateFormat }} +

+ } @else if (!col.dateFormat && currentColumnField) { +

{{ getCellValue(currentColumnField) }}

+ } @else { +

{{ currentColumnField ?? '-' }}

} + } - @if (col.showIcon && !col.isArray) { - - } -
+ @if (col.showIcon && !col.isArray) { + + } } From 9ae51f669317f62afc7d263b261e798e46ce0d87 Mon Sep 17 00:00:00 2001 From: Roma Date: Thu, 18 Sep 2025 19:27:28 +0300 Subject: [PATCH 5/5] fix(global-search): Fixed order of applying filters --- src/app/shared/stores/global-search/global-search.state.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/app/shared/stores/global-search/global-search.state.ts b/src/app/shared/stores/global-search/global-search.state.ts index 85f85b131..22da0a9a8 100644 --- a/src/app/shared/stores/global-search/global-search.state.ts +++ b/src/app/shared/stores/global-search/global-search.state.ts @@ -300,6 +300,9 @@ export class GlobalSearchState { private buildParamsForIndexCardSearch(state: GlobalSearchStateModel): Record { const filtersParams: Record = {}; + Object.entries(state.defaultFilterValues).forEach(([key, value]) => { + filtersParams[`cardSearchFilter[${key}][]`] = value; + }); Object.entries(state.filterValues).forEach(([key, value]) => { if (value) { const filterDefinition = state.filters.find((f) => f.key === key); @@ -322,10 +325,6 @@ export class GlobalSearchState { const sortParam = sortBy.includes('count') && !sortBy.includes('relevance') ? 'sort[integer-value]' : 'sort'; filtersParams[sortParam] = sortBy; - Object.entries(state.defaultFilterValues).forEach(([key, value]) => { - filtersParams[`cardSearchFilter[${key}][]`] = value; - }); - return filtersParams; } }