Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/app/core/handle/HandleResourceTypeIdserializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export const HandleResourceTypeIdSerializer = {
return 3;
case COMMUNITY:
return 4;
case SITE:
return 5;
default:
return null;
}
Expand All @@ -27,8 +29,10 @@ export const HandleResourceTypeIdSerializer = {
return COLLECTION;
case 4:
return COMMUNITY;
default:
case 5:
return SITE;
default:
return null;
}
}
};
1 change: 1 addition & 0 deletions src/app/core/handle/handle.resource-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { ResourceType } from '../shared/resource-type';

export const HANDLE = new ResourceType('handle');
export const SUCCESSFUL_RESPONSE_START_CHAR = '2';
export const INVALID_RESOURCE_TYPE_ID = -1;
export const COMMUNITY = 'Community';
export const COLLECTION = 'Collection';
export const ITEM = 'Item';
Expand Down
54 changes: 49 additions & 5 deletions src/app/handle-page/handle-table/handle-table.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ <h5 class="card-header">{{ 'handle-table.title' | translate }}</h5>
class="btn btn-outline-secondary dropdown-toggle"
data-bs-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
<span *ngIf="searchOption != null" [ngModel]="searchOption" name="searchOption" ngDefaultControl>{{searchOption}}</span>
<span *ngIf="searchOption != null">{{searchOption}}</span>
<span *ngIf="searchOption == null" >{{'handle-table.dropdown.search-option' | translate}}</span>
</button>
<div ngbDropdownMenu aria-labelledby="resultdropdown">
Expand All @@ -20,9 +20,53 @@ <h5 class="card-header">{{ 'handle-table.title' | translate }}</h5>
<button class="dropdown-item" (click)="setSearchOption($event)">{{"handle-table.table.resource-type" | translate}}</button>
</div>
</div>
<input type="text" id="clarin-dc-search-box" class="form-control" aria-label="Text input with dropdown button"
[(ngModel)]="searchQuery"
[disabled]="!searchOption">

<!-- Search input area -->
<div class="search-input-container flex-fill">
<!-- Default disabled search input when no option is selected -->
<input *ngIf="!searchOption"
type="text"
class="form-control search-input"
[placeholder]="'handle-table.search.placeholder.no-option' | translate"
disabled>

<!-- Text input for Handle search -->
<input *ngIf="searchOption === handleOption"
type="text"
class="form-control search-input"
[(ngModel)]="searchQuery"
(keyup.enter)="searchHandles()"
[placeholder]="'handle-table.search.placeholder.handle' | translate">

<!-- Dropdown for Internal search -->
<div *ngIf="searchOption === internalOption" class="select-wrapper">
<select class="form-select w-100"
[(ngModel)]="searchQuery"
(change)="searchHandles()"
[attr.aria-label]="'handle-table.search.aria.select-internal' | translate">
<option value="" disabled [selected]="!searchQuery">{{'handle-table.search.internal.select' | translate}}</option>
<option value="yes">{{'handle-table.search.internal.yes' | translate}}</option>
<option value="no">{{'handle-table.search.internal.no' | translate}}</option>
</select>
<i class="fas fa-chevron-down select-icon"></i>
</div>

<!-- Dropdown for Resource Type search -->
<div *ngIf="searchOption === resourceTypeOption" class="select-wrapper">
<select class="form-select w-100"
[(ngModel)]="searchQuery"
(change)="searchHandles()"
[attr.aria-label]="'handle-table.search.aria.select-resource-type' | translate">
<option value="" disabled [selected]="!searchQuery">{{'handle-table.search.resource-type.select' | translate}}</option>
<option value="Site">{{'handle-table.search.resource-type.site' | translate}}</option>
<option value="Community">{{'handle-table.search.resource-type.community' | translate}}</option>
<option value="Collection">{{'handle-table.search.resource-type.collection' | translate}}</option>
<option value="Item">{{'handle-table.search.resource-type.item' | translate}}</option>
</select>
<i class="fas fa-chevron-down select-icon"></i>
</div>
</div>

<span class="input-group-append" (click)="searchHandles()">
<button type="submit" class="btn btn-primary search-button">
<i class="fas fa-search"></i>{{'handle-table.dropdown.search-button' | translate}}</button>
Expand Down Expand Up @@ -70,7 +114,7 @@ <h5 class="card-header">{{ 'handle-table.title' | translate }}</h5>
</a>
</td>
<td class="version-row-element-editor">
{{handle?.resourceTypeID}}
{{getTranslatedResourceType(handle?.resourceTypeID)}}
</td>
<td class="version-row-element-editor">
<span *ngIf="handle?.resourceId != null">
Expand Down
47 changes: 46 additions & 1 deletion src/app/handle-page/handle-table/handle-table.component.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,48 @@
/**
The file for styling `handle-table.component.html`. No styling needed.
* Styling for handle-table component search functionality
*/

// Make select elements look like buttons to match previous dropdown styling
.search-input-container {
.select-wrapper {
position: relative;
display: inline-block;
width: 100%;
}

.form-select {
background: white;
border: 1px solid #ced4da;
border-radius: 0.25rem;
padding: 0.375rem 2.5rem 0.375rem 0.75rem;
color: #495057;
appearance: none;
cursor: pointer;

&:focus {
border-color: #80bdff;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
outline: 0;
}

&:disabled {
background-color: #f8f9fa;
color: #6c757d;
cursor: not-allowed;
}
}

.select-icon {
position: absolute;
right: 0.75rem;
top: 50%;
transform: translateY(-50%);
pointer-events: none;
color: #495057;
font-size: 0.875rem;
}

.form-control {
border-radius: 0;
}
}
70 changes: 45 additions & 25 deletions src/app/handle-page/handle-table/handle-table.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ import { Handle } from '../../core/handle/handle.model';
import {
COLLECTION,
COMMUNITY,
INVALID_RESOURCE_TYPE_ID,
ITEM,
SITE,
SUCCESSFUL_RESPONSE_START_CHAR
} from '../../core/handle/handle.resource-type';
import { getCommunityPageRoute } from '../../community-page/community-page-routing-paths';
import { getCollectionPageRoute } from '../../collection-page/collection-page-routing-paths';
import { getEntityPageRoute } from '../../item-page/item-page-routing-paths';
import { HandleResourceTypeIdSerializer } from '../../core/handle/HandleResourceTypeIdserializer';

/**
* Constants for converting the searchQuery for the server
Expand Down Expand Up @@ -359,6 +361,47 @@ export class HandleTableComponent implements OnInit {
*/
setSearchOption(event) {
this.searchOption = event?.target?.innerHTML;
// Reset search query when changing search option
this.searchQuery = '';
}

/**
* Get translated resource type name for table display
* Converts constants like 'Community', 'Collection', 'Item', 'Site' to translated strings
*/
getTranslatedResourceType(resourceTypeID: string): string {
if (!resourceTypeID) {
return '';
}

// Map the constant values to lowercase for translation keys
const resourceTypeKey = resourceTypeID.toLowerCase();
const translationKey = `handle-table.search.resource-type.${resourceTypeKey}`;

// Return translated value, fallback to original if translation not found
const translated = this.translateService.instant(translationKey);
return translated !== translationKey ? translated : resourceTypeID;
}

/**
* Parse internal search query to server format
*/
private parseInternalSearchQuery(searchQuery: string): string {
const normalizedQuery = searchQuery.toLowerCase();
if (normalizedQuery === 'yes') {
return 'internal';
} else if (normalizedQuery === 'no') {
return 'external';
}
return searchQuery;
}

/**
* Parse resource type search query to server format (converts to numeric ID)
*/
private parseResourceTypeSearchQuery(searchQuery: string): string {
const id = HandleResourceTypeIdSerializer.Serialize(searchQuery);
return id ? id.toString() : INVALID_RESOURCE_TYPE_ID.toString();
}

/**
Expand All @@ -381,35 +424,12 @@ export class HandleTableComponent implements OnInit {
parsedSearchOption = HANDLE_SEARCH_OPTION;
break;
case this.internalOption:
// if the handle doesn't have the URL - is internal, if it does - is external
parsedSearchOption = URL_SEARCH_OPTION;
if (this.searchQuery.toLowerCase() === 'yes') {
parsedSearchQuery = 'internal';
} else if (this.searchQuery.toLowerCase() === 'no') {
parsedSearchQuery = 'external';
}
parsedSearchQuery = this.parseInternalSearchQuery(this.searchQuery);
break;
case this.resourceTypeOption:
parsedSearchOption = RESOURCE_TYPE_SEARCH_OPTION;
// parse resourceType from string to the number because the resourceType is integer on the server
switch (this.searchQuery.toLowerCase()) {
case ITEM.toLowerCase():
parsedSearchQuery = '' + 2;
break;
case COLLECTION.toLowerCase():
parsedSearchQuery = '' + 3;
break;
case COMMUNITY.toLowerCase():
parsedSearchQuery = '' + 4;
break;
case SITE.toLowerCase():
parsedSearchQuery = '' + 5;
break;
// no results for invalid search inputs
default:
parsedSearchQuery = '' + -1;
break;
}
parsedSearchQuery = this.parseResourceTypeSearchQuery(this.searchQuery);
break;
}
}
Expand Down
38 changes: 37 additions & 1 deletion src/assets/i18n/cs.json5
Original file line number Diff line number Diff line change
Expand Up @@ -8513,7 +8513,7 @@
// "handle-table.table.handle": "Handle",
"handle-table.table.handle": "Handle",

// "handle-table.table.internal": "Is Internal",
// "handle-table.table.internal": "Is internal",
"handle-table.table.internal": "Je interní",

// "handle-table.table.is-internal": "Yes",
Expand Down Expand Up @@ -8546,6 +8546,42 @@
// "handle-table.dropdown.search-button": "Search",
"handle-table.dropdown.search-button": "Hledat",

// "handle-table.search.placeholder.no-option": "Please select a search option first",
"handle-table.search.placeholder.no-option": "Nejprve vyberte možnost vyhledávání",

// "handle-table.search.placeholder.handle": "Enter handle",
"handle-table.search.placeholder.handle": "Zadejte Handle",

// "handle-table.search.internal.select": "Select internal option",
"handle-table.search.internal.select": "Vyberte možnost interní",

// "handle-table.search.internal.yes": "Yes",
"handle-table.search.internal.yes": "Ano",

// "handle-table.search.internal.no": "No",
"handle-table.search.internal.no": "Ne",

// "handle-table.search.resource-type.select": "Select resource type",
"handle-table.search.resource-type.select": "Vyberte typ zdroje",

// "handle-table.search.resource-type.site": "Site",
"handle-table.search.resource-type.site": "Stránka",

// "handle-table.search.resource-type.community": "Community",
"handle-table.search.resource-type.community": "Komunita",

// "handle-table.search.resource-type.collection": "Collection",
"handle-table.search.resource-type.collection": "Kolekce",

// "handle-table.search.resource-type.item": "Item",
"handle-table.search.resource-type.item": "Záznam",

// "handle-table.search.aria.select-internal": "Select internal option",
"handle-table.search.aria.select-internal": "Vyberte možnost interní",

// "handle-table.search.aria.select-resource-type": "Select resource type",
"handle-table.search.aria.select-resource-type": "Vyberte typ zdroje",

// "handle-table.global-actions.title": "Global Actions",
"handle-table.global-actions.title": "Globální akce",

Expand Down
26 changes: 25 additions & 1 deletion src/assets/i18n/en.json5
Original file line number Diff line number Diff line change
Expand Up @@ -5675,7 +5675,7 @@

"handle-table.table.handle": "Handle",

"handle-table.table.internal": "Is Internal",
"handle-table.table.internal": "Is internal",

"handle-table.table.is-internal": "Yes",

Expand All @@ -5697,6 +5697,30 @@

"handle-table.dropdown.search-button": "Search",

"handle-table.search.placeholder.no-option": "Please select a search option first",

"handle-table.search.placeholder.handle": "Enter handle",

"handle-table.search.internal.select": "Select internal option",

"handle-table.search.internal.yes": "Yes",

"handle-table.search.internal.no": "No",

"handle-table.search.resource-type.select": "Select resource type",

"handle-table.search.resource-type.site": "Site",

"handle-table.search.resource-type.community": "Community",

"handle-table.search.resource-type.collection": "Collection",

"handle-table.search.resource-type.item": "Item",

"handle-table.search.aria.select-internal": "Select internal option",

"handle-table.search.aria.select-resource-type": "Select resource type",

"handle-table.global-actions.title": "Global Actions",

"handle-table.global-actions.actions-list-message": "This is the list of available global actions.",
Expand Down