From 4c892093f89c0cb568336d46c885a6c327a4eb22 Mon Sep 17 00:00:00 2001 From: HuynhKhoa1601 Date: Wed, 12 Jul 2023 19:21:57 +0700 Subject: [PATCH 01/26] create new component and add model file and service file --- src/app/core/core.module.ts | 4 + .../data/metadata-bitstream-data.service.ts | 151 ++++++++++++++++++ .../core/metadata/metadata-bitstream.model.ts | 61 +++++++ .../metadata-bitstream.resource-type.ts | 10 ++ src/app/item-page/item-page.module.ts | 5 +- .../preview-section.component.html | 30 ++++ .../preview-section.component.scss | 48 ++++++ .../preview-section.component.spec.ts | 25 +++ .../preview-section.component.ts | 67 ++++++++ .../untyped-item/untyped-item.component.html | 1 + 10 files changed, 400 insertions(+), 2 deletions(-) create mode 100644 src/app/core/data/metadata-bitstream-data.service.ts create mode 100644 src/app/core/metadata/metadata-bitstream.model.ts create mode 100644 src/app/core/metadata/metadata-bitstream.resource-type.ts create mode 100644 src/app/item-page/simple/field-components/preview-section/preview-section.component.html create mode 100644 src/app/item-page/simple/field-components/preview-section/preview-section.component.scss create mode 100644 src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts create mode 100644 src/app/item-page/simple/field-components/preview-section/preview-section.component.ts diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 24f230b0e70..b656ee6eb1e 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -70,6 +70,7 @@ import { EPerson } from './eperson/models/eperson.model'; import { Group } from './eperson/models/group.model'; import { JsonPatchOperationsBuilder } from './json-patch/builder/json-patch-operations-builder'; import { MetadataField } from './metadata/metadata-field.model'; +import { MetadataBitstream } from './metadata/metadata-bitstream.model'; import { MetadataSchema } from './metadata/metadata-schema.model'; import { MetadataService } from './metadata/metadata.service'; import { RegistryService } from './registry/registry.service'; @@ -138,6 +139,7 @@ import { SiteAdministratorGuard } from './data/feature-authorization/feature-aut import { Registration } from './shared/registration.model'; import { MetadataSchemaDataService } from './data/metadata-schema-data.service'; import { MetadataFieldDataService } from './data/metadata-field-data.service'; +import { MetadataBitstreamDataService } from './data/metadata-bitstream-data.service'; import { DsDynamicTypeBindRelationService } from '../shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service'; import { TokenResponseParsingService } from './auth/token-response-parsing.service'; import { SubmissionCcLicenseDataService } from './submission/submission-cc-license-data.service'; @@ -292,6 +294,7 @@ const PROVIDERS = [ SiteRegisterGuard, MetadataSchemaDataService, MetadataFieldDataService, + MetadataBitstreamDataService, TokenResponseParsingService, ReloadGuard, EndUserAgreementCurrentUserGuard, @@ -328,6 +331,7 @@ export const models = ResourcePolicy, MetadataSchema, MetadataField, + MetadataBitstream, License, WorkflowItem, WorkspaceItem, diff --git a/src/app/core/data/metadata-bitstream-data.service.ts b/src/app/core/data/metadata-bitstream-data.service.ts new file mode 100644 index 00000000000..2c17adca6d3 --- /dev/null +++ b/src/app/core/data/metadata-bitstream-data.service.ts @@ -0,0 +1,151 @@ +import { Injectable } from '@angular/core'; +import { hasValue } from '../../shared/empty.util'; +import { PaginatedList } from './paginated-list.model'; +import { RemoteData } from './remote-data'; +import { RequestService } from './request.service'; +import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { HALEndpointService } from '../shared/hal-endpoint.service'; +import { MetadataField } from '../metadata/metadata-field.model'; +import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { Observable } from 'rxjs'; +import { take } from 'rxjs/operators'; +import { RequestParam } from '../cache/models/request-param.model'; +import { FindListOptions } from './find-list-options.model'; +import { SearchData, SearchDataImpl } from './base/search-data'; +import { PutData, PutDataImpl } from './base/put-data'; +import { CreateData, CreateDataImpl } from './base/create-data'; +import { NoContent } from '../shared/NoContent.model'; +import { NotificationsService } from '../../shared/notifications/notifications.service'; +import { ObjectCacheService } from '../cache/object-cache.service'; +import { METADATA_BITSTREAM } from '../metadata/metadata-bitstream.resource-type'; + +/** + * A service responsible for fetching/sending data from/to the REST API on the metadatafields endpoint + */ +@Injectable() +@dataService(METADATA_BITSTREAM) +export class MetadataBitstreamDataService extends IdentifiableDataService implements CreateData, PutData, DeleteData, SearchData { + private createData: CreateData; + private searchData: SearchData; + private putData: PutData; + private deleteData: DeleteData; + protected searchByHandleLinkPath = 'byHandle'; + + constructor( + protected requestService: RequestService, + protected rdbService: RemoteDataBuildService, + protected objectCache: ObjectCacheService, + protected halService: HALEndpointService, + protected notificationsService: NotificationsService, + ) { + super('metadatabitstreams', requestService, rdbService, objectCache, halService); + + // this.createData = new CreateDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, notificationsService, this.responseMsToLive); + // this.searchData = new SearchDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive); + // this.putData = new PutDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive); + // this.deleteData = new DeleteDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, notificationsService, this.responseMsToLive, this.constructIdEndpoint); + } + + + /** + * Find metadata fields with either the partial metadata field name (e.g. "dc.ti") as query or an exact match to + * at least the schema, element or qualifier + * @param schema optional; an exact match of the prefix of the metadata schema (e.g. "dc", "dcterms", "eperson") + * @param element optional; an exact match of the field's element (e.g. "contributor", "title") + * @param qualifier optional; an exact match of the field's qualifier (e.g. "author", "alternative") + * @param query optional (if any of schema, element or qualifier used) - part of the fully qualified field, + * should start with the start of the schema, element or qualifier (e.g. “dc.ti”, “contributor”, “auth”, “contributor.ot”) + * @param exactName optional; the exact fully qualified field, should use the syntax schema.element.qualifier or + * schema.element if no qualifier exists (e.g. "dc.title", "dc.contributor.author"). It will only return one value + * if there's an exact match + * @param options The options info used to retrieve the fields + * @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's no valid cached version. Defaults to true + * @param reRequestOnStale Whether or not the request should automatically be re-requested after the response becomes stale + * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved + */ + searchByHandleParams(handle: string, fileGrpType: string, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable> { + const optionParams = Object.assign(new FindListOptions(), options, { + searchParams: [ + new RequestParam('handle', hasValue(handle) ? handle : ''), + new RequestParam('fileGrpType', hasValue(fileGrpType) ? fileGrpType : ''), + ], + }); + return this.searchBy(this.searchByHandleLinkPath, optionParams, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + } + + + /** + * Clear all metadata field requests + * Used for refreshing lists after adding/updating/removing a metadata field from a metadata schema + */ + clearRequests(): void { + this.getBrowseEndpoint().pipe(take(1)).subscribe((href: string) => { + this.requestService.setStaleByHrefSubstring(href); + }); + + } + + + /** + * Delete an existing object on the server + * @param objectId The id of the object to be removed + * @param copyVirtualMetadata (optional parameter) the identifiers of the relationship types for which the virtual + * metadata should be saved as real metadata + * @return A RemoteData observable with an empty payload, but still representing the state of the request: statusCode, + * errorMessage, timeCompleted, etc + */ + delete(objectId: string, copyVirtualMetadata?: string[]): Observable> { + return this.deleteData.delete(objectId, copyVirtualMetadata); + } + + /** + * Delete an existing object on the server + * @param href The self link of the object to be removed + * @param copyVirtualMetadata (optional parameter) the identifiers of the relationship types for which the virtual + * metadata should be saved as real metadata + * @return A RemoteData observable with an empty payload, but still representing the state of the request: statusCode, + * errorMessage, timeCompleted, etc + * Only emits once all request related to the DSO has been invalidated. + */ + public deleteByHref(href: string, copyVirtualMetadata?: string[]): Observable> { + return this.deleteData.deleteByHref(href, copyVirtualMetadata); + } + + /** + * Send a PUT request for the specified object + * + * @param object The object to send a put request for. + */ + put(object: MetadataField): Observable> { + return this.putData.put(object); + } + + /** + * Create a new object on the server, and store the response in the object cache + * + * @param object The object to create + * @param params Array with additional params to combine with query string + */ + create(object: MetadataField, ...params: RequestParam[]): Observable> { + return this.createData.create(object, ...params); + } + + /** + * Make a new FindListRequest with given search method + * + * @param searchMethod The search method for the object + * @param options The [[FindListOptions]] object + * @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's + * no valid cached version. Defaults to true + * @param reRequestOnStale Whether or not the request should automatically be re- + * requested after the response becomes stale + * @param linksToFollow List of {@link FollowLinkConfig} that indicate which + * {@link HALLink}s should be automatically resolved + * @return {Observable>} + * Return an observable that emits response from the server + */ + public searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig[]): Observable>> { + return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + } + +} \ No newline at end of file diff --git a/src/app/core/metadata/metadata-bitstream.model.ts b/src/app/core/metadata/metadata-bitstream.model.ts new file mode 100644 index 00000000000..e6e40d62016 --- /dev/null +++ b/src/app/core/metadata/metadata-bitstream.model.ts @@ -0,0 +1,61 @@ +import { autoserialize, deserialize } from 'cerialize'; +import { ListableObject } from '../../shared/object-collection/shared/listable-object.model'; +import { typedObject } from '../cache/builders/build-decorators'; +import { GenericConstructor } from '../shared/generic-constructor'; +import { HALLink } from '../shared/hal-link.model'; +import { HALResource } from '../shared/hal-resource.model'; +import { ResourceType } from '../shared/resource-type'; +import { excludeFromEquals } from '../utilities/equals.decorators'; +import { METADATA_BITSTREAM } from './metadata-bitstream.resource-type'; + +/** + * Class the represents a metadata field + */ +@typedObject +export class MetadataBitstream extends ListableObject implements HALResource { + static type = METADATA_BITSTREAM; + + /** + * The object type + */ + @excludeFromEquals + @autoserialize + type: ResourceType; + + /** + * The identifier of this metadata field + */ + @autoserialize + id: number; + + /** + * The element of this metadata field + */ + @autoserialize + bitstreamRest: any; + + /** + * The qualifier of this metadata field + */ + @autoserialize + fileInfo: any; + + /** + * The scope note of this metadata field + */ + @autoserialize + href: any; + + /** + * The {@link HALLink}s for this MetadataField + */ + @deserialize + _links: { + self: HALLink, + schema: HALLink + }; + + getRenderTypes(): (string | GenericConstructor)[] { + return [this.constructor as GenericConstructor]; + } +} \ No newline at end of file diff --git a/src/app/core/metadata/metadata-bitstream.resource-type.ts b/src/app/core/metadata/metadata-bitstream.resource-type.ts new file mode 100644 index 00000000000..ef5c337166e --- /dev/null +++ b/src/app/core/metadata/metadata-bitstream.resource-type.ts @@ -0,0 +1,10 @@ +import { ResourceType } from '../shared/resource-type'; + +/** + * The resource type for MetadataBitstream + * + * Needs to be in a separate file to prevent circular + * dependencies in webpack. + */ + +export const METADATA_BITSTREAM = new ResourceType('metadatabitstream'); \ No newline at end of file diff --git a/src/app/item-page/item-page.module.ts b/src/app/item-page/item-page.module.ts index d7f9f9bdfaf..0218da43a6b 100644 --- a/src/app/item-page/item-page.module.ts +++ b/src/app/item-page/item-page.module.ts @@ -48,7 +48,7 @@ import { ChartsModule } from 'ng2-charts'; import { ClarinGenericItemFieldComponent } from './simple/field-components/clarin-generic-item-field/clarin-generic-item-field.component'; import { ClarinCollectionsItemFieldComponent } from './simple/field-components/clarin-collections-item-field/clarin-collections-item-field.component'; import { ClarinFilesItemFieldComponent } from './simple/field-components/clarin-files-item-field/clarin-files-item-field.component'; - +import { PreviewSectionComponent } from './simple/field-components/preview-section/preview-section.component'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator @@ -93,7 +93,8 @@ const DECLARATIONS = [ ClarinStatisticsButtonComponent, ClarinGenericItemFieldComponent, ClarinCollectionsItemFieldComponent, - ClarinFilesItemFieldComponent + ClarinFilesItemFieldComponent, + PreviewSectionComponent ]; @NgModule({ diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.html b/src/app/item-page/simple/field-components/preview-section/preview-section.component.html new file mode 100644 index 00000000000..7b60ee592ad --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.html @@ -0,0 +1,30 @@ +
+
+
+

Name: {{file.name}}

+

Size: {{file.size}}

+

Format: {{file.format}}

+

Description: {{file.description}}

+

MD5: {{file.md5}}

+
+ + +
+
+ Preview +
+
+ + + +
    +
  • + {{file.name}} {{file.size}} +
    + +
    +
  • +
+
+
+
\ No newline at end of file diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.scss b/src/app/item-page/simple/field-components/preview-section/preview-section.component.scss new file mode 100644 index 00000000000..77ae9971b41 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.scss @@ -0,0 +1,48 @@ +file-preview-box { + border: 1px solid black; + + .file-content { + display: flex; + + .preview-image { + width: 50%; + } + + .file-info { + padding: 20px; + + p { + margin-bottom: 5px; + } + + .button-container { + margin-top: 20px; + + .download-btn, .preview-btn { + margin-right: 10px; + padding: 10px 20px; + border: none; + color: white; + cursor: pointer; + } + + .download-btn { + background-color: blue; + } + + .preview-btn { + background-color: green; + } + } + } + } + + .file-list { + padding: 20px; + + ul { + list-style-type: none; + padding-left: 0; + } + } +} \ No newline at end of file diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts b/src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts new file mode 100644 index 00000000000..f4aeef26dd9 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PreviewSectionComponent } from './preview-section.component'; + +describe('PreviewSectionComponent', () => { + let component: PreviewSectionComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ PreviewSectionComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(PreviewSectionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.ts b/src/app/item-page/simple/field-components/preview-section/preview-section.component.ts new file mode 100644 index 00000000000..b9f628c0e1b --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.ts @@ -0,0 +1,67 @@ +import { Component, OnInit } from '@angular/core'; +import { RegistryService } from 'src/app/core/registry/registry.service'; + +@Component({ + selector: 'ds-preview-section', + templateUrl: './preview-section.component.html', + styleUrls: ['./preview-section.component.scss'] +}) +export class PreviewSectionComponent implements OnInit { + + file = { + previewImageUrl: + 'https://lindat.mff.cuni.cz/repository/xmlui/themes/UFAL/images/mime/application-x-gzip.png', // replace with your image URL + name: 'ud-treebanks-v2.12.tgz', + size: '497.82 MB', + format: 'application/x-gzip', + description: 'Treebank data', + md5: 'afb7546d9591a82f372686bcc100db52', + }; + + fileList: any[] = []; // Modified + + isPreviewVisible = false; + + constructor(protected registryService: RegistryService) {} // Modified + + ngOnInit(): void { + // this.registryService + // .getMetadataBitstream('123456789/36', 'ORIGINAL,TEXT,THUMBNAIL') + // .subscribe( + // (remoteData: any) => { + // console.log('Received data:', remoteData); + // if ( + // remoteData && + // remoteData._embedded && + // remoteData._embedded.metadatabitstreams + // ) { + // this.fileList = this.parseFiles( + // remoteData._embedded.metadatabitstreams[0].fileInfo + // ); + // } + // }, + // (error: any) => { + // console.log('Received error:', error); + // } + // ); + } + + togglePreview() { + this.isPreviewVisible = !this.isPreviewVisible; + } + + parseFiles(files: any[]): any[] { + let parsedFiles: any[] = []; + for (let file of files) { + let parsedFile: any = {}; + parsedFile.name = file.name; + parsedFile.size = file.size; + parsedFile.isDirectory = file.isDirectory; + if (file.isDirectory && file.sub) { + parsedFile.sub = this.parseFiles(Object.values(file.sub)); + } + parsedFiles.push(parsedFile); + } + return parsedFiles; + } +} diff --git a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html index 3fb68ff17d8..3a6ffd4a239 100644 --- a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html +++ b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html @@ -109,5 +109,6 @@

[iconName]="'fa-paperclip'" [separator]="'
'"> + From 65290d834c5cdb0820e0e4590dd04a1a7179a35e Mon Sep 17 00:00:00 2001 From: HuynhKhoa1601 Date: Thu, 13 Jul 2023 17:37:59 +0700 Subject: [PATCH 02/26] build the user interface and calling the api from backend --- angular.json | 1 + .../data/metadata-bitstream-data.service.ts | 124 +- .../core/metadata/metadata-bitstream.model.ts | 58 +- src/app/core/registry/registry.service.ts | 20 +- .../preview-section.component.html | 4736 ++++++++++++++++- .../preview-section.component.scss | 123 +- .../preview-section.component.ts | 72 +- .../item-page/simple/item-page.component.html | 1 + .../untyped-item/untyped-item.component.html | 2 +- 9 files changed, 4939 insertions(+), 198 deletions(-) diff --git a/angular.json b/angular.json index b151a355acc..c7e3ff7ce71 100644 --- a/angular.json +++ b/angular.json @@ -49,6 +49,7 @@ "styles": [ "src/styles/startup.scss", "src/aai/discojuice/discojuice.css", + "node_modules/font-awesome/css/font-awesome.css", "node_modules/bootstrap/dist/css/bootstrap.min.css", { "input": "src/styles/base-theme.scss", diff --git a/src/app/core/data/metadata-bitstream-data.service.ts b/src/app/core/data/metadata-bitstream-data.service.ts index 2c17adca6d3..9e6c62c159e 100644 --- a/src/app/core/data/metadata-bitstream-data.service.ts +++ b/src/app/core/data/metadata-bitstream-data.service.ts @@ -5,30 +5,32 @@ import { RemoteData } from './remote-data'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; -import { MetadataField } from '../metadata/metadata-field.model'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { Observable } from 'rxjs'; -import { take } from 'rxjs/operators'; import { RequestParam } from '../cache/models/request-param.model'; -import { FindListOptions } from './find-list-options.model'; -import { SearchData, SearchDataImpl } from './base/search-data'; -import { PutData, PutDataImpl } from './base/put-data'; -import { CreateData, CreateDataImpl } from './base/create-data'; import { NoContent } from '../shared/NoContent.model'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { ObjectCacheService } from '../cache/object-cache.service'; import { METADATA_BITSTREAM } from '../metadata/metadata-bitstream.resource-type'; +import { FindListOptions } from './request.models'; +import { dataService } from '../cache/builders/build-decorators'; +import { MetadataBitstream } from '../metadata/metadata-bitstream.model'; +import { DataService } from './data.service'; +import { HttpClient } from '@angular/common/http'; +import { Store } from '@ngrx/store'; +import { CoreState } from '../core.reducers'; +import { ChangeAnalyzer } from './change-analyzer'; /** * A service responsible for fetching/sending data from/to the REST API on the metadatafields endpoint */ @Injectable() @dataService(METADATA_BITSTREAM) -export class MetadataBitstreamDataService extends IdentifiableDataService implements CreateData, PutData, DeleteData, SearchData { - private createData: CreateData; - private searchData: SearchData; - private putData: PutData; - private deleteData: DeleteData; +export class MetadataBitstreamDataService extends DataService { + protected store: Store; + protected http: HttpClient; + protected comparator: ChangeAnalyzer; + protected linkPath = 'metadatabitstreams'; protected searchByHandleLinkPath = 'byHandle'; constructor( @@ -38,12 +40,7 @@ export class MetadataBitstreamDataService extends IdentifiableDataService i protected halService: HALEndpointService, protected notificationsService: NotificationsService, ) { - super('metadatabitstreams', requestService, rdbService, objectCache, halService); - - // this.createData = new CreateDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, notificationsService, this.responseMsToLive); - // this.searchData = new SearchDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive); - // this.putData = new PutDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive); - // this.deleteData = new DeleteDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, notificationsService, this.responseMsToLive, this.constructIdEndpoint); + super(); } @@ -70,82 +67,25 @@ export class MetadataBitstreamDataService extends IdentifiableDataService i new RequestParam('fileGrpType', hasValue(fileGrpType) ? fileGrpType : ''), ], }); - return this.searchBy(this.searchByHandleLinkPath, optionParams, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); - } - - - /** - * Clear all metadata field requests - * Used for refreshing lists after adding/updating/removing a metadata field from a metadata schema - */ - clearRequests(): void { - this.getBrowseEndpoint().pipe(take(1)).subscribe((href: string) => { - this.requestService.setStaleByHrefSubstring(href); - }); - - } - - - /** - * Delete an existing object on the server - * @param objectId The id of the object to be removed - * @param copyVirtualMetadata (optional parameter) the identifiers of the relationship types for which the virtual - * metadata should be saved as real metadata - * @return A RemoteData observable with an empty payload, but still representing the state of the request: statusCode, - * errorMessage, timeCompleted, etc - */ - delete(objectId: string, copyVirtualMetadata?: string[]): Observable> { - return this.deleteData.delete(objectId, copyVirtualMetadata); - } - - /** - * Delete an existing object on the server - * @param href The self link of the object to be removed - * @param copyVirtualMetadata (optional parameter) the identifiers of the relationship types for which the virtual - * metadata should be saved as real metadata - * @return A RemoteData observable with an empty payload, but still representing the state of the request: statusCode, - * errorMessage, timeCompleted, etc - * Only emits once all request related to the DSO has been invalidated. - */ - public deleteByHref(href: string, copyVirtualMetadata?: string[]): Observable> { - return this.deleteData.deleteByHref(href, copyVirtualMetadata); - } - - /** - * Send a PUT request for the specified object - * - * @param object The object to send a put request for. - */ - put(object: MetadataField): Observable> { - return this.putData.put(object); + return this.searchBy(this.searchByHandleLinkPath, optionParams, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow) } - /** - * Create a new object on the server, and store the response in the object cache - * - * @param object The object to create - * @param params Array with additional params to combine with query string - */ - create(object: MetadataField, ...params: RequestParam[]): Observable> { - return this.createData.create(object, ...params); - } - - /** - * Make a new FindListRequest with given search method - * - * @param searchMethod The search method for the object - * @param options The [[FindListOptions]] object - * @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's - * no valid cached version. Defaults to true - * @param reRequestOnStale Whether or not the request should automatically be re- - * requested after the response becomes stale - * @param linksToFollow List of {@link FollowLinkConfig} that indicate which - * {@link HALLink}s should be automatically resolved - * @return {Observable>} - * Return an observable that emits response from the server - */ - public searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig[]): Observable>> { - return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); - } + // /** + // * Make a new FindListRequest with given search method + // * + // * @param searchMethod The search method for the object + // * @param options The [[FindListOptions]] object + // * @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's + // * no valid cached version. Defaults to true + // * @param reRequestOnStale Whether or not the request should automatically be re- + // * requested after the response becomes stale + // * @param linksToFollow List of {@link FollowLinkConfig} that indicate which + // * {@link HALLink}s should be automatically resolved + // * @return {Observable>} + // * Return an observable that emits response from the server + // */ + // public searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig[]): Observable>> { + // return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + // } } \ No newline at end of file diff --git a/src/app/core/metadata/metadata-bitstream.model.ts b/src/app/core/metadata/metadata-bitstream.model.ts index e6e40d62016..b5f3baebce6 100644 --- a/src/app/core/metadata/metadata-bitstream.model.ts +++ b/src/app/core/metadata/metadata-bitstream.model.ts @@ -1,6 +1,6 @@ -import { autoserialize, deserialize } from 'cerialize'; +import { autoserialize, autoserializeAs, deserialize, deserializeAs } from 'cerialize'; import { ListableObject } from '../../shared/object-collection/shared/listable-object.model'; -import { typedObject } from '../cache/builders/build-decorators'; +import { typedObject } from '../cache/builders/build-decorators'; import { GenericConstructor } from '../shared/generic-constructor'; import { HALLink } from '../shared/hal-link.model'; import { HALResource } from '../shared/hal-resource.model'; @@ -9,7 +9,18 @@ import { excludeFromEquals } from '../utilities/equals.decorators'; import { METADATA_BITSTREAM } from './metadata-bitstream.resource-type'; /** - * Class the represents a metadata field + * Class the represents a File + */ +class FileInfo { + @autoserialize name: string; + @autoserialize content: any; + @autoserialize size: string; + @autoserialize isDirectory: boolean; + @autoserializeAs(FileInfo, 'sub') sub: {[key: string]: FileInfo}; +} + +/** + * Class that represents a MetadataBitstream */ @typedObject export class MetadataBitstream extends ListableObject implements HALResource { @@ -29,22 +40,51 @@ export class MetadataBitstream extends ListableObject implements HALResource { id: number; /** - * The element of this metadata field + * The name of this bitstream + */ + @autoserialize + name: string; + + /** + * The description of this bitstream + */ + @autoserialize + description: string; + + /** + * The fileSize of this bitstream + */ + @autoserialize + fileSize: string; + + /** + * The checksum of this bitstream + */ + @autoserialize + checksum: string; + + /** + * The fileInfo of this bitstream + */ + @autoserializeAs(FileInfo, 'fileInfo') fileInfo: FileInfo[]; + + /** + * The format of this bitstream */ @autoserialize - bitstreamRest: any; + format: string; /** - * The qualifier of this metadata field + * The href of this bitstream */ @autoserialize - fileInfo: any; + href: string; /** - * The scope note of this metadata field + * The canPreview of this bitstream */ @autoserialize - href: any; + canPreview: boolean; /** * The {@link HALLink}s for this MetadataField diff --git a/src/app/core/registry/registry.service.ts b/src/app/core/registry/registry.service.ts index 0046dbdb19c..e2980306176 100644 --- a/src/app/core/registry/registry.service.ts +++ b/src/app/core/registry/registry.service.ts @@ -27,9 +27,11 @@ import { MetadataSchema } from '../metadata/metadata-schema.model'; import { MetadataField } from '../metadata/metadata-field.model'; import { MetadataSchemaDataService } from '../data/metadata-schema-data.service'; import { MetadataFieldDataService } from '../data/metadata-field-data.service'; +import { MetadataBitstreamDataService } from '../data/metadata-bitstream-data.service'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { RequestParam } from '../cache/models/request-param.model'; import { NoContent } from '../shared/NoContent.model'; +import { MetadataBitstream } from '../metadata/metadata-bitstream.model'; const metadataRegistryStateSelector = (state: AppState) => state.metadataRegistry; const editMetadataSchemaSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editSchema); @@ -47,7 +49,8 @@ export class RegistryService { private notificationsService: NotificationsService, private translateService: TranslateService, private metadataSchemaService: MetadataSchemaDataService, - private metadataFieldService: MetadataFieldDataService) { + private metadataFieldService: MetadataFieldDataService, + private metadataBitstreamDataService: MetadataBitstreamDataService) { } @@ -104,6 +107,21 @@ export class RegistryService { return this.metadataFieldService.findBySchema(schema, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); } + /** + * retrieves all metadatabistream that belong to a certain metadata + * @param schema The schema to filter by + * @param options The options info used to retrieve the fields + * @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's + * no valid cached version. Defaults to true + * @param reRequestOnStale Whether or not the request should automatically be re- + * requested after the response becomes stale + * @param linksToFollow List of {@link FollowLinkConfig} that indicate which + * {@link HALLink}s should be automatically resolved + */ + public getMetadataBitstream(handle: string, fileGrpType: string, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable> { + return this.metadataBitstreamDataService.searchByHandleParams(handle, fileGrpType, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + } + public editMetadataSchema(schema: MetadataSchema) { this.store.dispatch(new MetadataRegistryEditSchemaAction(schema)); } diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.html b/src/app/item-page/simple/field-components/preview-section/preview-section.component.html index 7b60ee592ad..328e3c21251 100644 --- a/src/app/item-page/simple/field-components/preview-section/preview-section.component.html +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.html @@ -1,30 +1,4712 @@
-
-
-

Name: {{file.name}}

-

Size: {{file.size}}

-

Format: {{file.format}}

-

Description: {{file.description}}

-

MD5: {{file.md5}}

-
- - -
-
- Preview -
-
- - - -
    -
  • - {{file.name}} {{file.size}} -
    - -
    -
  • +
    +
    +
    Name
    +
    + ud-treebanks-v2.12.tgz +
    +
    Size
    +
    497.82 MB
    +
    Format
    +
    application/x-gzip
    +
    Description
    +
    Treebank data
    +
    MD5
    +
    + afb7546d9591a82f372686bcc100db52 +
    +
    + Preview +
    + +
    +
    +
    +  File Preview +
    +
    +
      +
    • + ud-treebanks-v2.12 +
        +
      • + UD_English-PUD +
          +
        • + stats.xml8 kB +
        • +
        • + en_pud-ud-test.conllu1 MB +
        • +
        • + README.md6 kB +
        • +
        • + en_pud-ud-test.txt109 kB +
        • +
        • + LICENSE.txt19 kB +
        • +
        +
      • +
      • + UD_Finnish-PUD +
          +
        • + stats.xml17 kB +
        • +
        • + README.txt2 kB +
        • +
        • + fi_pud-ud-test.txt119 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + fi_pud-ud-test.conllu1 MB +
        • +
        +
      • +
      • + UD_Telugu-MTG +
          +
        • + te_mtg-ud-test.txt10 kB +
        • +
        • + README.md1 kB +
        • +
        • + te_mtg-ud-train.conllu494 kB +
        • +
        • + te_mtg-ud-dev.conllu64 kB +
        • +
        • + stats.xml3 kB +
        • +
        • + te_mtg-ud-test.conllu70 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + te_mtg-ud-dev.txt9 kB +
        • +
        • + te_mtg-ud-train.txt72 kB +
        • +
        +
      • +
      • + UD_Neapolitan-RB +
          +
        • + stats.xml1 kB +
        • +
        • + README.md1 kB +
        • +
        • + nap_rb-ud-test.conllu431 B +
        • +
        • + LICENSE.txt202 B +
        • +
        • + nap_rb-ud-test.txt56 B +
        • +
        +
      • +
      • + UD_Swedish-Talbanken +
          +
        • + sv_talbanken-ud-test.txt122 kB +
        • +
        • + README.md7 kB +
        • +
        • + sv_talbanken-ud-train.txt402 kB +
        • +
        • + stats.xml9 kB +
        • +
        • + LICENSE.txt20 kB +
        • +
        • + sv_talbanken-ud-train.conllu5 MB +
        • +
        • + sv_talbanken-ud-dev.conllu834 kB +
        • +
        • + sv_talbanken-ud-test.conllu1 MB +
        • +
        • + sv_talbanken-ud-dev.txt58 kB +
        • +
        +
      • +
      • + UD_Romanian-RRT +
          +
        • + README.md5 kB +
        • +
        • + ro_rrt-ud-dev.txt98 kB +
        • +
        • + ro_rrt-ud-train.conllu13 MB +
        • +
        • + stats.xml12 kB +
        • +
        • + LICENSE.txt66 B +
        • +
        • + ro_rrt-ud-dev.conllu1 MB +
        • +
        • + ro_rrt-ud-test.conllu1 MB +
        • +
        • + ro_rrt-ud-train.txt1 MB +
        • +
        • + ro_rrt-ud-test.txt94 kB +
        • +
        +
      • +
      • + UD_Czech-CLTT +
          +
        • + cs_cltt-ud-dev.conllu1 MB +
        • +
        • + cs_cltt-ud-test.txt81 kB +
        • +
        • + README.md3 kB +
        • +
        • + cs_cltt-ud-train.txt96 kB +
        • +
        • + cs_cltt-ud-dev.txt76 kB +
        • +
        • + stats.xml13 kB +
        • +
        • + cs_cltt-ud-train.conllu1 MB +
        • +
        • + LICENSE.txt265 B +
        • +
        • + cs_cltt-ud-test.conllu1 MB +
        • +
        +
      • +
      • + UD_Czech-PUD +
          +
        • + stats.xml16 kB +
        • +
        • + README.md3 kB +
        • +
        • + cs_pud-ud-test.txt114 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + cs_pud-ud-test.conllu2 MB +
        • +
        +
      • +
      • + UD_Sinhala-STB +
          +
        • + stats.xml14 kB +
        • +
        • + README.md1 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + si_stb-ud-test.txt11 kB +
        • +
        • + si_stb-ud-test.conllu109 kB +
        • +
        +
      • +
      • + UD_German-GSD +
          +
        • + README.md9 kB +
        • +
        • + de_gsd-ud-dev.conllu882 kB +
        • +
        • + de_gsd-ud-dev.txt72 kB +
        • +
        • + de_gsd-ud-train.txt1 MB +
        • +
        • + de_gsd-ud-test.conllu1 MB +
        • +
        • + stats.xml11 kB +
        • +
        • + de_gsd-ud-train.conllu18 MB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + de_gsd-ud-test.txt97 kB +
        • +
        +
      • +
      • + UD_Zaar-Autogramm +
          +
        • + stats.xml10 kB +
        • +
        • + README.md2 kB +
        • +
        • + say_autogramm-ud-test.conllu951 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + say_autogramm-ud-test.txt42 kB +
        • +
        +
      • +
      • + UD_Akuntsu-TuDeT +
          +
        • + stats.xml7 kB +
        • +
        • + aqz_tudet-ud-test.conllu89 kB +
        • +
        • + README.md3 kB +
        • +
        • + aqz_tudet-ud-test.txt6 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Komi_Permyak-UH +
          +
        • + stats.xml14 kB +
        • +
        • + README.md6 kB +
        • +
        • + koi_uh-ud-test.conllu107 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + koi_uh-ud-test.txt8 kB +
        • +
        +
      • +
      • + UD_Pomak-Philotis +
          +
        • + README.md2 kB +
        • +
        • + qpm_philotis-ud-train.conllu5 MB +
        • +
        • + qpm_philotis-ud-test.txt45 kB +
        • +
        • + qpm_philotis-ud-train.txt357 kB +
        • +
        • + qpm_philotis-ud-dev.txt45 kB +
        • +
        • + qpm_philotis-ud-dev.conllu690 kB +
        • +
        • + qpm_philotis-ud-test.conllu695 kB +
        • +
        • + stats.xml12 kB +
        • +
        • + LICENSE.txt417 B +
        • +
        +
      • +
      • + UD_Faroese-FarPaHC +
          +
        • + fo_farpahc-ud-dev.conllu465 kB +
        • +
        • + fo_farpahc-ud-dev.txt42 kB +
        • +
        • + README.md4 kB +
        • +
        • + fo_farpahc-ud-test.conllu459 kB +
        • +
        • + fo_farpahc-ud-train.txt105 kB +
        • +
        • + fo_farpahc-ud-train.conllu1 MB +
        • +
        • + stats.xml5 kB +
        • +
        • + fo_farpahc-ud-test.txt42 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Turkish-Penn +
          +
        • + README.md1 kB +
        • +
        • + tr_penn-ud-dev.conllu477 kB +
        • +
        • + tr_penn-ud-train.conllu11 MB +
        • +
        • + tr_penn-ud-test.txt69 kB +
        • +
        • + stats.xml13 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + tr_penn-ud-test.conllu682 kB +
        • +
        • + tr_penn-ud-dev.txt48 kB +
        • +
        • + tr_penn-ud-train.txt1 MB +
        • +
        +
      • +
      • + UD_Japanese-PUDLUW +
          +
        • + stats.xml4 kB +
        • +
        • + README.md5 kB +
        • +
        • + ja_pudluw-ud-test.txt138 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + ja_pudluw-ud-test.conllu4 MB +
        • +
        +
      • +
      • + UD_Chinese-PUD +
          +
        • + stats.xml5 kB +
        • +
        • + README.md5 kB +
        • +
        • + zh_pud-ud-test.conllu2 MB +
        • +
        • + zh_pud-ud-test.txt101 kB +
        • +
        • + LICENSE.txt19 kB +
        • +
        +
      • +
      • + UD_Teko-TuDeT +
          +
        • + stats.xml14 kB +
        • +
        • + eme_tudet-ud-test.conllu206 kB +
        • +
        • + eme_tudet-ud-test.txt17 kB +
        • +
        • + README.md1 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Latin-UDante +
          +
        • + la_udante-ud-train.conllu2 MB +
        • +
        • + README.md10 kB +
        • +
        • + la_udante-ud-dev.conllu1 MB +
        • +
        • + la_udante-ud-train.txt170 kB +
        • +
        • + stats.xml19 kB +
        • +
        • + la_udante-ud-test.txt78 kB +
        • +
        • + la_udante-ud-dev.txt67 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + la_udante-ud-test.conllu1 MB +
        • +
        +
      • +
      • + UD_Buryat-BDT +
          +
        • + stats.xml12 kB +
        • +
        • + README.txt1 kB +
        • +
        • + bxr_bdt-ud-train.txt1 kB +
        • +
        • + bxr_bdt-ud-train.conllu11 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + bxr_bdt-ud-test.txt114 kB +
        • +
        • + bxr_bdt-ud-test.conllu699 kB +
        • +
        +
      • +
      • + UD_Italian-MarkIT +
          +
        • + it_markit-ud-dev.txt54 kB +
        • +
        • + README.md1 kB +
        • +
        • + it_markit-ud-train.txt102 kB +
        • +
        • + it_markit-ud-test.txt52 kB +
        • +
        • + stats.xml8 kB +
        • +
        • + it_markit-ud-train.conllu1 MB +
        • +
        • + LICENSE.txt188 B +
        • +
        • + it_markit-ud-test.conllu642 kB +
        • +
        • + it_markit-ud-dev.conllu649 kB +
        • +
        +
      • +
      • + UD_Abaza-ATB +
          +
        • + stats.xml17 kB +
        • +
        • + abq_atb-ud-test.conllu125 kB +
        • +
        • + README.md1 kB +
        • +
        • + abq_atb-ud-test.txt9 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Slovenian-SST +
          +
        • + stats.xml11 kB +
        • +
        • + sl_sst-ud-test.txt53 kB +
        • +
        • + README.md5 kB +
        • +
        • + sl_sst-ud-train.conllu1 MB +
        • +
        • + sl_sst-ud-test.conllu988 kB +
        • +
        • + LICENSE.txt441 B +
        • +
        • + sl_sst-ud-train.txt103 kB +
        • +
        +
      • +
      • + UD_English-GUMReddit +
          +
        • + README.md24 kB +
        • +
        • + en_gumreddit-ud-train.txt23 kB +
        • +
        • + en_gumreddit-ud-train.conllu1 MB +
        • +
        • + en_gumreddit-ud-dev.conllu171 kB +
        • +
        • + get_text.py28 kB +
        • +
        • + en_gumreddit-ud-dev.txt3 kB +
        • +
        • + stats.xml6 kB +
        • +
        • + en_gumreddit-ud-test.txt3 kB +
        • +
        • + LICENSE.txt313 B +
        • +
        • + en_gumreddit-ud-test.conllu172 kB +
        • +
        +
      • +
      • + UD_Guarani-OldTuDeT +
          +
        • + stats.xml8 kB +
        • +
        • + README.md2 kB +
        • +
        • + gn_oldtudet-ud-test.txt1 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + gn_oldtudet-ud-test.conllu18 kB +
        • +
        +
      • +
      • + UD_Warlpiri-UFAL +
          +
        • + stats.xml6 kB +
        • +
        • + README.md870 B +
        • +
        • + LICENSE.txt202 B +
        • +
        • + wbp_ufal-ud-test.txt2 kB +
        • +
        • + wbp_ufal-ud-test.conllu37 kB +
        • +
        +
      • +
      • + UD_Norwegian-Bokmaal +
          +
        • + README.md7 kB +
        • +
        • + no_bokmaal-ud-dev.txt195 kB +
        • +
        • + no_bokmaal-ud-train.txt1 MB +
        • +
        • + no_bokmaal-ud-test.txt161 kB +
        • +
        • + stats.xml9 kB +
        • +
        • + no_bokmaal-ud-train.conllu15 MB +
        • +
        • + no_bokmaal-ud-test.conllu1 MB +
        • +
        • + no_bokmaal-ud-dev.conllu2 MB +
        • +
        • + LICENSE.txt68 B +
        • +
        +
      • +
      • + UD_French-FQB +
          +
        • + stats.xml8 kB +
        • +
        • + fr_fqb-ud-test.conllu1 MB +
        • +
        • + README.md3 kB +
        • +
        • + fr_fqb-ud-test.txt117 kB +
        • +
        • + LICENSE.txt14 kB +
        • +
        +
      • +
      • + UD_South_Levantine_Arabic-MADAR +
          +
        • + stats.xml4 kB +
        • +
        • + README.md2 kB +
        • +
        • + ajp_madar-ud-test.conllu42 kB +
        • +
        • + ajp_madar-ud-test.txt5 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Chinese-GSDSimp +
          +
        • + zh_gsdsimp-ud-test.txt53 kB +
        • +
        • + README.md2 kB +
        • +
        • + zh_gsdsimp-ud-dev.conllu1 MB +
        • +
        • + zh_gsdsimp-ud-train.txt433 kB +
        • +
        • + zh_gsdsimp-ud-train.conllu8 MB +
        • +
        • + stats.xml5 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + zh_gsdsimp-ud-dev.txt55 kB +
        • +
        • + zh_gsdsimp-ud-test.conllu1 MB +
        • +
        +
      • +
      • + UD_Galician-CTG +
          +
        • + gl_ctg-ud-dev.conllu1 MB +
        • +
        • + README.md2 kB +
        • +
        • + gl_ctg-ud-test.conllu1 MB +
        • +
        • + gl_ctg-ud-dev.txt155 kB +
        • +
        • + gl_ctg-ud-train.conllu4 MB +
        • +
        • + gl_ctg-ud-test.txt156 kB +
        • +
        • + stats.xml4 kB +
        • +
        • + gl_ctg-ud-train.txt413 kB +
        • +
        • + LICENSE.txt173 B +
        • +
        +
      • +
      • + UD_Slovenian-SSJ +
          +
        • + sl_ssj-ud-dev.conllu1 MB +
        • +
        • + README.md5 kB +
        • +
        • + sl_ssj-ud-train.txt1 MB +
        • +
        • + sl_ssj-ud-test.conllu1 MB +
        • +
        • + sl_ssj-ud-train.conllu15 MB +
        • +
        • + sl_ssj-ud-dev.txt147 kB +
        • +
        • + stats.xml12 kB +
        • +
        • + LICENSE.txt222 B +
        • +
        • + sl_ssj-ud-test.txt141 kB +
        • +
        +
      • +
      • + UD_French-PUD +
          +
        • + fr_pud-ud-test.txt130 kB +
        • +
        • + stats.xml8 kB +
        • +
        • + fr_pud-ud-test.conllu1 MB +
        • +
        • + README.md5 kB +
        • +
        • + LICENSE.txt19 kB +
        • +
        +
      • +
      • + UD_English-GUM +
          +
        • + en_gum-ud-test.txt99 kB +
        • +
        • + README.md24 kB +
        • +
        • + en_gum-ud-dev.txt94 kB +
        • +
        • + en_gum-ud-train.conllu12 MB +
        • +
        • + en_gum-ud-dev.conllu1 MB +
        • +
        • + stats.xml10 kB +
        • +
        • + en_gum-ud-test.conllu1 MB +
        • +
        • + en_gum-ud-train.txt716 kB +
        • +
        • + LICENSE.txt1 kB +
        • +
        +
      • +
      • + UD_Moksha-JR +
          +
        • + stats.xml26 kB +
        • +
        • + README.md6 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + mdf_jr-ud-test.txt42 kB +
        • +
        • + mdf_jr-ud-test.conllu466 kB +
        • +
        +
      • +
      • + UD_Munduruku-TuDeT +
          +
        • + stats.xml8 kB +
        • +
        • + README.md2 kB +
        • +
        • + myu_tudet-ud-test.conllu73 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + myu_tudet-ud-test.txt5 kB +
        • +
        +
      • +
      • + UD_Indonesian-GSD +
          +
        • + README.md6 kB +
        • +
        • + id_gsd-ud-test.txt69 kB +
        • +
        • + id_gsd-ud-dev.conllu969 kB +
        • +
        • + id_gsd-ud-train.conllu7 MB +
        • +
        • + stats.xml8 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + id_gsd-ud-test.conllu903 kB +
        • +
        • + id_gsd-ud-dev.txt73 kB +
        • +
        • + id_gsd-ud-train.txt573 kB +
        • +
        +
      • +
      • + UD_Kyrgyz-KTMU +
          +
        • + stats.xml14 kB +
        • +
        • + README.md1 kB +
        • +
        • + ky_ktmu-ud-train.conllu62 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + ky_ktmu-ud-train.txt8 kB +
        • +
        • + ky_ktmu-ud-test.conllu594 kB +
        • +
        • + ky_ktmu-ud-test.txt78 kB +
        • +
        +
      • +
      • + UD_French-ParTUT +
          +
        • + README.md5 kB +
        • +
        • + fr_partut-ud-dev.conllu117 kB +
        • +
        • + fr_partut-ud-train.conllu1 MB +
        • +
        • + fr_partut-ud-test.txt14 kB +
        • +
        • + fr_partut-ud-train.txt128 kB +
        • +
        • + stats.xml8 kB +
        • +
        • + LICENSE.txt18 kB +
        • +
        • + fr_partut-ud-test.conllu165 kB +
        • +
        • + fr_partut-ud-dev.txt9 kB +
        • +
        +
      • +
      • + UD_Turkish-Tourism +
          +
        • + tr_tourism-ud-test.conllu715 kB +
        • +
        • + README.md1 kB +
        • +
        • + tr_tourism-ud-dev.conllu747 kB +
        • +
        • + tr_tourism-ud-train.conllu5 MB +
        • +
        • + stats.xml13 kB +
        • +
        • + tr_tourism-ud-train.txt477 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + tr_tourism-ud-dev.txt69 kB +
        • +
        • + tr_tourism-ud-test.txt67 kB +
        • +
        +
      • +
      • + UD_Spanish-GSD +
          +
        • + README.md5 kB +
        • +
        • + es_gsd-ud-test.conllu716 kB +
        • +
        • + es_gsd-ud-train.conllu22 MB +
        • +
        • + es_gsd-ud-test.txt61 kB +
        • +
        • + es_gsd-ud-train.txt1 MB +
        • +
        • + es_gsd-ud-dev.conllu2 MB +
        • +
        • + es_gsd-ud-dev.txt191 kB +
        • +
        • + stats.xml11 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Ancient_Greek-Perseus +
          +
        • + README.md4 kB +
        • +
        • + grc_perseus-ud-dev.txt250 kB +
        • +
        • + grc_perseus-ud-test.conllu1 MB +
        • +
        • + grc_perseus-ud-test.txt231 kB +
        • +
        • + grc_perseus-ud-train.txt1 MB +
        • +
        • + stats.xml10 kB +
        • +
        • + grc_perseus-ud-train.conllu14 MB +
        • +
        • + LICENSE.txt279 B +
        • +
        • + grc_perseus-ud-dev.conllu1 MB +
        • +
        +
      • +
      • + UD_Mbya_Guarani-Thomas +
          +
        • + stats.xml8 kB +
        • +
        • + README.md3 kB +
        • +
        • + gun_thomas-ud-test.txt7 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + gun_thomas-ud-test.conllu90 kB +
        • +
        +
      • +
      • + UD_Tagalog-Ugnayan +
          +
        • + stats.xml3 kB +
        • +
        • + README.md1 kB +
        • +
        • + tl_ugnayan-ud-test.txt5 kB +
        • +
        • + tl_ugnayan-ud-test.conllu53 kB +
        • +
        • + LICENSE.txt219 B +
        • +
        +
      • +
      • + UD_Italian-TWITTIRO +
          +
        • + README.md3 kB +
        • +
        • + it_twittiro-ud-test.conllu184 kB +
        • +
        • + it_twittiro-ud-test.txt15 kB +
        • +
        • + it_twittiro-ud-train.conllu1 MB +
        • +
        • + it_twittiro-ud-train.txt120 kB +
        • +
        • + stats.xml9 kB +
        • +
        • + it_twittiro-ud-dev.txt15 kB +
        • +
        • + it_twittiro-ud-dev.conllu188 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Skolt_Sami-Giellagas +
          +
        • + stats.xml12 kB +
        • +
        • + sms_giellagas-ud-test.conllu233 kB +
        • +
        • + sms_giellagas-ud-test.txt17 kB +
        • +
        • + README.md4 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_English-Atis +
          +
        • + en_atis-ud-test.conllu342 kB +
        • +
        • + README.md1 kB +
        • +
        • + en_atis-ud-train.conllu2 MB +
        • +
        • + en_atis-ud-test.txt36 kB +
        • +
        • + en_atis-ud-train.txt271 kB +
        • +
        • + en_atis-ud-dev.txt36 kB +
        • +
        • + stats.xml6 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + en_atis-ud-dev.conllu341 kB +
        • +
        +
      • +
      • + UD_Polish-LFG +
          +
        • + pl_lfg-ud-dev.txt74 kB +
        • +
        • + pl_lfg-ud-train.txt596 kB +
        • +
        • + README.md6 kB +
        • +
        • + pl_lfg-ud-test.txt74 kB +
        • +
        • + pl_lfg-ud-dev.conllu1 MB +
        • +
        • + pl_lfg-ud-test.conllu1 MB +
        • +
        • + stats.xml14 kB +
        • +
        • + LICENSE.txt34 kB +
        • +
        • + pl_lfg-ud-train.conllu11 MB +
        • +
        +
      • +
      • + UD_Russian-GSD +
          +
        • + ru_gsd-ud-dev.conllu1 MB +
        • +
        • + README.md1 kB +
        • +
        • + ru_gsd-ud-test.conllu1003 kB +
        • +
        • + ru_gsd-ud-dev.txt123 kB +
        • +
        • + ru_gsd-ud-train.txt794 kB +
        • +
        • + ru_gsd-ud-test.txt120 kB +
        • +
        • + stats.xml13 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + ru_gsd-ud-train.conllu6 MB +
        • +
        +
      • +
      • + UD_Classical_Chinese-Kyoto +
          +
        • + lzh_kyoto-ud-train.conllu34 MB +
        • +
        • + README.md4 kB +
        • +
        • + lzh_kyoto-ud-test.conllu2 MB +
        • +
        • + lzh_kyoto-ud-train.txt1 MB +
        • +
        • + lzh_kyoto-ud-dev.txt97 kB +
        • +
        • + lzh_kyoto-ud-dev.conllu2 MB +
        • +
        • + stats.xml7 kB +
        • +
        • + lzh_kyoto-ud-test.txt84 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Estonian-EWT +
          +
        • + et_ewt-ud-train.txt379 kB +
        • +
        • + README.md4 kB +
        • +
        • + et_ewt-ud-dev.txt54 kB +
        • +
        • + et_ewt-ud-dev.conllu698 kB +
        • +
        • + et_ewt-ud-test.conllu926 kB +
        • +
        • + et_ewt-ud-test.txt76 kB +
        • +
        • + et_ewt-ud-train.conllu4 MB +
        • +
        • + stats.xml13 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Chinese-PatentChar +
          +
        • + stats.xml2 kB +
        • +
        • + README.md1009 B +
        • +
        • + zh_patentchar-ud-test.txt11 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + zh_patentchar-ud-test.conllu115 kB +
        • +
        +
      • +
      • + UD_Yakut-YKTDT +
          +
        • + stats.xml10 kB +
        • +
        • + README.md2 kB +
        • +
        • + sah_yktdt-ud-test.txt15 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + sah_yktdt-ud-test.conllu148 kB +
        • +
        +
      • +
      • + UD_Indonesian-CSUI +
          +
        • + stats.xml7 kB +
        • +
        • + README.md3 kB +
        • +
        • + id_csui-ud-test.txt59 kB +
        • +
        • + id_csui-ud-train.txt108 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + id_csui-ud-test.conllu589 kB +
        • +
        • + id_csui-ud-train.conllu1 MB +
        • +
        +
      • +
      • + UD_Portuguese-PetroGold +
          +
        • + README.md3 kB +
        • +
        • + pt_petrogold-ud-test.txt154 kB +
        • +
        • + pt_petrogold-ud-dev.conllu1 MB +
        • +
        • + pt_petrogold-ud-train.conllu12 MB +
        • +
        • + stats.xml9 kB +
        • +
        • + pt_petrogold-ud-dev.txt115 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + pt_petrogold-ud-train.txt1 MB +
        • +
        • + pt_petrogold-ud-test.conllu1 MB +
        • +
        +
      • +
      • + UD_Lithuanian-ALKSNIS +
          +
        • + lt_alksnis-ud-train.txt317 kB +
        • +
        • + README.md4 kB +
        • +
        • + lt_alksnis-ud-test.conllu1 MB +
        • +
        • + lt_alksnis-ud-train.conllu4 MB +
        • +
        • + lt_alksnis-ud-test.txt69 kB +
        • +
        • + lt_alksnis-ud-dev.conllu1 MB +
        • +
        • + stats.xml13 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + lt_alksnis-ud-dev.txt78 kB +
        • +
        +
      • +
      • + UD_Dutch-Alpino +
          +
        • + nl_alpino-ud-test.conllu901 kB +
        • +
        • + nl_alpino-ud-train.conllu14 MB +
        • +
        • + nl_alpino-ud-train.txt1016 kB +
        • +
        • + nl_alpino-ud-dev.conllu942 kB +
        • +
        • + nl_alpino-ud-dev.txt62 kB +
        • +
        • + stats.xml7 kB +
        • +
        • + LICENSE.txt19 kB +
        • +
        • + README.txt5 kB +
        • +
        • + nl_alpino-ud-test.txt64 kB +
        • +
        +
      • +
      • + UD_Apurina-UFPA +
          +
        • + stats.xml9 kB +
        • +
        • + README.md3 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + apu_ufpa-ud-test.conllu115 kB +
        • +
        • + apu_ufpa-ud-test.txt5 kB +
        • +
        +
      • +
      • + UD_Livvi-KKPP +
          +
        • + stats.xml10 kB +
        • +
        • + olo_kkpp-ud-train.txt808 B +
        • +
        • + README.md4 kB +
        • +
        • + olo_kkpp-ud-test.txt9 kB +
        • +
        • + olo_kkpp-ud-test.conllu103 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + olo_kkpp-ud-train.conllu15 kB +
        • +
        +
      • +
      • + UD_German-PUD +
          +
        • + stats.xml10 kB +
        • +
        • + README.md5 kB +
        • +
        • + LICENSE.txt19 kB +
        • +
        • + de_pud-ud-test.txt126 kB +
        • +
        • + de_pud-ud-test.conllu1 MB +
        • +
        +
      • +
      • + UD_Western_Armenian-ArmTDP +
          +
        • + README.md3 kB +
        • +
        • + hyw_armtdp-ud-test.txt141 kB +
        • +
        • + hyw_armtdp-ud-train.txt1006 kB +
        • +
        • + hyw_armtdp-ud-dev.txt133 kB +
        • +
        • + hyw_armtdp-ud-test.conllu1 MB +
        • +
        • + hyw_armtdp-ud-dev.conllu1 MB +
        • +
        • + stats.xml24 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + hyw_armtdp-ud-train.conllu12 MB +
        • +
        +
      • +
      • + UD_Urdu-UDTB +
          +
        • + README.md2 kB +
        • +
        • + ur_udtb-ud-train.txt853 kB +
        • +
        • + ur_udtb-ud-test.txt117 kB +
        • +
        • + ur_udtb-ud-train.conllu11 MB +
        • +
        • + ur_udtb-ud-test.conllu1 MB +
        • +
        • + stats.xml11 kB +
        • +
        • + ur_udtb-ud-dev.txt115 kB +
        • +
        • + LICENSE.txt247 B +
        • +
        • + ur_udtb-ud-dev.conllu1 MB +
        • +
        +
      • +
      • + UD_Akkadian-PISANDUB +
          +
        • + stats.xml3 kB +
        • +
        • + README.md871 B +
        • +
        • + akk_pisandub-ud-test.txt15 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + akk_pisandub-ud-test.conllu99 kB +
        • +
        +
      • +
      • + UD_Galician-TreeGal +
          +
        • + stats.xml9 kB +
        • +
        • + README.md5 kB +
        • +
        • + gl_treegal-ud-test.txt50 kB +
        • +
        • + gl_treegal-ud-train.conllu1 MB +
        • +
        • + LICENSE.txt14 kB +
        • +
        • + gl_treegal-ud-train.txt76 kB +
        • +
        • + gl_treegal-ud-test.conllu670 kB +
        • +
        +
      • +
      • + UD_Old_Turkish-Tonqq +
          +
        • + stats.xml2 kB +
        • +
        • + otk_tonqq-ud-test.txt1 kB +
        • +
        • + README.md1 kB +
        • +
        • + otk_tonqq-ud-test.conllu10 kB +
        • +
        • + LICENSE.txt6 kB +
        • +
        +
      • +
      • + UD_Gheg-GPS +
          +
        • + stats.xml8 kB +
        • +
        • + README.md2 kB +
        • +
        • + aln_gps-ud-test.txt71 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + aln_gps-ud-test.conllu984 kB +
        • +
        +
      • +
      • + UD_Czech-FicTree +
          +
        • + README.md3 kB +
        • +
        • + cs_fictree-ud-test.conllu1 MB +
        • +
        • + cs_fictree-ud-test.txt86 kB +
        • +
        • + cs_fictree-ud-train.conllu13 MB +
        • +
        • + cs_fictree-ud-dev.txt86 kB +
        • +
        • + stats.xml15 kB +
        • +
        • + cs_fictree-ud-dev.conllu1 MB +
        • +
        • + LICENSE.txt219 B +
        • +
        • + cs_fictree-ud-train.txt696 kB +
        • +
        +
      • +
      • + UD_Italian-PoSTWITA +
          +
        • + it_postwita-ud-test.conllu759 kB +
        • +
        • + it_postwita-ud-train.txt526 kB +
        • +
        • + README.md4 kB +
        • +
        • + it_postwita-ud-dev.conllu732 kB +
        • +
        • + it_postwita-ud-train.conllu5 MB +
        • +
        • + stats.xml9 kB +
        • +
        • + LICENSE.txt18 kB +
        • +
        • + it_postwita-ud-dev.txt64 kB +
        • +
        • + it_postwita-ud-test.txt67 kB +
        • +
        +
      • +
      • + UD_Low_Saxon-LSDC +
          +
        • + stats.xml10 kB +
        • +
        • + README.md4 kB +
        • +
        • + nds_lsdc-ud-test.conllu236 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + nds_lsdc-ud-test.txt13 kB +
        • +
        +
      • +
      • + UD_Hebrew-IAHLTwiki +
          +
        • + README.md2 kB +
        • +
        • + he_iahltwiki-ud-train.conllu8 MB +
        • +
        • + he_iahltwiki-ud-dev.txt60 kB +
        • +
        • + he_iahltwiki-ud-dev.conllu713 kB +
        • +
        • + he_iahltwiki-ud-test.conllu810 kB +
        • +
        • + he_iahltwiki-ud-train.txt762 kB +
        • +
        • + stats.xml12 kB +
        • +
        • + he_iahltwiki-ud-test.txt68 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Polish-PDB +
          +
        • + pl_pdb-ud-train.txt1 MB +
        • +
        • + README.md5 kB +
        • +
        • + pl_pdb-ud-dev.conllu3 MB +
        • +
        • + pl_pdb-ud-test.txt203 kB +
        • +
        • + pl_pdb-ud-train.conllu27 MB +
        • +
        • + pl_pdb-ud-dev.txt210 kB +
        • +
        • + stats.xml17 kB +
        • +
        • + LICENSE.txt384 B +
        • +
        • + pl_pdb-ud-test.conllu3 MB +
        • +
        +
      • +
      • + UD_Croatian-SET +
          +
        • + hr_set-ud-dev.conllu1 MB +
        • +
        • + README.md5 kB +
        • +
        • + hr_set-ud-dev.txt130 kB +
        • +
        • + hr_set-ud-train.conllu11 MB +
        • +
        • + hr_set-ud-train.txt901 kB +
        • +
        • + stats.xml11 kB +
        • +
        • + hr_set-ud-test.txt143 kB +
        • +
        • + LICENSE.txt233 B +
        • +
        • + hr_set-ud-test.conllu1 MB +
        • +
        +
      • +
      • + UD_North_Sami-Giella +
          +
        • + stats.xml10 kB +
        • +
        • + README.md2 kB +
        • +
        • + sme_giella-ud-train.conllu1 MB +
        • +
        • + sme_giella-ud-train.txt107 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + sme_giella-ud-test.conllu668 kB +
        • +
        • + sme_giella-ud-test.txt70 kB +
        • +
        +
      • +
      • + UD_Old_Irish-DipWBG +
          +
        • + stats.xml8 kB +
        • +
        • + README.md2 kB +
        • +
        • + sga_dipwbg-ud-test.txt1 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + sga_dipwbg-ud-test.conllu31 kB +
        • +
        +
      • +
      • + UD_Khunsari-AHA +
          +
        • + stats.xml4 kB +
        • +
        • + README.md1 kB +
        • +
        • + kfm_aha-ud-test.conllu6 kB +
        • +
        • + kfm_aha-ud-test.txt542 B +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Xibe-XDT +
          +
        • + stats.xml16 kB +
        • +
        • + sjo_xdt-ud-test.txt217 kB +
        • +
        • + README.md1 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + sjo_xdt-ud-test.conllu1 MB +
        • +
        +
      • +
      • + UD_Maltese-MUDT +
          +
        • + mt_mudt-ud-dev.txt55 kB +
        • +
        • + README.md6 kB +
        • +
        • + mt_mudt-ud-train.conllu1020 kB +
        • +
        • + mt_mudt-ud-test.txt59 kB +
        • +
        • + mt_mudt-ud-dev.conllu454 kB +
        • +
        • + stats.xml3 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + mt_mudt-ud-train.txt123 kB +
        • +
        • + mt_mudt-ud-test.conllu489 kB +
        • +
        +
      • +
      • + UD_Persian-Seraji +
          +
        • + fa_seraji-ud-dev.conllu1 MB +
        • +
        • + README.md5 kB +
        • +
        • + fa_seraji-ud-test.txt134 kB +
        • +
        • + fa_seraji-ud-train.conllu11 MB +
        • +
        • + fa_seraji-ud-test.conllu1 MB +
        • +
        • + stats.xml9 kB +
        • +
        • + fa_seraji-ud-train.txt995 kB +
        • +
        • + LICENSE.txt110 B +
        • +
        • + fa_seraji-ud-dev.txt133 kB +
        • +
        +
      • +
      • + UD_Indonesian-PUD +
          +
        • + stats.xml8 kB +
        • +
        • + README.md8 kB +
        • +
        • + id_pud-ud-test.txt117 kB +
        • +
        • + LICENSE.txt19 kB +
        • +
        • + id_pud-ud-test.conllu1 MB +
        • +
        +
      • +
      • + UD_Belarusian-HSE +
          +
        • + be_hse-ud-test.txt180 kB +
        • +
        • + README.md7 kB +
        • +
        • + be_hse-ud-train.txt2 MB +
        • +
        • + be_hse-ud-dev.conllu1 MB +
        • +
        • + be_hse-ud-train.conllu27 MB +
        • +
        • + be_hse-ud-test.conllu1 MB +
        • +
        • + stats.xml17 kB +
        • +
        • + LICENSE.txt1021 B +
        • +
        • + be_hse-ud-dev.txt164 kB +
        • +
        +
      • +
      • + UD_Turkish-BOUN +
          +
        • + stats.xml14 kB +
        • +
        • + README.md4 kB +
        • +
        • + tr_boun-ud-train.conllu7 MB +
        • +
        • + tr_boun-ud-dev.txt81 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + tr_boun-ud-train.txt660 kB +
        • +
        • + tr_boun-ud-test.conllu933 kB +
        • +
        +
      • +
      • + UD_Norwegian-Nynorsk +
          +
        • + no_nynorsk-ud-dev.conllu1 MB +
        • +
        • + README.md5 kB +
        • +
        • + no_nynorsk-ud-test.txt135 kB +
        • +
        • + no_nynorsk-ud-dev.txt166 kB +
        • +
        • + stats.xml8 kB +
        • +
        • + no_nynorsk-ud-test.conllu1 MB +
        • +
        • + LICENSE.txt68 B +
        • +
        • + no_nynorsk-ud-train.txt1 MB +
        • +
        • + no_nynorsk-ud-train.conllu14 MB +
        • +
        +
      • +
      • + UD_Guajajara-TuDeT +
          +
        • + stats.xml13 kB +
        • +
        • + README.md3 kB +
        • +
        • + gub_tudet-ud-test.txt47 kB +
        • +
        • + gub_tudet-ud-test.conllu705 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Ligurian-GLT +
          +
        • + stats.xml8 kB +
        • +
        • + lij_glt-ud-test.conllu411 kB +
        • +
        • + lij_glt-ud-train.txt918 B +
        • +
        • + README.md1 kB +
        • +
        • + lij_glt-ud-train.conllu14 kB +
        • +
        • + LICENSE.txt3 kB +
        • +
        • + lij_glt-ud-test.txt27 kB +
        • +
        +
      • +
      • + UD_Romanian-SiMoNERo +
          +
        • + ro_simonero-ud-test.conllu1 MB +
        • +
        • + README.md2 kB +
        • +
        • + ro_simonero-ud-dev.conllu1 MB +
        • +
        • + ro_simonero-ud-test.txt93 kB +
        • +
        • + ro_simonero-ud-train.txt719 kB +
        • +
        • + ro_simonero-ud-dev.txt91 kB +
        • +
        • + stats.xml11 kB +
        • +
        • + ro_simonero-ud-train.conllu9 MB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Spanish-PUD +
          +
        • + stats.xml9 kB +
        • +
        • + es_pud-ud-test.conllu1 MB +
        • +
        • + README.md6 kB +
        • +
        • + LICENSE.txt19 kB +
        • +
        • + es_pud-ud-test.txt123 kB +
        • +
        +
      • +
      • + UD_Cebuano-GJA +
          +
        • + ceb_gja-ud-test.conllu99 kB +
        • +
        • + stats.xml7 kB +
        • +
        • + README.md1 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + ceb_gja-ud-test.txt5 kB +
        • +
        +
      • +
      • + UD_Serbian-SET +
          +
        • + sr_set-ud-test.txt67 kB +
        • +
        • + README.md1 kB +
        • +
        • + sr_set-ud-train.conllu5 MB +
        • +
        • + sr_set-ud-dev.txt68 kB +
        • +
        • + stats.xml11 kB +
        • +
        • + sr_set-ud-test.conllu847 kB +
        • +
        • + sr_set-ud-train.txt432 kB +
        • +
        • + LICENSE.txt230 B +
        • +
        • + sr_set-ud-dev.conllu888 kB +
        • +
        +
      • +
      • + UD_Tatar-NMCTT +
          +
        • + stats.xml12 kB +
        • +
        • + README.md1 kB +
        • +
        • + tt_nmctt-ud-test.txt26 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + tt_nmctt-ud-test.conllu220 kB +
        • +
        +
      • +
      • + UD_Hittite-HitTB +
          +
        • + stats.xml9 kB +
        • +
        • + README.md1 kB +
        • +
        • + hit_hittb-ud-test.conllu115 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + hit_hittb-ud-test.txt10 kB +
        • +
        +
      • +
      • + UD_Chinese-HK +
          +
        • + stats.xml4 kB +
        • +
        • + README.md4 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + zh_hk-ud-test.conllu872 kB +
        • +
        • + zh_hk-ud-test.txt41 kB +
        • +
        +
      • +
      • + UD_Marathi-UFAL +
          +
        • + README.md1 kB +
        • +
        • + mr_ufal-ud-train.conllu385 kB +
        • +
        • + mr_ufal-ud-test.txt4 kB +
        • +
        • + mr_ufal-ud-dev.conllu56 kB +
        • +
        • + mr_ufal-ud-dev.txt4 kB +
        • +
        • + mr_ufal-ud-train.txt33 kB +
        • +
        • + stats.xml14 kB +
        • +
        • + mr_ufal-ud-test.conllu51 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Maghrebi_Arabic_French-Arabizi +
          +
        • + qaf_arabizi-ud-dev.conllu222 kB +
        • +
        • + README.md3 kB +
        • +
        • + qaf_arabizi-ud-train.txt81 kB +
        • +
        • + qaf_arabizi-ud-test.conllu220 kB +
        • +
        • + qaf_arabizi-ud-dev.txt11 kB +
        • +
        • + qaf_arabizi-ud-train.conllu1 MB +
        • +
        • + stats.xml6 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + qaf_arabizi-ud-test.txt11 kB +
        • +
        +
      • +
      • + UD_Afrikaans-AfriBooms +
          +
        • + af_afribooms-ud-test.conllu618 kB +
        • +
        • + af_afribooms-ud-train.conllu2 MB +
        • +
        • + af_afribooms-ud-test.txt57 kB +
        • +
        • + stats.xml8 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + README.txt1 kB +
        • +
        • + af_afribooms-ud-dev.txt30 kB +
        • +
        • + af_afribooms-ud-dev.conllu321 kB +
        • +
        • + af_afribooms-ud-train.txt195 kB +
        • +
        +
      • +
      • + UD_Czech-CAC +
          +
        • + cs_cac-ud-test.conllu1 MB +
        • +
        • + cs_cac-ud-test.txt71 kB +
        • +
        • + README.md6 kB +
        • +
        • + cs_cac-ud-train.conllu51 MB +
        • +
        • + cs_cac-ud-dev.txt72 kB +
        • +
        • + cs_cac-ud-train.txt2 MB +
        • +
        • + stats.xml19 kB +
        • +
        • + LICENSE.txt265 B +
        • +
        • + cs_cac-ud-dev.conllu1 MB +
        • +
        +
      • +
      • + UD_Arabic-PADT +
          +
        • + README.md6 kB +
        • +
        • + ar_padt-ud-dev.conllu5 MB +
        • +
        • + ar_padt-ud-train.conllu38 MB +
        • +
        • + ar_padt-ud-train.txt1 MB +
        • +
        • + ar_padt-ud-test.txt234 kB +
        • +
        • + ar_padt-ud-test.conllu4 MB +
        • +
        • + stats.xml11 kB +
        • +
        • + ar_padt-ud-dev.txt241 kB +
        • +
        • + LICENSE.txt19 kB +
        • +
        +
      • +
      • + UD_English-Pronouns +
          +
        • + stats.xml5 kB +
        • +
        • + en_pronouns-ud-test.conllu138 kB +
        • +
        • + README.md9 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + en_pronouns-ud-test.txt7 kB +
        • +
        +
      • +
      • + UD_Upper_Sorbian-UFAL +
          +
        • + stats.xml11 kB +
        • +
        • + hsb_ufal-ud-test.conllu730 kB +
        • +
        • + README.md1 kB +
        • +
        • + hsb_ufal-ud-train.conllu31 kB +
        • +
        • + hsb_ufal-ud-test.txt64 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + hsb_ufal-ud-train.txt2 kB +
        • +
        +
      • +
      • + UD_Czech-PDT +
          +
        • + cs_pdt-ud-train.conllu144 MB +
        • +
        • + README.md12 kB +
        • +
        • + cs_pdt-ud-test.conllu21 MB +
        • +
        • + cs_pdt-ud-test.txt1 MB +
        • +
        • + cs_pdt-ud-dev.txt989 kB +
        • +
        • + cs_pdt-ud-dev.conllu19 MB +
        • +
        • + stats.xml18 kB +
        • +
        • + LICENSE.txt311 B +
        • +
        • + cs_pdt-ud-train.txt7 MB +
        • +
        +
      • +
      • + UD_Bororo-BDT +
          +
        • + stats.xml8 kB +
        • +
        • + README.md2 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + bor_bdt-ud-test.conllu63 kB +
        • +
        • + bor_bdt-ud-test.txt4 kB +
        • +
        +
      • +
      • + UD_Swedish_Sign_Language-SSLC +
          +
        • + stats.xml2 kB +
        • +
        • + swl_sslc-ud-test.txt15 kB +
        • +
        • + README.md1 kB +
        • +
        • + LICENSE.txt19 kB +
        • +
        • + swl_sslc-ud-test.conllu79 kB +
        • +
        +
      • +
      • + UD_Chinese-GSD +
          +
        • + README.md2 kB +
        • +
        • + zh_gsd-ud-test.conllu1 MB +
        • +
        • + zh_gsd-ud-train.conllu8 MB +
        • +
        • + zh_gsd-ud-train.txt433 kB +
        • +
        • + zh_gsd-ud-dev.txt55 kB +
        • +
        • + zh_gsd-ud-dev.conllu1 MB +
        • +
        • + stats.xml5 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + zh_gsd-ud-test.txt53 kB +
        • +
        +
      • +
      • + UD_Xavante-XDT +
          +
        • + stats.xml6 kB +
        • +
        • + xav_xdt-ud-test.txt8 kB +
        • +
        • + README.md1 kB +
        • +
        • + xav_xdt-ud-test.conllu119 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Arabic-PUD +
          +
        • + stats.xml9 kB +
        • +
        • + README.md5 kB +
        • +
        • + ar_pud-ud-test.txt168 kB +
        • +
        • + LICENSE.txt19 kB +
        • +
        • + ar_pud-ud-test.conllu2 MB +
        • +
        +
      • +
      • + UD_Russian-PUD +
          +
        • + stats.xml12 kB +
        • +
        • + README.md5 kB +
        • +
        • + LICENSE.txt19 kB +
        • +
        • + ru_pud-ud-test.txt209 kB +
        • +
        • + ru_pud-ud-test.conllu1 MB +
        • +
        +
      • +
      • + UD_Erzya-JR +
          +
        • + stats.xml31 kB +
        • +
        • + myv_jr-ud-test.txt107 kB +
        • +
        • + README.txt6 kB +
        • +
        • + myv_jr-ud-test.conllu1 MB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + myv_jr-ud-train.txt102 kB +
        • +
        • + myv_jr-ud-train.conllu1 MB +
        • +
        +
      • +
      • + UD_French-GSD +
          +
        • + fr_gsd-ud-train.conllu21 MB +
        • +
        • + README.md7 kB +
        • +
        • + fr_gsd-ud-dev.conllu2 MB +
        • +
        • + fr_gsd-ud-dev.txt184 kB +
        • +
        • + stats.xml10 kB +
        • +
        • + fr_gsd-ud-test.conllu636 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + fr_gsd-ud-test.txt49 kB +
        • +
        • + fr_gsd-ud-train.txt1 MB +
        • +
        +
      • +
      • + UD_Assyrian-AS +
          +
        • + stats.xml7 kB +
        • +
        • + aii_as-ud-test.conllu31 kB +
        • +
        • + README.md1 kB +
        • +
        • + aii_as-ud-test.txt4 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Chukchi-HSE +
          +
        • + stats.xml3 kB +
        • +
        • + README.md4 kB +
        • +
        • + ckt_hse-ud-test.txt72 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + ckt_hse-ud-test.conllu793 kB +
        • +
        +
      • +
      • + UD_Albanian-TSA +
          +
        • + stats.xml8 kB +
        • +
        • + sq_tsa-ud-test.conllu61 kB +
        • +
        • + README.md1 kB +
        • +
        • + sq_tsa-ud-test.txt5 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Javanese-CSUI +
          +
        • + stats.xml7 kB +
        • +
        • + jv_csui-ud-test.txt77 kB +
        • +
        • + README.md3 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + jv_csui-ud-test.conllu936 kB +
        • +
        +
      • +
      • + UD_Old_East_Slavic-RNC +
          +
        • + README.md20 kB +
        • +
        • + orv_rnc-ud-dev.txt87 kB +
        • +
        • + orv_rnc-ud-dev.conllu945 kB +
        • +
        • + orv_rnc-ud-test.conllu1 MB +
        • +
        • + stats.xml17 kB +
        • +
        • + orv_rnc-ud-train.txt175 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + orv_rnc-ud-test.txt183 kB +
        • +
        • + orv_rnc-ud-train.conllu1 MB +
        • +
        +
      • +
      • + UD_Old_Irish-DipSGG +
          +
        • + stats.xml8 kB +
        • +
        • + README.md3 kB +
        • +
        • + sga_dipsgg-ud-test.txt2 kB +
        • +
        • + LICENSE.txt15 B +
        • +
        • + sga_dipsgg-ud-test.conllu34 kB +
        • +
        +
      • +
      • + UD_Latin-LLCT +
          +
        • + la_llct-ud-dev.conllu2 MB +
        • +
        • + README.md9 kB +
        • +
        • + la_llct-ud-test.conllu2 MB +
        • +
        • + la_llct-ud-train.conllu17 MB +
        • +
        • + stats.xml13 kB +
        • +
        • + la_llct-ud-dev.txt136 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + la_llct-ud-test.txt136 kB +
        • +
        • + la_llct-ud-train.txt1 MB +
        • +
        +
      • +
      • + UD_Japanese-BCCWJ +
          +
        • + ja_bccwj-ud-train.txt902 kB +
        • +
        • + ja_bccwj-ud-train.conllu67 MB +
        • +
        • + ja_bccwj-ud-dev.txt177 kB +
        • +
        • + ja_bccwj-ud-test.conllu12 MB +
        • +
        • + merge +
            +
          • + test_pos.pkl2 MB +
          • +
          • + dev_pos.pkl2 MB +
          • +
          • + script +
              +
            • + lib.py5 kB +
            • +
            • + restore_word_unit_bccwj.py7 kB +
            • +
            • + convert_core_bccwj_pkl.py746 B +
            • +
            +
          • +
          • + misc_mapping.pkl23 MB +
          • +
          • + merge.sh1 kB +
          • +
          • + train_pos.pkl13 MB +
          • +
          +
        • +
        • + stats.xml3 kB +
        • +
        • + LICENSE.txt18 kB +
        • +
        • + README.txt3 kB +
        • +
        • + ja_bccwj-ud-test.txt165 kB +
        • +
        • + ja_bccwj-ud-dev.conllu13 MB +
        • +
        +
      • +
      • + UD_Latin-ITTB +
          +
        • + la_ittb-ud-train.txt2 MB +
        • +
        • + README.md11 kB +
        • +
        • + la_ittb-ud-dev.txt168 kB +
        • +
        • + la_ittb-ud-test.conllu2 MB +
        • +
        • + la_ittb-ud-dev.conllu2 MB +
        • +
        • + stats.xml17 kB +
        • +
        • + LICENSE.txt19 kB +
        • +
        • + la_ittb-ud-test.txt169 kB +
        • +
        • + la_ittb-ud-train.conllu37 MB +
        • +
        +
      • +
      • + UD_Italian-ParlaMint +
          +
        • + stats.xml8 kB +
        • +
        • + it_parlamint-ud-train.txt52 kB +
        • +
        • + README.md2 kB +
        • +
        • + it_parlamint-ud-train.conllu640 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + it_parlamint-ud-test.conllu669 kB +
        • +
        • + it_parlamint-ud-test.txt55 kB +
        • +
        +
      • +
      • + UD_Armenian-ArmTDP +
          +
        • + README.md4 kB +
        • +
        • + hy_armtdp-ud-train.conllu5 MB +
        • +
        • + hy_armtdp-ud-dev.conllu694 kB +
        • +
        • + hy_armtdp-ud-dev.txt57 kB +
        • +
        • + hy_armtdp-ud-test.txt51 kB +
        • +
        • + hy_armtdp-ud-train.txt434 kB +
        • +
        • + stats.xml24 kB +
        • +
        • + hy_armtdp-ud-test.conllu656 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Vietnamese-VTB +
          +
        • + README.md1 kB +
        • +
        • + vi_vtb-ud-test.txt71 kB +
        • +
        • + vi_vtb-ud-train.txt129 kB +
        • +
        • + vi_vtb-ud-train.conllu924 kB +
        • +
        • + vi_vtb-ud-dev.txt168 kB +
        • +
        • + stats.xml6 kB +
        • +
        • + LICENSE.txt19 kB +
        • +
        • + vi_vtb-ud-test.conllu526 kB +
        • +
        • + vi_vtb-ud-dev.conllu1 MB +
        • +
        +
      • +
      • + UD_Western_Sierra_Puebla_Nahuatl-ITML +
          +
        • + stats.xml12 kB +
        • +
        • + nhi_itml-ud-test.txt51 kB +
        • +
        • + README.md1 kB +
        • +
        • + nhi_itml-ud-test.conllu1 MB +
        • +
        • + LICENSE.txt202 B +
        • +
        +
      • +
      • + UD_Icelandic-IcePaHC +
          +
        • + is_icepahc-ud-dev.conllu11 MB +
        • +
        • + is_icepahc-ud-test.txt738 kB +
        • +
        • + README.md6 kB +
        • +
        • + is_icepahc-ud-dev.txt735 kB +
        • +
        • + is_icepahc-ud-train.conllu58 MB +
        • +
        • + stats.xml11 kB +
        • +
        • + LICENSE.txt202 B +
        • +
        • + is_icepahc-ud-train.txt3 MB +
        • +
        • + is_icepahc-ud-test.conllu11 MB +
        • +
        +
      • +
      +
    • +
    • + +
        +
      • + ... too many files ...0 B +
      - +
    • +
    +
    -
    \ No newline at end of file +
+
diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.scss b/src/app/item-page/simple/field-components/preview-section/preview-section.component.scss index 77ae9971b41..e4267ba0874 100644 --- a/src/app/item-page/simple/field-components/preview-section/preview-section.component.scss +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.scss @@ -1,48 +1,107 @@ -file-preview-box { - border: 1px solid black; +.file-preview-box { + border: 1px solid #ddd; + padding: 4px; .file-content { - display: flex; + display: flex !important; + width: 100%; + justify-content: space-between; - .preview-image { - width: 50%; + .dl-horizontal { + margin-bottom: 0; } - .file-info { - padding: 20px; + .thumbnails dl { + padding: 5px; + display: table; + } - p { - margin-bottom: 5px; + @media (min-width: 768px){ + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; } + } - .button-container { - margin-top: 20px; - - .download-btn, .preview-btn { - margin-right: 10px; - padding: 10px 20px; - border: none; - color: white; - cursor: pointer; - } + @media (min-width: 768px) { + .dl-horizontal dd { + margin-left: 180px; + } + } + - .download-btn { - background-color: blue; - } + .preview-image { + width: 10%; + height: 10%; + } + + } - .preview-btn { - background-color: green; - } - } + .button-container { + .download-btn, .preview-btn { + display: inline; + padding: .2em .6em .3em; + font-size: 12px; + font-weight: bold; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; + border: none; + color: white; + cursor: pointer; + background-color: #5bc0de; } } - .file-list { - padding: 20px; + .panel { + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + box-shadow: 0 1px 1px rgba(0,0,0,0.05); + } + + .panel-info { + border-color: #bce8f1; + } - ul { - list-style-type: none; - padding-left: 0; - } + .panel-info>.panel-heading { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; + } + + .treeview .foldername:before { + font-family: FontAwesome; + content: '\f07b'; + margin-right: 5px; + color: #a0a0a0; + } + + .treeview .filename:before { + font-family: FontAwesome; + content: '\f016'; + margin-right: 5px; + color: #a0a0a0; + } + + .treeview li { + padding: 0 0 0 8px; + margin: 0; + list-style: none; + } + + .pull-right { + float: right !important; + } + + .panel-body { + padding: 15px; } } \ No newline at end of file diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.ts b/src/app/item-page/simple/field-components/preview-section/preview-section.component.ts index b9f628c0e1b..f7cf45a6413 100644 --- a/src/app/item-page/simple/field-components/preview-section/preview-section.component.ts +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.ts @@ -25,43 +25,43 @@ export class PreviewSectionComponent implements OnInit { constructor(protected registryService: RegistryService) {} // Modified ngOnInit(): void { - // this.registryService - // .getMetadataBitstream('123456789/36', 'ORIGINAL,TEXT,THUMBNAIL') - // .subscribe( - // (remoteData: any) => { - // console.log('Received data:', remoteData); - // if ( - // remoteData && - // remoteData._embedded && - // remoteData._embedded.metadatabitstreams - // ) { - // this.fileList = this.parseFiles( - // remoteData._embedded.metadatabitstreams[0].fileInfo - // ); - // } - // }, - // (error: any) => { - // console.log('Received error:', error); - // } - // ); + this.registryService + .getMetadataBitstream('123456789/36', 'ORIGINAL,TEXT,THUMBNAIL') + .subscribe( + (remoteData: any) => { + console.log('Received data:', remoteData); + // if ( + // remoteData && + // remoteData._embedded && + // remoteData._embedded.metadatabitstreams + // ) { + // this.fileList = this.parseFiles( + // remoteData._embedded.metadatabitstreams[0].fileInfo + // ); + // } + }, + (error: any) => { + console.log('Received error:', error); + } + ); } - togglePreview() { - this.isPreviewVisible = !this.isPreviewVisible; - } + // togglePreview() { + // this.isPreviewVisible = !this.isPreviewVisible; + // } - parseFiles(files: any[]): any[] { - let parsedFiles: any[] = []; - for (let file of files) { - let parsedFile: any = {}; - parsedFile.name = file.name; - parsedFile.size = file.size; - parsedFile.isDirectory = file.isDirectory; - if (file.isDirectory && file.sub) { - parsedFile.sub = this.parseFiles(Object.values(file.sub)); - } - parsedFiles.push(parsedFile); - } - return parsedFiles; - } + // parseFiles(files: any[]): any[] { + // let parsedFiles: any[] = []; + // for (let file of files) { + // let parsedFile: any = {}; + // parsedFile.name = file.name; + // parsedFile.size = file.size; + // parsedFile.isDirectory = file.isDirectory; + // if (file.isDirectory && file.sub) { + // parsedFile.sub = this.parseFiles(Object.values(file.sub)); + // } + // parsedFiles.push(parsedFile); + // } + // return parsedFiles; + // } } diff --git a/src/app/item-page/simple/item-page.component.html b/src/app/item-page/simple/item-page.component.html index c4c245e5604..44ebca5cc0a 100644 --- a/src/app/item-page/simple/item-page.component.html +++ b/src/app/item-page/simple/item-page.component.html @@ -11,6 +11,7 @@ + diff --git a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html index 3a6ffd4a239..5abd2645e4c 100644 --- a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html +++ b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html @@ -109,6 +109,6 @@

[iconName]="'fa-paperclip'" [separator]="'
'"> - + From e794918d3dd3c3069bea38bb2a1046c50dd2b5df Mon Sep 17 00:00:00 2001 From: HuynhKhoa1601 Date: Fri, 14 Jul 2023 19:42:05 +0700 Subject: [PATCH 03/26] add logic for handling data from BE and refactor the UI --- .../builders/remote-data-build.service.ts | 2 +- src/app/core/data/data.service.ts | 2 +- .../data/metadata-bitstream-data.service.ts | 3 +- .../core/metadata/metadata-bitstream.model.ts | 4 +- .../metadata-bitstream.resource-type.ts | 2 +- src/app/core/registry/registry.service.ts | 188 +- src/app/item-page/item-page.module.ts | 22 +- .../file-description.component.html | 91 + .../file-description.component.scss | 106 + .../file-description.component.spec.ts | 52 + .../file-description.component.ts | 16 + .../file-tree-view.component.html | 24 + .../file-tree-view.component.scss | 23 + .../file-tree-view.component.spec.ts | 55 + .../file-tree-view.component.ts | 20 + .../preview-section.component.html | 4715 +---------------- .../preview-section.component.spec.ts | 52 +- .../preview-section.component.ts | 65 +- .../item-page/simple/item-page.component.html | 2 +- .../shared/item-relationships-utils.ts | 65 +- 20 files changed, 663 insertions(+), 4846 deletions(-) create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.scss create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.spec.ts create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.html create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.scss create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.spec.ts create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts diff --git a/src/app/core/cache/builders/remote-data-build.service.ts b/src/app/core/cache/builders/remote-data-build.service.ts index 6b67549f2d7..72acde8df9b 100644 --- a/src/app/core/cache/builders/remote-data-build.service.ts +++ b/src/app/core/cache/builders/remote-data-build.service.ts @@ -218,7 +218,7 @@ export class RemoteDataBuildService { ); const payload$ = this.buildPayload(requestEntry$, href$, ...linksToFollow); - + return this.toRemoteDataObservable(requestEntry$, payload$); } diff --git a/src/app/core/data/data.service.ts b/src/app/core/data/data.service.ts index 6bad02e7761..ce103069ba8 100644 --- a/src/app/core/data/data.service.ts +++ b/src/app/core/data/data.service.ts @@ -457,7 +457,7 @@ export abstract class DataService implements UpdateDa * requested after the response becomes stale * @param linksToFollow List of {@link FollowLinkConfig} that indicate which * {@link HALLink}s should be automatically resolved - * @return {Observable>} + * @return {Observable>>} * Return an observable that emits response from the server */ searchBy(searchMethod: string, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable>> { diff --git a/src/app/core/data/metadata-bitstream-data.service.ts b/src/app/core/data/metadata-bitstream-data.service.ts index 9e6c62c159e..4d51f3f05d9 100644 --- a/src/app/core/data/metadata-bitstream-data.service.ts +++ b/src/app/core/data/metadata-bitstream-data.service.ts @@ -20,6 +20,7 @@ import { HttpClient } from '@angular/common/http'; import { Store } from '@ngrx/store'; import { CoreState } from '../core.reducers'; import { ChangeAnalyzer } from './change-analyzer'; +import { tap } from 'rxjs/operators'; /** * A service responsible for fetching/sending data from/to the REST API on the metadatafields endpoint @@ -67,7 +68,7 @@ export class MetadataBitstreamDataService extends DataService new RequestParam('fileGrpType', hasValue(fileGrpType) ? fileGrpType : ''), ], }); - return this.searchBy(this.searchByHandleLinkPath, optionParams, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow) + return this.searchBy(this.searchByHandleLinkPath, optionParams, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); } // /** diff --git a/src/app/core/metadata/metadata-bitstream.model.ts b/src/app/core/metadata/metadata-bitstream.model.ts index b5f3baebce6..de51e91dad6 100644 --- a/src/app/core/metadata/metadata-bitstream.model.ts +++ b/src/app/core/metadata/metadata-bitstream.model.ts @@ -11,12 +11,12 @@ import { METADATA_BITSTREAM } from './metadata-bitstream.resource-type'; /** * Class the represents a File */ -class FileInfo { +export class FileInfo { @autoserialize name: string; @autoserialize content: any; @autoserialize size: string; @autoserialize isDirectory: boolean; - @autoserializeAs(FileInfo, 'sub') sub: {[key: string]: FileInfo}; + @autoserializeAs('sub') sub: {[key: string]: FileInfo}; } /** diff --git a/src/app/core/metadata/metadata-bitstream.resource-type.ts b/src/app/core/metadata/metadata-bitstream.resource-type.ts index ef5c337166e..f023a8c5259 100644 --- a/src/app/core/metadata/metadata-bitstream.resource-type.ts +++ b/src/app/core/metadata/metadata-bitstream.resource-type.ts @@ -7,4 +7,4 @@ import { ResourceType } from '../shared/resource-type'; * dependencies in webpack. */ -export const METADATA_BITSTREAM = new ResourceType('metadatabitstream'); \ No newline at end of file +export const METADATA_BITSTREAM = new ResourceType('metadatabitstream'); diff --git a/src/app/core/registry/registry.service.ts b/src/app/core/registry/registry.service.ts index e2980306176..e423c926809 100644 --- a/src/app/core/registry/registry.service.ts +++ b/src/app/core/registry/registry.service.ts @@ -3,7 +3,11 @@ import { Injectable } from '@angular/core'; import { RemoteData } from '../data/remote-data'; import { PaginatedList } from '../data/paginated-list.model'; import { FindListOptions } from '../data/request.models'; -import { hasValue, hasValueOperator, isNotEmptyOperator } from '../../shared/empty.util'; +import { + hasValue, + hasValueOperator, + isNotEmptyOperator, +} from '../../shared/empty.util'; import { getFirstSucceededRemoteDataPayload } from '../shared/operators'; import { createSelector, select, Store } from '@ngrx/store'; import { AppState } from '../../app.reducer'; @@ -18,7 +22,7 @@ import { MetadataRegistryEditFieldAction, MetadataRegistryEditSchemaAction, MetadataRegistrySelectFieldAction, - MetadataRegistrySelectSchemaAction + MetadataRegistrySelectSchemaAction, } from '../../admin/admin-registries/metadata-registry/metadata-registry.actions'; import { map, mergeMap, tap } from 'rxjs/operators'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -33,26 +37,38 @@ import { RequestParam } from '../cache/models/request-param.model'; import { NoContent } from '../shared/NoContent.model'; import { MetadataBitstream } from '../metadata/metadata-bitstream.model'; -const metadataRegistryStateSelector = (state: AppState) => state.metadataRegistry; -const editMetadataSchemaSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editSchema); -const selectedMetadataSchemasSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.selectedSchemas); -const editMetadataFieldSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editField); -const selectedMetadataFieldsSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.selectedFields); +const metadataRegistryStateSelector = (state: AppState) => + state.metadataRegistry; +const editMetadataSchemaSelector = createSelector( + metadataRegistryStateSelector, + (metadataState: MetadataRegistryState) => metadataState.editSchema +); +const selectedMetadataSchemasSelector = createSelector( + metadataRegistryStateSelector, + (metadataState: MetadataRegistryState) => metadataState.selectedSchemas +); +const editMetadataFieldSelector = createSelector( + metadataRegistryStateSelector, + (metadataState: MetadataRegistryState) => metadataState.editField +); +const selectedMetadataFieldsSelector = createSelector( + metadataRegistryStateSelector, + (metadataState: MetadataRegistryState) => metadataState.selectedFields +); /** * Service for registry related CRUD actions such as metadata schema, metadata field and bitstream format */ @Injectable() export class RegistryService { - - constructor(private store: Store, - private notificationsService: NotificationsService, - private translateService: TranslateService, - private metadataSchemaService: MetadataSchemaDataService, - private metadataFieldService: MetadataFieldDataService, - private metadataBitstreamDataService: MetadataBitstreamDataService) { - - } + constructor( + private store: Store, + private notificationsService: NotificationsService, + private translateService: TranslateService, + private metadataSchemaService: MetadataSchemaDataService, + private metadataFieldService: MetadataFieldDataService, + private metadataBitstreamDataService: MetadataBitstreamDataService + ) {} /** * Retrieves all metadata schemas @@ -64,8 +80,18 @@ export class RegistryService { * @param linksToFollow List of {@link FollowLinkConfig} that indicate which * {@link HALLink}s should be automatically resolved */ - public getMetadataSchemas(options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable>> { - return this.metadataSchemaService.findAll(options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + public getMetadataSchemas( + options: FindListOptions = {}, + useCachedVersionIfAvailable = true, + reRequestOnStale = true, + ...linksToFollow: FollowLinkConfig[] + ): Observable>> { + return this.metadataSchemaService.findAll( + options, + useCachedVersionIfAvailable, + reRequestOnStale, + ...linksToFollow + ); } /** @@ -78,17 +104,32 @@ export class RegistryService { * @param linksToFollow List of {@link FollowLinkConfig} that indicate which * {@link HALLink}s should be automatically resolved */ - public getMetadataSchemaByPrefix(prefix: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable> { + public getMetadataSchemaByPrefix( + prefix: string, + useCachedVersionIfAvailable = true, + reRequestOnStale = true, + ...linksToFollow: FollowLinkConfig[] + ): Observable> { // Temporary options to get ALL metadataschemas until there's a rest api endpoint for fetching a specific schema const options: FindListOptions = Object.assign(new FindListOptions(), { - elementsPerPage: 10000 + elementsPerPage: 10000, }); return this.getMetadataSchemas(options).pipe( getFirstSucceededRemoteDataPayload(), map((schemas: PaginatedList) => schemas.page), isNotEmptyOperator(), - map((schemas: MetadataSchema[]) => schemas.filter((schema) => schema.prefix === prefix)[0]), - mergeMap((schema: MetadataSchema) => this.metadataSchemaService.findById(`${schema.id}`, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow)) + map( + (schemas: MetadataSchema[]) => + schemas.filter((schema) => schema.prefix === prefix)[0] + ), + mergeMap((schema: MetadataSchema) => + this.metadataSchemaService.findById( + `${schema.id}`, + useCachedVersionIfAvailable, + reRequestOnStale, + ...linksToFollow + ) + ) ); } @@ -103,12 +144,24 @@ export class RegistryService { * @param linksToFollow List of {@link FollowLinkConfig} that indicate which * {@link HALLink}s should be automatically resolved */ - public getMetadataFieldsBySchema(schema: MetadataSchema, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable>> { - return this.metadataFieldService.findBySchema(schema, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + public getMetadataFieldsBySchema( + schema: MetadataSchema, + options: FindListOptions = {}, + useCachedVersionIfAvailable = true, + reRequestOnStale = true, + ...linksToFollow: FollowLinkConfig[] + ): Observable>> { + return this.metadataFieldService.findBySchema( + schema, + options, + useCachedVersionIfAvailable, + reRequestOnStale, + ...linksToFollow + ); } /** - * retrieves all metadatabistream that belong to a certain metadata + * retrieves all metadatabistream that belong to a certain metadata * @param schema The schema to filter by * @param options The options info used to retrieve the fields * @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's @@ -118,8 +171,22 @@ export class RegistryService { * @param linksToFollow List of {@link FollowLinkConfig} that indicate which * {@link HALLink}s should be automatically resolved */ - public getMetadataBitstream(handle: string, fileGrpType: string, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable> { - return this.metadataBitstreamDataService.searchByHandleParams(handle, fileGrpType, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + public getMetadataBitstream( + handle: string, + fileGrpType: string, + options: FindListOptions = {}, + useCachedVersionIfAvailable = true, + reRequestOnStale = true, + ...linksToFollow: FollowLinkConfig[] + ): Observable> { + return this.metadataBitstreamDataService.searchByHandleParams( + handle, + fileGrpType, + options, + useCachedVersionIfAvailable, + reRequestOnStale, + ...linksToFollow + ); } public editMetadataSchema(schema: MetadataSchema) { @@ -230,13 +297,17 @@ export class RegistryService { * - On update, a PutRequest is used * @param schema The MetadataSchema to create or update */ - public createOrUpdateMetadataSchema(schema: MetadataSchema): Observable { + public createOrUpdateMetadataSchema( + schema: MetadataSchema + ): Observable { const isUpdate = hasValue(schema.id); return this.metadataSchemaService.createOrUpdateMetadataSchema(schema).pipe( getFirstSucceededRemoteDataPayload(), hasValueOperator(), tap(() => { - this.showNotifications(true, isUpdate, false, { prefix: schema.prefix }); + this.showNotifications(true, isUpdate, false, { + prefix: schema.prefix, + }); }) ); } @@ -262,17 +333,24 @@ export class RegistryService { * @param field The MetadataField to create * @param schema The MetadataSchema to create the field in */ - public createMetadataField(field: MetadataField, schema: MetadataSchema): Observable { + public createMetadataField( + field: MetadataField, + schema: MetadataSchema + ): Observable { if (!field.qualifier) { field.qualifier = null; } - return this.metadataFieldService.create(field, new RequestParam('schemaId', schema.id)).pipe( - getFirstSucceededRemoteDataPayload(), - hasValueOperator(), - tap(() => { - this.showNotifications(true, false, true, { field: field.toString() }); - }) - ); + return this.metadataFieldService + .create(field, new RequestParam('schemaId', schema.id)) + .pipe( + getFirstSucceededRemoteDataPayload(), + hasValueOperator(), + tap(() => { + this.showNotifications(true, false, true, { + field: field.toString(), + }); + }) + ); } /** @@ -308,13 +386,23 @@ export class RegistryService { this.metadataFieldService.clearRequests(); } - private showNotifications(success: boolean, edited: boolean, isField: boolean, options: any) { + private showNotifications( + success: boolean, + edited: boolean, + isField: boolean, + options: any + ) { const prefix = 'admin.registries.schema.notification'; const suffix = success ? 'success' : 'failure'; const editedString = edited ? 'edited' : 'created'; const messages = observableCombineLatest( - this.translateService.get(success ? `${prefix}.${suffix}` : `${prefix}.${suffix}`), - this.translateService.get(`${prefix}${isField ? '.field' : ''}.${editedString}`, options) + this.translateService.get( + success ? `${prefix}.${suffix}` : `${prefix}.${suffix}` + ), + this.translateService.get( + `${prefix}${isField ? '.field' : ''}.${editedString}`, + options + ) ); messages.subscribe(([head, content]) => { if (success) { @@ -339,7 +427,23 @@ export class RegistryService { * {@link HALLink}s should be automatically resolved * @returns an observable that emits a remote data object with a page of metadata fields that match the query */ - queryMetadataFields(query: string, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable>> { - return this.metadataFieldService.searchByFieldNameParams(null, null, null, query, null, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + queryMetadataFields( + query: string, + options: FindListOptions = {}, + useCachedVersionIfAvailable = true, + reRequestOnStale = true, + ...linksToFollow: FollowLinkConfig[] + ): Observable>> { + return this.metadataFieldService.searchByFieldNameParams( + null, + null, + null, + query, + null, + options, + useCachedVersionIfAvailable, + reRequestOnStale, + ...linksToFollow + ); } } diff --git a/src/app/item-page/item-page.module.ts b/src/app/item-page/item-page.module.ts index 0218da43a6b..a2699098596 100644 --- a/src/app/item-page/item-page.module.ts +++ b/src/app/item-page/item-page.module.ts @@ -48,12 +48,14 @@ import { ChartsModule } from 'ng2-charts'; import { ClarinGenericItemFieldComponent } from './simple/field-components/clarin-generic-item-field/clarin-generic-item-field.component'; import { ClarinCollectionsItemFieldComponent } from './simple/field-components/clarin-collections-item-field/clarin-collections-item-field.component'; import { ClarinFilesItemFieldComponent } from './simple/field-components/clarin-files-item-field/clarin-files-item-field.component'; +import { FileDescriptionComponent } from './simple/field-components/preview-section/file-description/file-description.component'; +import { FileTreeViewComponent } from './simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component'; import { PreviewSectionComponent } from './simple/field-components/preview-section/preview-section.component'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator PublicationComponent, - UntypedItemComponent + UntypedItemComponent, ]; const DECLARATIONS = [ @@ -94,7 +96,9 @@ const DECLARATIONS = [ ClarinGenericItemFieldComponent, ClarinCollectionsItemFieldComponent, ClarinFilesItemFieldComponent, - PreviewSectionComponent + PreviewSectionComponent, + FileDescriptionComponent, + FileTreeViewComponent, ]; @NgModule({ @@ -107,15 +111,10 @@ const DECLARATIONS = [ JournalEntitiesModule.withEntryComponents(), ResearchEntitiesModule.withEntryComponents(), NgxGalleryModule, - ChartsModule - ], - declarations: [ - ...DECLARATIONS, - VersionedItemComponent + ChartsModule, ], - exports: [ - ...DECLARATIONS - ] + declarations: [...DECLARATIONS, VersionedItemComponent], + exports: [...DECLARATIONS], }) export class ItemPageModule { /** @@ -125,8 +124,7 @@ export class ItemPageModule { static withEntryComponents() { return { ngModule: ItemPageModule, - providers: ENTRY_COMPONENTS.map((component) => ({provide: component})) + providers: ENTRY_COMPONENTS.map((component) => ({ provide: component })), }; } - } diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html new file mode 100644 index 00000000000..8a5cd15c580 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html @@ -0,0 +1,91 @@ +
+
+ +
+
+
+
Name
+
+ {{ fileInput.name }} +
+
Size
+
+ {{ fileInput.fileSize }} +
+
Format
+
+ {{ fileInput.format }} +
+
Description
+
+ {{ fileInput.description }} +
+
MD5
+
+ {{ fileInput.checksum }} +
+
+ Preview +
+ +
+
+
+  File Preview +
+
+
    + + + + +
    {{fileInput.fileInfo[0].content}}
    +
    +
+
+
+
+
diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.scss b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.scss new file mode 100644 index 00000000000..2336ee20794 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.scss @@ -0,0 +1,106 @@ +.file-preview-box { + border: 1px solid #ddd; + padding: 4px; + margin-bottom: 10px; + + video { + margin-left: 100px; + } + + .file-content { + display: flex !important; + width: 100%; + justify-content: space-between; + + .dl-horizontal { + margin-bottom: 0; + } + + .thumbnails dl { + padding: 5px; + display: table; + } + + @media (min-width: 768px){ + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + } + + @media (min-width: 768px) { + .dl-horizontal dd { + margin-left: 180px; + } + } + + + .preview-image { + width: 10%; + height: 10%; + } + + } + + .button-container { + .download-btn, .preview-btn { + display: inline; + padding: .2em .6em .3em; + font-size: 14px; + font-weight: bold; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; + border: none; + color: white; + cursor: pointer; + background-color: #5bc0de; + } + } + + .panel { + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + box-shadow: 0 1px 1px rgba(0,0,0,0.05); + } + + .panel-info { + border-color: #bce8f1; + } + + .panel-info>.panel-heading { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; + } + + .panel-body { + padding: 15px; + + pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.428571429; + color: #333; + white-space: pre-wrap; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; + } + } + + .pull-right { + float: right !important; + } +} \ No newline at end of file diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.spec.ts b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.spec.ts new file mode 100644 index 00000000000..46586a7ce43 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.spec.ts @@ -0,0 +1,52 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { MetadataBitstream } from 'src/app/core/metadata/metadata-bitstream.model'; +import { ResourceType } from 'src/app/core/shared/resource-type'; +import { FileDescriptionComponent } from './file-description.component'; + +describe('FileDescriptionComponent', () => { + let component: FileDescriptionComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [FileDescriptionComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(FileDescriptionComponent); + component = fixture.componentInstance; + + // Mock the input value + const fileInput = new MetadataBitstream(); + fileInput.id = 123; + fileInput.name = 'testFile'; + fileInput.description = 'test description'; + fileInput.fileSize = '5MB'; + fileInput.checksum = 'abc'; + fileInput.type = new ResourceType('item'); + fileInput.fileInfo = []; + fileInput.format = 'application/pdf'; + fileInput.canPreview = false; + fileInput._links = { + self: { href: '' }, + schema: { href: '' }, + }; + + component.fileInput = fileInput; + + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should display the file name', () => { + const fileNameElement = fixture.debugElement.query( + By.css('.file-content dd') + ).nativeElement; + expect(fileNameElement.textContent).toContain('testFile'); + }); +}); diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts new file mode 100644 index 00000000000..68145d2fff4 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts @@ -0,0 +1,16 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { MetadataBitstream } from 'src/app/core/metadata/metadata-bitstream.model'; + +@Component({ + selector: 'ds-file-description', + templateUrl: './file-description.component.html', + styleUrls: ['./file-description.component.scss'], +}) +export class FileDescriptionComponent implements OnInit { + @Input() + fileInput: MetadataBitstream; + + ngOnInit(): void { + console.log(this.fileInput); + } +} diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.html b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.html new file mode 100644 index 00000000000..b61251030b7 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.html @@ -0,0 +1,24 @@ +
  • + + + {{ node.name }} + + + + + {{ node.name }}{{ node.size }} + + +
      + +
    +
  • \ No newline at end of file diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.scss b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.scss new file mode 100644 index 00000000000..1aaef2bf84c --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.scss @@ -0,0 +1,23 @@ +.foldername:before { + font-family: FontAwesome; + content: '\f07b'; + margin-right: 5px; + color: #a0a0a0; +} + +.filename:before { + font-family: FontAwesome; + content: '\f016'; + margin-right: 5px; + color: #a0a0a0; +} + + li { + padding: 0 0 0 8px; + margin: 0; + list-style: none; +} + +.pull-right { + float: right !important; +} \ No newline at end of file diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.spec.ts b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.spec.ts new file mode 100644 index 00000000000..606370da57a --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.spec.ts @@ -0,0 +1,55 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { FileInfo, MetadataBitstream } from 'src/app/core/metadata/metadata-bitstream.model'; +import { FileTreeViewComponent } from './file-tree-view.component'; + +describe('FileTreeViewComponent', () => { + let component: FileTreeViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ FileTreeViewComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(FileTreeViewComponent); + component = fixture.componentInstance; + + // Mock the node input value + const fileInfo = new FileInfo(); + fileInfo.name = 'TestFolder'; + fileInfo.isDirectory = true; + fileInfo.size = null; + fileInfo.content = null; // add content property + fileInfo.sub = { + 'TestSubFolder': { + name: 'TestSubFolder', + isDirectory: true, + size: null, + content: null, // add content property + sub: null + } + }; + + const metadataBitstream = new MetadataBitstream(); + metadataBitstream.fileInfo = [fileInfo]; + component.node = fileInfo; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should display the node name', () => { + const nodeNameElement = fixture.debugElement.query(By.css('.foldername')).nativeElement; + expect(nodeNameElement.textContent).toContain('TestFolder'); + }); + + it('should correctly get the keys of the sub object', () => { + expect(component.getKeys(component.node.sub)).toEqual(['TestSubFolder']); + }); +}); diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts new file mode 100644 index 00000000000..4471ebb25b7 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts @@ -0,0 +1,20 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { FileInfo } from 'src/app/core/metadata/metadata-bitstream.model'; + +@Component({ + selector: 'ds-file-tree-view', + templateUrl: './file-tree-view.component.html', + styleUrls: ['./file-tree-view.component.scss'], +}) +export class FileTreeViewComponent implements OnInit { + @Input() + node: FileInfo; + + getKeys(obj: any): string[] { + return Object.keys(obj); + } + + ngOnInit(): void { + console.log(this.node); + } +} diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.html b/src/app/item-page/simple/field-components/preview-section/preview-section.component.html index 328e3c21251..37ba7d1ce28 100644 --- a/src/app/item-page/simple/field-components/preview-section/preview-section.component.html +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.html @@ -1,4712 +1,3 @@ -
    -
    -
    -
    Name
    -
    - ud-treebanks-v2.12.tgz -
    -
    Size
    -
    497.82 MB
    -
    Format
    -
    application/x-gzip
    -
    Description
    -
    Treebank data
    -
    MD5
    -
    - afb7546d9591a82f372686bcc100db52 -
    -
    - Preview -
    - -
    -
    -
    -  File Preview -
    -
    -
      -
    • - ud-treebanks-v2.12 -
        -
      • - UD_English-PUD -
          -
        • - stats.xml8 kB -
        • -
        • - en_pud-ud-test.conllu1 MB -
        • -
        • - README.md6 kB -
        • -
        • - en_pud-ud-test.txt109 kB -
        • -
        • - LICENSE.txt19 kB -
        • -
        -
      • -
      • - UD_Finnish-PUD -
          -
        • - stats.xml17 kB -
        • -
        • - README.txt2 kB -
        • -
        • - fi_pud-ud-test.txt119 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - fi_pud-ud-test.conllu1 MB -
        • -
        -
      • -
      • - UD_Telugu-MTG -
          -
        • - te_mtg-ud-test.txt10 kB -
        • -
        • - README.md1 kB -
        • -
        • - te_mtg-ud-train.conllu494 kB -
        • -
        • - te_mtg-ud-dev.conllu64 kB -
        • -
        • - stats.xml3 kB -
        • -
        • - te_mtg-ud-test.conllu70 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - te_mtg-ud-dev.txt9 kB -
        • -
        • - te_mtg-ud-train.txt72 kB -
        • -
        -
      • -
      • - UD_Neapolitan-RB -
          -
        • - stats.xml1 kB -
        • -
        • - README.md1 kB -
        • -
        • - nap_rb-ud-test.conllu431 B -
        • -
        • - LICENSE.txt202 B -
        • -
        • - nap_rb-ud-test.txt56 B -
        • -
        -
      • -
      • - UD_Swedish-Talbanken -
          -
        • - sv_talbanken-ud-test.txt122 kB -
        • -
        • - README.md7 kB -
        • -
        • - sv_talbanken-ud-train.txt402 kB -
        • -
        • - stats.xml9 kB -
        • -
        • - LICENSE.txt20 kB -
        • -
        • - sv_talbanken-ud-train.conllu5 MB -
        • -
        • - sv_talbanken-ud-dev.conllu834 kB -
        • -
        • - sv_talbanken-ud-test.conllu1 MB -
        • -
        • - sv_talbanken-ud-dev.txt58 kB -
        • -
        -
      • -
      • - UD_Romanian-RRT -
          -
        • - README.md5 kB -
        • -
        • - ro_rrt-ud-dev.txt98 kB -
        • -
        • - ro_rrt-ud-train.conllu13 MB -
        • -
        • - stats.xml12 kB -
        • -
        • - LICENSE.txt66 B -
        • -
        • - ro_rrt-ud-dev.conllu1 MB -
        • -
        • - ro_rrt-ud-test.conllu1 MB -
        • -
        • - ro_rrt-ud-train.txt1 MB -
        • -
        • - ro_rrt-ud-test.txt94 kB -
        • -
        -
      • -
      • - UD_Czech-CLTT -
          -
        • - cs_cltt-ud-dev.conllu1 MB -
        • -
        • - cs_cltt-ud-test.txt81 kB -
        • -
        • - README.md3 kB -
        • -
        • - cs_cltt-ud-train.txt96 kB -
        • -
        • - cs_cltt-ud-dev.txt76 kB -
        • -
        • - stats.xml13 kB -
        • -
        • - cs_cltt-ud-train.conllu1 MB -
        • -
        • - LICENSE.txt265 B -
        • -
        • - cs_cltt-ud-test.conllu1 MB -
        • -
        -
      • -
      • - UD_Czech-PUD -
          -
        • - stats.xml16 kB -
        • -
        • - README.md3 kB -
        • -
        • - cs_pud-ud-test.txt114 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - cs_pud-ud-test.conllu2 MB -
        • -
        -
      • -
      • - UD_Sinhala-STB -
          -
        • - stats.xml14 kB -
        • -
        • - README.md1 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - si_stb-ud-test.txt11 kB -
        • -
        • - si_stb-ud-test.conllu109 kB -
        • -
        -
      • -
      • - UD_German-GSD -
          -
        • - README.md9 kB -
        • -
        • - de_gsd-ud-dev.conllu882 kB -
        • -
        • - de_gsd-ud-dev.txt72 kB -
        • -
        • - de_gsd-ud-train.txt1 MB -
        • -
        • - de_gsd-ud-test.conllu1 MB -
        • -
        • - stats.xml11 kB -
        • -
        • - de_gsd-ud-train.conllu18 MB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - de_gsd-ud-test.txt97 kB -
        • -
        -
      • -
      • - UD_Zaar-Autogramm -
          -
        • - stats.xml10 kB -
        • -
        • - README.md2 kB -
        • -
        • - say_autogramm-ud-test.conllu951 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - say_autogramm-ud-test.txt42 kB -
        • -
        -
      • -
      • - UD_Akuntsu-TuDeT -
          -
        • - stats.xml7 kB -
        • -
        • - aqz_tudet-ud-test.conllu89 kB -
        • -
        • - README.md3 kB -
        • -
        • - aqz_tudet-ud-test.txt6 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Komi_Permyak-UH -
          -
        • - stats.xml14 kB -
        • -
        • - README.md6 kB -
        • -
        • - koi_uh-ud-test.conllu107 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - koi_uh-ud-test.txt8 kB -
        • -
        -
      • -
      • - UD_Pomak-Philotis -
          -
        • - README.md2 kB -
        • -
        • - qpm_philotis-ud-train.conllu5 MB -
        • -
        • - qpm_philotis-ud-test.txt45 kB -
        • -
        • - qpm_philotis-ud-train.txt357 kB -
        • -
        • - qpm_philotis-ud-dev.txt45 kB -
        • -
        • - qpm_philotis-ud-dev.conllu690 kB -
        • -
        • - qpm_philotis-ud-test.conllu695 kB -
        • -
        • - stats.xml12 kB -
        • -
        • - LICENSE.txt417 B -
        • -
        -
      • -
      • - UD_Faroese-FarPaHC -
          -
        • - fo_farpahc-ud-dev.conllu465 kB -
        • -
        • - fo_farpahc-ud-dev.txt42 kB -
        • -
        • - README.md4 kB -
        • -
        • - fo_farpahc-ud-test.conllu459 kB -
        • -
        • - fo_farpahc-ud-train.txt105 kB -
        • -
        • - fo_farpahc-ud-train.conllu1 MB -
        • -
        • - stats.xml5 kB -
        • -
        • - fo_farpahc-ud-test.txt42 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Turkish-Penn -
          -
        • - README.md1 kB -
        • -
        • - tr_penn-ud-dev.conllu477 kB -
        • -
        • - tr_penn-ud-train.conllu11 MB -
        • -
        • - tr_penn-ud-test.txt69 kB -
        • -
        • - stats.xml13 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - tr_penn-ud-test.conllu682 kB -
        • -
        • - tr_penn-ud-dev.txt48 kB -
        • -
        • - tr_penn-ud-train.txt1 MB -
        • -
        -
      • -
      • - UD_Japanese-PUDLUW -
          -
        • - stats.xml4 kB -
        • -
        • - README.md5 kB -
        • -
        • - ja_pudluw-ud-test.txt138 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - ja_pudluw-ud-test.conllu4 MB -
        • -
        -
      • -
      • - UD_Chinese-PUD -
          -
        • - stats.xml5 kB -
        • -
        • - README.md5 kB -
        • -
        • - zh_pud-ud-test.conllu2 MB -
        • -
        • - zh_pud-ud-test.txt101 kB -
        • -
        • - LICENSE.txt19 kB -
        • -
        -
      • -
      • - UD_Teko-TuDeT -
          -
        • - stats.xml14 kB -
        • -
        • - eme_tudet-ud-test.conllu206 kB -
        • -
        • - eme_tudet-ud-test.txt17 kB -
        • -
        • - README.md1 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Latin-UDante -
          -
        • - la_udante-ud-train.conllu2 MB -
        • -
        • - README.md10 kB -
        • -
        • - la_udante-ud-dev.conllu1 MB -
        • -
        • - la_udante-ud-train.txt170 kB -
        • -
        • - stats.xml19 kB -
        • -
        • - la_udante-ud-test.txt78 kB -
        • -
        • - la_udante-ud-dev.txt67 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - la_udante-ud-test.conllu1 MB -
        • -
        -
      • -
      • - UD_Buryat-BDT -
          -
        • - stats.xml12 kB -
        • -
        • - README.txt1 kB -
        • -
        • - bxr_bdt-ud-train.txt1 kB -
        • -
        • - bxr_bdt-ud-train.conllu11 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - bxr_bdt-ud-test.txt114 kB -
        • -
        • - bxr_bdt-ud-test.conllu699 kB -
        • -
        -
      • -
      • - UD_Italian-MarkIT -
          -
        • - it_markit-ud-dev.txt54 kB -
        • -
        • - README.md1 kB -
        • -
        • - it_markit-ud-train.txt102 kB -
        • -
        • - it_markit-ud-test.txt52 kB -
        • -
        • - stats.xml8 kB -
        • -
        • - it_markit-ud-train.conllu1 MB -
        • -
        • - LICENSE.txt188 B -
        • -
        • - it_markit-ud-test.conllu642 kB -
        • -
        • - it_markit-ud-dev.conllu649 kB -
        • -
        -
      • -
      • - UD_Abaza-ATB -
          -
        • - stats.xml17 kB -
        • -
        • - abq_atb-ud-test.conllu125 kB -
        • -
        • - README.md1 kB -
        • -
        • - abq_atb-ud-test.txt9 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Slovenian-SST -
          -
        • - stats.xml11 kB -
        • -
        • - sl_sst-ud-test.txt53 kB -
        • -
        • - README.md5 kB -
        • -
        • - sl_sst-ud-train.conllu1 MB -
        • -
        • - sl_sst-ud-test.conllu988 kB -
        • -
        • - LICENSE.txt441 B -
        • -
        • - sl_sst-ud-train.txt103 kB -
        • -
        -
      • -
      • - UD_English-GUMReddit -
          -
        • - README.md24 kB -
        • -
        • - en_gumreddit-ud-train.txt23 kB -
        • -
        • - en_gumreddit-ud-train.conllu1 MB -
        • -
        • - en_gumreddit-ud-dev.conllu171 kB -
        • -
        • - get_text.py28 kB -
        • -
        • - en_gumreddit-ud-dev.txt3 kB -
        • -
        • - stats.xml6 kB -
        • -
        • - en_gumreddit-ud-test.txt3 kB -
        • -
        • - LICENSE.txt313 B -
        • -
        • - en_gumreddit-ud-test.conllu172 kB -
        • -
        -
      • -
      • - UD_Guarani-OldTuDeT -
          -
        • - stats.xml8 kB -
        • -
        • - README.md2 kB -
        • -
        • - gn_oldtudet-ud-test.txt1 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - gn_oldtudet-ud-test.conllu18 kB -
        • -
        -
      • -
      • - UD_Warlpiri-UFAL -
          -
        • - stats.xml6 kB -
        • -
        • - README.md870 B -
        • -
        • - LICENSE.txt202 B -
        • -
        • - wbp_ufal-ud-test.txt2 kB -
        • -
        • - wbp_ufal-ud-test.conllu37 kB -
        • -
        -
      • -
      • - UD_Norwegian-Bokmaal -
          -
        • - README.md7 kB -
        • -
        • - no_bokmaal-ud-dev.txt195 kB -
        • -
        • - no_bokmaal-ud-train.txt1 MB -
        • -
        • - no_bokmaal-ud-test.txt161 kB -
        • -
        • - stats.xml9 kB -
        • -
        • - no_bokmaal-ud-train.conllu15 MB -
        • -
        • - no_bokmaal-ud-test.conllu1 MB -
        • -
        • - no_bokmaal-ud-dev.conllu2 MB -
        • -
        • - LICENSE.txt68 B -
        • -
        -
      • -
      • - UD_French-FQB -
          -
        • - stats.xml8 kB -
        • -
        • - fr_fqb-ud-test.conllu1 MB -
        • -
        • - README.md3 kB -
        • -
        • - fr_fqb-ud-test.txt117 kB -
        • -
        • - LICENSE.txt14 kB -
        • -
        -
      • -
      • - UD_South_Levantine_Arabic-MADAR -
          -
        • - stats.xml4 kB -
        • -
        • - README.md2 kB -
        • -
        • - ajp_madar-ud-test.conllu42 kB -
        • -
        • - ajp_madar-ud-test.txt5 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Chinese-GSDSimp -
          -
        • - zh_gsdsimp-ud-test.txt53 kB -
        • -
        • - README.md2 kB -
        • -
        • - zh_gsdsimp-ud-dev.conllu1 MB -
        • -
        • - zh_gsdsimp-ud-train.txt433 kB -
        • -
        • - zh_gsdsimp-ud-train.conllu8 MB -
        • -
        • - stats.xml5 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - zh_gsdsimp-ud-dev.txt55 kB -
        • -
        • - zh_gsdsimp-ud-test.conllu1 MB -
        • -
        -
      • -
      • - UD_Galician-CTG -
          -
        • - gl_ctg-ud-dev.conllu1 MB -
        • -
        • - README.md2 kB -
        • -
        • - gl_ctg-ud-test.conllu1 MB -
        • -
        • - gl_ctg-ud-dev.txt155 kB -
        • -
        • - gl_ctg-ud-train.conllu4 MB -
        • -
        • - gl_ctg-ud-test.txt156 kB -
        • -
        • - stats.xml4 kB -
        • -
        • - gl_ctg-ud-train.txt413 kB -
        • -
        • - LICENSE.txt173 B -
        • -
        -
      • -
      • - UD_Slovenian-SSJ -
          -
        • - sl_ssj-ud-dev.conllu1 MB -
        • -
        • - README.md5 kB -
        • -
        • - sl_ssj-ud-train.txt1 MB -
        • -
        • - sl_ssj-ud-test.conllu1 MB -
        • -
        • - sl_ssj-ud-train.conllu15 MB -
        • -
        • - sl_ssj-ud-dev.txt147 kB -
        • -
        • - stats.xml12 kB -
        • -
        • - LICENSE.txt222 B -
        • -
        • - sl_ssj-ud-test.txt141 kB -
        • -
        -
      • -
      • - UD_French-PUD -
          -
        • - fr_pud-ud-test.txt130 kB -
        • -
        • - stats.xml8 kB -
        • -
        • - fr_pud-ud-test.conllu1 MB -
        • -
        • - README.md5 kB -
        • -
        • - LICENSE.txt19 kB -
        • -
        -
      • -
      • - UD_English-GUM -
          -
        • - en_gum-ud-test.txt99 kB -
        • -
        • - README.md24 kB -
        • -
        • - en_gum-ud-dev.txt94 kB -
        • -
        • - en_gum-ud-train.conllu12 MB -
        • -
        • - en_gum-ud-dev.conllu1 MB -
        • -
        • - stats.xml10 kB -
        • -
        • - en_gum-ud-test.conllu1 MB -
        • -
        • - en_gum-ud-train.txt716 kB -
        • -
        • - LICENSE.txt1 kB -
        • -
        -
      • -
      • - UD_Moksha-JR -
          -
        • - stats.xml26 kB -
        • -
        • - README.md6 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - mdf_jr-ud-test.txt42 kB -
        • -
        • - mdf_jr-ud-test.conllu466 kB -
        • -
        -
      • -
      • - UD_Munduruku-TuDeT -
          -
        • - stats.xml8 kB -
        • -
        • - README.md2 kB -
        • -
        • - myu_tudet-ud-test.conllu73 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - myu_tudet-ud-test.txt5 kB -
        • -
        -
      • -
      • - UD_Indonesian-GSD -
          -
        • - README.md6 kB -
        • -
        • - id_gsd-ud-test.txt69 kB -
        • -
        • - id_gsd-ud-dev.conllu969 kB -
        • -
        • - id_gsd-ud-train.conllu7 MB -
        • -
        • - stats.xml8 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - id_gsd-ud-test.conllu903 kB -
        • -
        • - id_gsd-ud-dev.txt73 kB -
        • -
        • - id_gsd-ud-train.txt573 kB -
        • -
        -
      • -
      • - UD_Kyrgyz-KTMU -
          -
        • - stats.xml14 kB -
        • -
        • - README.md1 kB -
        • -
        • - ky_ktmu-ud-train.conllu62 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - ky_ktmu-ud-train.txt8 kB -
        • -
        • - ky_ktmu-ud-test.conllu594 kB -
        • -
        • - ky_ktmu-ud-test.txt78 kB -
        • -
        -
      • -
      • - UD_French-ParTUT -
          -
        • - README.md5 kB -
        • -
        • - fr_partut-ud-dev.conllu117 kB -
        • -
        • - fr_partut-ud-train.conllu1 MB -
        • -
        • - fr_partut-ud-test.txt14 kB -
        • -
        • - fr_partut-ud-train.txt128 kB -
        • -
        • - stats.xml8 kB -
        • -
        • - LICENSE.txt18 kB -
        • -
        • - fr_partut-ud-test.conllu165 kB -
        • -
        • - fr_partut-ud-dev.txt9 kB -
        • -
        -
      • -
      • - UD_Turkish-Tourism -
          -
        • - tr_tourism-ud-test.conllu715 kB -
        • -
        • - README.md1 kB -
        • -
        • - tr_tourism-ud-dev.conllu747 kB -
        • -
        • - tr_tourism-ud-train.conllu5 MB -
        • -
        • - stats.xml13 kB -
        • -
        • - tr_tourism-ud-train.txt477 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - tr_tourism-ud-dev.txt69 kB -
        • -
        • - tr_tourism-ud-test.txt67 kB -
        • -
        -
      • -
      • - UD_Spanish-GSD -
          -
        • - README.md5 kB -
        • -
        • - es_gsd-ud-test.conllu716 kB -
        • -
        • - es_gsd-ud-train.conllu22 MB -
        • -
        • - es_gsd-ud-test.txt61 kB -
        • -
        • - es_gsd-ud-train.txt1 MB -
        • -
        • - es_gsd-ud-dev.conllu2 MB -
        • -
        • - es_gsd-ud-dev.txt191 kB -
        • -
        • - stats.xml11 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Ancient_Greek-Perseus -
          -
        • - README.md4 kB -
        • -
        • - grc_perseus-ud-dev.txt250 kB -
        • -
        • - grc_perseus-ud-test.conllu1 MB -
        • -
        • - grc_perseus-ud-test.txt231 kB -
        • -
        • - grc_perseus-ud-train.txt1 MB -
        • -
        • - stats.xml10 kB -
        • -
        • - grc_perseus-ud-train.conllu14 MB -
        • -
        • - LICENSE.txt279 B -
        • -
        • - grc_perseus-ud-dev.conllu1 MB -
        • -
        -
      • -
      • - UD_Mbya_Guarani-Thomas -
          -
        • - stats.xml8 kB -
        • -
        • - README.md3 kB -
        • -
        • - gun_thomas-ud-test.txt7 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - gun_thomas-ud-test.conllu90 kB -
        • -
        -
      • -
      • - UD_Tagalog-Ugnayan -
          -
        • - stats.xml3 kB -
        • -
        • - README.md1 kB -
        • -
        • - tl_ugnayan-ud-test.txt5 kB -
        • -
        • - tl_ugnayan-ud-test.conllu53 kB -
        • -
        • - LICENSE.txt219 B -
        • -
        -
      • -
      • - UD_Italian-TWITTIRO -
          -
        • - README.md3 kB -
        • -
        • - it_twittiro-ud-test.conllu184 kB -
        • -
        • - it_twittiro-ud-test.txt15 kB -
        • -
        • - it_twittiro-ud-train.conllu1 MB -
        • -
        • - it_twittiro-ud-train.txt120 kB -
        • -
        • - stats.xml9 kB -
        • -
        • - it_twittiro-ud-dev.txt15 kB -
        • -
        • - it_twittiro-ud-dev.conllu188 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Skolt_Sami-Giellagas -
          -
        • - stats.xml12 kB -
        • -
        • - sms_giellagas-ud-test.conllu233 kB -
        • -
        • - sms_giellagas-ud-test.txt17 kB -
        • -
        • - README.md4 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_English-Atis -
          -
        • - en_atis-ud-test.conllu342 kB -
        • -
        • - README.md1 kB -
        • -
        • - en_atis-ud-train.conllu2 MB -
        • -
        • - en_atis-ud-test.txt36 kB -
        • -
        • - en_atis-ud-train.txt271 kB -
        • -
        • - en_atis-ud-dev.txt36 kB -
        • -
        • - stats.xml6 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - en_atis-ud-dev.conllu341 kB -
        • -
        -
      • -
      • - UD_Polish-LFG -
          -
        • - pl_lfg-ud-dev.txt74 kB -
        • -
        • - pl_lfg-ud-train.txt596 kB -
        • -
        • - README.md6 kB -
        • -
        • - pl_lfg-ud-test.txt74 kB -
        • -
        • - pl_lfg-ud-dev.conllu1 MB -
        • -
        • - pl_lfg-ud-test.conllu1 MB -
        • -
        • - stats.xml14 kB -
        • -
        • - LICENSE.txt34 kB -
        • -
        • - pl_lfg-ud-train.conllu11 MB -
        • -
        -
      • -
      • - UD_Russian-GSD -
          -
        • - ru_gsd-ud-dev.conllu1 MB -
        • -
        • - README.md1 kB -
        • -
        • - ru_gsd-ud-test.conllu1003 kB -
        • -
        • - ru_gsd-ud-dev.txt123 kB -
        • -
        • - ru_gsd-ud-train.txt794 kB -
        • -
        • - ru_gsd-ud-test.txt120 kB -
        • -
        • - stats.xml13 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - ru_gsd-ud-train.conllu6 MB -
        • -
        -
      • -
      • - UD_Classical_Chinese-Kyoto -
          -
        • - lzh_kyoto-ud-train.conllu34 MB -
        • -
        • - README.md4 kB -
        • -
        • - lzh_kyoto-ud-test.conllu2 MB -
        • -
        • - lzh_kyoto-ud-train.txt1 MB -
        • -
        • - lzh_kyoto-ud-dev.txt97 kB -
        • -
        • - lzh_kyoto-ud-dev.conllu2 MB -
        • -
        • - stats.xml7 kB -
        • -
        • - lzh_kyoto-ud-test.txt84 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Estonian-EWT -
          -
        • - et_ewt-ud-train.txt379 kB -
        • -
        • - README.md4 kB -
        • -
        • - et_ewt-ud-dev.txt54 kB -
        • -
        • - et_ewt-ud-dev.conllu698 kB -
        • -
        • - et_ewt-ud-test.conllu926 kB -
        • -
        • - et_ewt-ud-test.txt76 kB -
        • -
        • - et_ewt-ud-train.conllu4 MB -
        • -
        • - stats.xml13 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Chinese-PatentChar -
          -
        • - stats.xml2 kB -
        • -
        • - README.md1009 B -
        • -
        • - zh_patentchar-ud-test.txt11 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - zh_patentchar-ud-test.conllu115 kB -
        • -
        -
      • -
      • - UD_Yakut-YKTDT -
          -
        • - stats.xml10 kB -
        • -
        • - README.md2 kB -
        • -
        • - sah_yktdt-ud-test.txt15 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - sah_yktdt-ud-test.conllu148 kB -
        • -
        -
      • -
      • - UD_Indonesian-CSUI -
          -
        • - stats.xml7 kB -
        • -
        • - README.md3 kB -
        • -
        • - id_csui-ud-test.txt59 kB -
        • -
        • - id_csui-ud-train.txt108 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - id_csui-ud-test.conllu589 kB -
        • -
        • - id_csui-ud-train.conllu1 MB -
        • -
        -
      • -
      • - UD_Portuguese-PetroGold -
          -
        • - README.md3 kB -
        • -
        • - pt_petrogold-ud-test.txt154 kB -
        • -
        • - pt_petrogold-ud-dev.conllu1 MB -
        • -
        • - pt_petrogold-ud-train.conllu12 MB -
        • -
        • - stats.xml9 kB -
        • -
        • - pt_petrogold-ud-dev.txt115 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - pt_petrogold-ud-train.txt1 MB -
        • -
        • - pt_petrogold-ud-test.conllu1 MB -
        • -
        -
      • -
      • - UD_Lithuanian-ALKSNIS -
          -
        • - lt_alksnis-ud-train.txt317 kB -
        • -
        • - README.md4 kB -
        • -
        • - lt_alksnis-ud-test.conllu1 MB -
        • -
        • - lt_alksnis-ud-train.conllu4 MB -
        • -
        • - lt_alksnis-ud-test.txt69 kB -
        • -
        • - lt_alksnis-ud-dev.conllu1 MB -
        • -
        • - stats.xml13 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - lt_alksnis-ud-dev.txt78 kB -
        • -
        -
      • -
      • - UD_Dutch-Alpino -
          -
        • - nl_alpino-ud-test.conllu901 kB -
        • -
        • - nl_alpino-ud-train.conllu14 MB -
        • -
        • - nl_alpino-ud-train.txt1016 kB -
        • -
        • - nl_alpino-ud-dev.conllu942 kB -
        • -
        • - nl_alpino-ud-dev.txt62 kB -
        • -
        • - stats.xml7 kB -
        • -
        • - LICENSE.txt19 kB -
        • -
        • - README.txt5 kB -
        • -
        • - nl_alpino-ud-test.txt64 kB -
        • -
        -
      • -
      • - UD_Apurina-UFPA -
          -
        • - stats.xml9 kB -
        • -
        • - README.md3 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - apu_ufpa-ud-test.conllu115 kB -
        • -
        • - apu_ufpa-ud-test.txt5 kB -
        • -
        -
      • -
      • - UD_Livvi-KKPP -
          -
        • - stats.xml10 kB -
        • -
        • - olo_kkpp-ud-train.txt808 B -
        • -
        • - README.md4 kB -
        • -
        • - olo_kkpp-ud-test.txt9 kB -
        • -
        • - olo_kkpp-ud-test.conllu103 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - olo_kkpp-ud-train.conllu15 kB -
        • -
        -
      • -
      • - UD_German-PUD -
          -
        • - stats.xml10 kB -
        • -
        • - README.md5 kB -
        • -
        • - LICENSE.txt19 kB -
        • -
        • - de_pud-ud-test.txt126 kB -
        • -
        • - de_pud-ud-test.conllu1 MB -
        • -
        -
      • -
      • - UD_Western_Armenian-ArmTDP -
          -
        • - README.md3 kB -
        • -
        • - hyw_armtdp-ud-test.txt141 kB -
        • -
        • - hyw_armtdp-ud-train.txt1006 kB -
        • -
        • - hyw_armtdp-ud-dev.txt133 kB -
        • -
        • - hyw_armtdp-ud-test.conllu1 MB -
        • -
        • - hyw_armtdp-ud-dev.conllu1 MB -
        • -
        • - stats.xml24 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - hyw_armtdp-ud-train.conllu12 MB -
        • -
        -
      • -
      • - UD_Urdu-UDTB -
          -
        • - README.md2 kB -
        • -
        • - ur_udtb-ud-train.txt853 kB -
        • -
        • - ur_udtb-ud-test.txt117 kB -
        • -
        • - ur_udtb-ud-train.conllu11 MB -
        • -
        • - ur_udtb-ud-test.conllu1 MB -
        • -
        • - stats.xml11 kB -
        • -
        • - ur_udtb-ud-dev.txt115 kB -
        • -
        • - LICENSE.txt247 B -
        • -
        • - ur_udtb-ud-dev.conllu1 MB -
        • -
        -
      • -
      • - UD_Akkadian-PISANDUB -
          -
        • - stats.xml3 kB -
        • -
        • - README.md871 B -
        • -
        • - akk_pisandub-ud-test.txt15 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - akk_pisandub-ud-test.conllu99 kB -
        • -
        -
      • -
      • - UD_Galician-TreeGal -
          -
        • - stats.xml9 kB -
        • -
        • - README.md5 kB -
        • -
        • - gl_treegal-ud-test.txt50 kB -
        • -
        • - gl_treegal-ud-train.conllu1 MB -
        • -
        • - LICENSE.txt14 kB -
        • -
        • - gl_treegal-ud-train.txt76 kB -
        • -
        • - gl_treegal-ud-test.conllu670 kB -
        • -
        -
      • -
      • - UD_Old_Turkish-Tonqq -
          -
        • - stats.xml2 kB -
        • -
        • - otk_tonqq-ud-test.txt1 kB -
        • -
        • - README.md1 kB -
        • -
        • - otk_tonqq-ud-test.conllu10 kB -
        • -
        • - LICENSE.txt6 kB -
        • -
        -
      • -
      • - UD_Gheg-GPS -
          -
        • - stats.xml8 kB -
        • -
        • - README.md2 kB -
        • -
        • - aln_gps-ud-test.txt71 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - aln_gps-ud-test.conllu984 kB -
        • -
        -
      • -
      • - UD_Czech-FicTree -
          -
        • - README.md3 kB -
        • -
        • - cs_fictree-ud-test.conllu1 MB -
        • -
        • - cs_fictree-ud-test.txt86 kB -
        • -
        • - cs_fictree-ud-train.conllu13 MB -
        • -
        • - cs_fictree-ud-dev.txt86 kB -
        • -
        • - stats.xml15 kB -
        • -
        • - cs_fictree-ud-dev.conllu1 MB -
        • -
        • - LICENSE.txt219 B -
        • -
        • - cs_fictree-ud-train.txt696 kB -
        • -
        -
      • -
      • - UD_Italian-PoSTWITA -
          -
        • - it_postwita-ud-test.conllu759 kB -
        • -
        • - it_postwita-ud-train.txt526 kB -
        • -
        • - README.md4 kB -
        • -
        • - it_postwita-ud-dev.conllu732 kB -
        • -
        • - it_postwita-ud-train.conllu5 MB -
        • -
        • - stats.xml9 kB -
        • -
        • - LICENSE.txt18 kB -
        • -
        • - it_postwita-ud-dev.txt64 kB -
        • -
        • - it_postwita-ud-test.txt67 kB -
        • -
        -
      • -
      • - UD_Low_Saxon-LSDC -
          -
        • - stats.xml10 kB -
        • -
        • - README.md4 kB -
        • -
        • - nds_lsdc-ud-test.conllu236 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - nds_lsdc-ud-test.txt13 kB -
        • -
        -
      • -
      • - UD_Hebrew-IAHLTwiki -
          -
        • - README.md2 kB -
        • -
        • - he_iahltwiki-ud-train.conllu8 MB -
        • -
        • - he_iahltwiki-ud-dev.txt60 kB -
        • -
        • - he_iahltwiki-ud-dev.conllu713 kB -
        • -
        • - he_iahltwiki-ud-test.conllu810 kB -
        • -
        • - he_iahltwiki-ud-train.txt762 kB -
        • -
        • - stats.xml12 kB -
        • -
        • - he_iahltwiki-ud-test.txt68 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Polish-PDB -
          -
        • - pl_pdb-ud-train.txt1 MB -
        • -
        • - README.md5 kB -
        • -
        • - pl_pdb-ud-dev.conllu3 MB -
        • -
        • - pl_pdb-ud-test.txt203 kB -
        • -
        • - pl_pdb-ud-train.conllu27 MB -
        • -
        • - pl_pdb-ud-dev.txt210 kB -
        • -
        • - stats.xml17 kB -
        • -
        • - LICENSE.txt384 B -
        • -
        • - pl_pdb-ud-test.conllu3 MB -
        • -
        -
      • -
      • - UD_Croatian-SET -
          -
        • - hr_set-ud-dev.conllu1 MB -
        • -
        • - README.md5 kB -
        • -
        • - hr_set-ud-dev.txt130 kB -
        • -
        • - hr_set-ud-train.conllu11 MB -
        • -
        • - hr_set-ud-train.txt901 kB -
        • -
        • - stats.xml11 kB -
        • -
        • - hr_set-ud-test.txt143 kB -
        • -
        • - LICENSE.txt233 B -
        • -
        • - hr_set-ud-test.conllu1 MB -
        • -
        -
      • -
      • - UD_North_Sami-Giella -
          -
        • - stats.xml10 kB -
        • -
        • - README.md2 kB -
        • -
        • - sme_giella-ud-train.conllu1 MB -
        • -
        • - sme_giella-ud-train.txt107 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - sme_giella-ud-test.conllu668 kB -
        • -
        • - sme_giella-ud-test.txt70 kB -
        • -
        -
      • -
      • - UD_Old_Irish-DipWBG -
          -
        • - stats.xml8 kB -
        • -
        • - README.md2 kB -
        • -
        • - sga_dipwbg-ud-test.txt1 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - sga_dipwbg-ud-test.conllu31 kB -
        • -
        -
      • -
      • - UD_Khunsari-AHA -
          -
        • - stats.xml4 kB -
        • -
        • - README.md1 kB -
        • -
        • - kfm_aha-ud-test.conllu6 kB -
        • -
        • - kfm_aha-ud-test.txt542 B -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Xibe-XDT -
          -
        • - stats.xml16 kB -
        • -
        • - sjo_xdt-ud-test.txt217 kB -
        • -
        • - README.md1 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - sjo_xdt-ud-test.conllu1 MB -
        • -
        -
      • -
      • - UD_Maltese-MUDT -
          -
        • - mt_mudt-ud-dev.txt55 kB -
        • -
        • - README.md6 kB -
        • -
        • - mt_mudt-ud-train.conllu1020 kB -
        • -
        • - mt_mudt-ud-test.txt59 kB -
        • -
        • - mt_mudt-ud-dev.conllu454 kB -
        • -
        • - stats.xml3 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - mt_mudt-ud-train.txt123 kB -
        • -
        • - mt_mudt-ud-test.conllu489 kB -
        • -
        -
      • -
      • - UD_Persian-Seraji -
          -
        • - fa_seraji-ud-dev.conllu1 MB -
        • -
        • - README.md5 kB -
        • -
        • - fa_seraji-ud-test.txt134 kB -
        • -
        • - fa_seraji-ud-train.conllu11 MB -
        • -
        • - fa_seraji-ud-test.conllu1 MB -
        • -
        • - stats.xml9 kB -
        • -
        • - fa_seraji-ud-train.txt995 kB -
        • -
        • - LICENSE.txt110 B -
        • -
        • - fa_seraji-ud-dev.txt133 kB -
        • -
        -
      • -
      • - UD_Indonesian-PUD -
          -
        • - stats.xml8 kB -
        • -
        • - README.md8 kB -
        • -
        • - id_pud-ud-test.txt117 kB -
        • -
        • - LICENSE.txt19 kB -
        • -
        • - id_pud-ud-test.conllu1 MB -
        • -
        -
      • -
      • - UD_Belarusian-HSE -
          -
        • - be_hse-ud-test.txt180 kB -
        • -
        • - README.md7 kB -
        • -
        • - be_hse-ud-train.txt2 MB -
        • -
        • - be_hse-ud-dev.conllu1 MB -
        • -
        • - be_hse-ud-train.conllu27 MB -
        • -
        • - be_hse-ud-test.conllu1 MB -
        • -
        • - stats.xml17 kB -
        • -
        • - LICENSE.txt1021 B -
        • -
        • - be_hse-ud-dev.txt164 kB -
        • -
        -
      • -
      • - UD_Turkish-BOUN -
          -
        • - stats.xml14 kB -
        • -
        • - README.md4 kB -
        • -
        • - tr_boun-ud-train.conllu7 MB -
        • -
        • - tr_boun-ud-dev.txt81 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - tr_boun-ud-train.txt660 kB -
        • -
        • - tr_boun-ud-test.conllu933 kB -
        • -
        -
      • -
      • - UD_Norwegian-Nynorsk -
          -
        • - no_nynorsk-ud-dev.conllu1 MB -
        • -
        • - README.md5 kB -
        • -
        • - no_nynorsk-ud-test.txt135 kB -
        • -
        • - no_nynorsk-ud-dev.txt166 kB -
        • -
        • - stats.xml8 kB -
        • -
        • - no_nynorsk-ud-test.conllu1 MB -
        • -
        • - LICENSE.txt68 B -
        • -
        • - no_nynorsk-ud-train.txt1 MB -
        • -
        • - no_nynorsk-ud-train.conllu14 MB -
        • -
        -
      • -
      • - UD_Guajajara-TuDeT -
          -
        • - stats.xml13 kB -
        • -
        • - README.md3 kB -
        • -
        • - gub_tudet-ud-test.txt47 kB -
        • -
        • - gub_tudet-ud-test.conllu705 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Ligurian-GLT -
          -
        • - stats.xml8 kB -
        • -
        • - lij_glt-ud-test.conllu411 kB -
        • -
        • - lij_glt-ud-train.txt918 B -
        • -
        • - README.md1 kB -
        • -
        • - lij_glt-ud-train.conllu14 kB -
        • -
        • - LICENSE.txt3 kB -
        • -
        • - lij_glt-ud-test.txt27 kB -
        • -
        -
      • -
      • - UD_Romanian-SiMoNERo -
          -
        • - ro_simonero-ud-test.conllu1 MB -
        • -
        • - README.md2 kB -
        • -
        • - ro_simonero-ud-dev.conllu1 MB -
        • -
        • - ro_simonero-ud-test.txt93 kB -
        • -
        • - ro_simonero-ud-train.txt719 kB -
        • -
        • - ro_simonero-ud-dev.txt91 kB -
        • -
        • - stats.xml11 kB -
        • -
        • - ro_simonero-ud-train.conllu9 MB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Spanish-PUD -
          -
        • - stats.xml9 kB -
        • -
        • - es_pud-ud-test.conllu1 MB -
        • -
        • - README.md6 kB -
        • -
        • - LICENSE.txt19 kB -
        • -
        • - es_pud-ud-test.txt123 kB -
        • -
        -
      • -
      • - UD_Cebuano-GJA -
          -
        • - ceb_gja-ud-test.conllu99 kB -
        • -
        • - stats.xml7 kB -
        • -
        • - README.md1 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - ceb_gja-ud-test.txt5 kB -
        • -
        -
      • -
      • - UD_Serbian-SET -
          -
        • - sr_set-ud-test.txt67 kB -
        • -
        • - README.md1 kB -
        • -
        • - sr_set-ud-train.conllu5 MB -
        • -
        • - sr_set-ud-dev.txt68 kB -
        • -
        • - stats.xml11 kB -
        • -
        • - sr_set-ud-test.conllu847 kB -
        • -
        • - sr_set-ud-train.txt432 kB -
        • -
        • - LICENSE.txt230 B -
        • -
        • - sr_set-ud-dev.conllu888 kB -
        • -
        -
      • -
      • - UD_Tatar-NMCTT -
          -
        • - stats.xml12 kB -
        • -
        • - README.md1 kB -
        • -
        • - tt_nmctt-ud-test.txt26 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - tt_nmctt-ud-test.conllu220 kB -
        • -
        -
      • -
      • - UD_Hittite-HitTB -
          -
        • - stats.xml9 kB -
        • -
        • - README.md1 kB -
        • -
        • - hit_hittb-ud-test.conllu115 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - hit_hittb-ud-test.txt10 kB -
        • -
        -
      • -
      • - UD_Chinese-HK -
          -
        • - stats.xml4 kB -
        • -
        • - README.md4 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - zh_hk-ud-test.conllu872 kB -
        • -
        • - zh_hk-ud-test.txt41 kB -
        • -
        -
      • -
      • - UD_Marathi-UFAL -
          -
        • - README.md1 kB -
        • -
        • - mr_ufal-ud-train.conllu385 kB -
        • -
        • - mr_ufal-ud-test.txt4 kB -
        • -
        • - mr_ufal-ud-dev.conllu56 kB -
        • -
        • - mr_ufal-ud-dev.txt4 kB -
        • -
        • - mr_ufal-ud-train.txt33 kB -
        • -
        • - stats.xml14 kB -
        • -
        • - mr_ufal-ud-test.conllu51 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Maghrebi_Arabic_French-Arabizi -
          -
        • - qaf_arabizi-ud-dev.conllu222 kB -
        • -
        • - README.md3 kB -
        • -
        • - qaf_arabizi-ud-train.txt81 kB -
        • -
        • - qaf_arabizi-ud-test.conllu220 kB -
        • -
        • - qaf_arabizi-ud-dev.txt11 kB -
        • -
        • - qaf_arabizi-ud-train.conllu1 MB -
        • -
        • - stats.xml6 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - qaf_arabizi-ud-test.txt11 kB -
        • -
        -
      • -
      • - UD_Afrikaans-AfriBooms -
          -
        • - af_afribooms-ud-test.conllu618 kB -
        • -
        • - af_afribooms-ud-train.conllu2 MB -
        • -
        • - af_afribooms-ud-test.txt57 kB -
        • -
        • - stats.xml8 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - README.txt1 kB -
        • -
        • - af_afribooms-ud-dev.txt30 kB -
        • -
        • - af_afribooms-ud-dev.conllu321 kB -
        • -
        • - af_afribooms-ud-train.txt195 kB -
        • -
        -
      • -
      • - UD_Czech-CAC -
          -
        • - cs_cac-ud-test.conllu1 MB -
        • -
        • - cs_cac-ud-test.txt71 kB -
        • -
        • - README.md6 kB -
        • -
        • - cs_cac-ud-train.conllu51 MB -
        • -
        • - cs_cac-ud-dev.txt72 kB -
        • -
        • - cs_cac-ud-train.txt2 MB -
        • -
        • - stats.xml19 kB -
        • -
        • - LICENSE.txt265 B -
        • -
        • - cs_cac-ud-dev.conllu1 MB -
        • -
        -
      • -
      • - UD_Arabic-PADT -
          -
        • - README.md6 kB -
        • -
        • - ar_padt-ud-dev.conllu5 MB -
        • -
        • - ar_padt-ud-train.conllu38 MB -
        • -
        • - ar_padt-ud-train.txt1 MB -
        • -
        • - ar_padt-ud-test.txt234 kB -
        • -
        • - ar_padt-ud-test.conllu4 MB -
        • -
        • - stats.xml11 kB -
        • -
        • - ar_padt-ud-dev.txt241 kB -
        • -
        • - LICENSE.txt19 kB -
        • -
        -
      • -
      • - UD_English-Pronouns -
          -
        • - stats.xml5 kB -
        • -
        • - en_pronouns-ud-test.conllu138 kB -
        • -
        • - README.md9 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - en_pronouns-ud-test.txt7 kB -
        • -
        -
      • -
      • - UD_Upper_Sorbian-UFAL -
          -
        • - stats.xml11 kB -
        • -
        • - hsb_ufal-ud-test.conllu730 kB -
        • -
        • - README.md1 kB -
        • -
        • - hsb_ufal-ud-train.conllu31 kB -
        • -
        • - hsb_ufal-ud-test.txt64 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - hsb_ufal-ud-train.txt2 kB -
        • -
        -
      • -
      • - UD_Czech-PDT -
          -
        • - cs_pdt-ud-train.conllu144 MB -
        • -
        • - README.md12 kB -
        • -
        • - cs_pdt-ud-test.conllu21 MB -
        • -
        • - cs_pdt-ud-test.txt1 MB -
        • -
        • - cs_pdt-ud-dev.txt989 kB -
        • -
        • - cs_pdt-ud-dev.conllu19 MB -
        • -
        • - stats.xml18 kB -
        • -
        • - LICENSE.txt311 B -
        • -
        • - cs_pdt-ud-train.txt7 MB -
        • -
        -
      • -
      • - UD_Bororo-BDT -
          -
        • - stats.xml8 kB -
        • -
        • - README.md2 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - bor_bdt-ud-test.conllu63 kB -
        • -
        • - bor_bdt-ud-test.txt4 kB -
        • -
        -
      • -
      • - UD_Swedish_Sign_Language-SSLC -
          -
        • - stats.xml2 kB -
        • -
        • - swl_sslc-ud-test.txt15 kB -
        • -
        • - README.md1 kB -
        • -
        • - LICENSE.txt19 kB -
        • -
        • - swl_sslc-ud-test.conllu79 kB -
        • -
        -
      • -
      • - UD_Chinese-GSD -
          -
        • - README.md2 kB -
        • -
        • - zh_gsd-ud-test.conllu1 MB -
        • -
        • - zh_gsd-ud-train.conllu8 MB -
        • -
        • - zh_gsd-ud-train.txt433 kB -
        • -
        • - zh_gsd-ud-dev.txt55 kB -
        • -
        • - zh_gsd-ud-dev.conllu1 MB -
        • -
        • - stats.xml5 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - zh_gsd-ud-test.txt53 kB -
        • -
        -
      • -
      • - UD_Xavante-XDT -
          -
        • - stats.xml6 kB -
        • -
        • - xav_xdt-ud-test.txt8 kB -
        • -
        • - README.md1 kB -
        • -
        • - xav_xdt-ud-test.conllu119 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Arabic-PUD -
          -
        • - stats.xml9 kB -
        • -
        • - README.md5 kB -
        • -
        • - ar_pud-ud-test.txt168 kB -
        • -
        • - LICENSE.txt19 kB -
        • -
        • - ar_pud-ud-test.conllu2 MB -
        • -
        -
      • -
      • - UD_Russian-PUD -
          -
        • - stats.xml12 kB -
        • -
        • - README.md5 kB -
        • -
        • - LICENSE.txt19 kB -
        • -
        • - ru_pud-ud-test.txt209 kB -
        • -
        • - ru_pud-ud-test.conllu1 MB -
        • -
        -
      • -
      • - UD_Erzya-JR -
          -
        • - stats.xml31 kB -
        • -
        • - myv_jr-ud-test.txt107 kB -
        • -
        • - README.txt6 kB -
        • -
        • - myv_jr-ud-test.conllu1 MB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - myv_jr-ud-train.txt102 kB -
        • -
        • - myv_jr-ud-train.conllu1 MB -
        • -
        -
      • -
      • - UD_French-GSD -
          -
        • - fr_gsd-ud-train.conllu21 MB -
        • -
        • - README.md7 kB -
        • -
        • - fr_gsd-ud-dev.conllu2 MB -
        • -
        • - fr_gsd-ud-dev.txt184 kB -
        • -
        • - stats.xml10 kB -
        • -
        • - fr_gsd-ud-test.conllu636 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - fr_gsd-ud-test.txt49 kB -
        • -
        • - fr_gsd-ud-train.txt1 MB -
        • -
        -
      • -
      • - UD_Assyrian-AS -
          -
        • - stats.xml7 kB -
        • -
        • - aii_as-ud-test.conllu31 kB -
        • -
        • - README.md1 kB -
        • -
        • - aii_as-ud-test.txt4 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Chukchi-HSE -
          -
        • - stats.xml3 kB -
        • -
        • - README.md4 kB -
        • -
        • - ckt_hse-ud-test.txt72 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - ckt_hse-ud-test.conllu793 kB -
        • -
        -
      • -
      • - UD_Albanian-TSA -
          -
        • - stats.xml8 kB -
        • -
        • - sq_tsa-ud-test.conllu61 kB -
        • -
        • - README.md1 kB -
        • -
        • - sq_tsa-ud-test.txt5 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Javanese-CSUI -
          -
        • - stats.xml7 kB -
        • -
        • - jv_csui-ud-test.txt77 kB -
        • -
        • - README.md3 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - jv_csui-ud-test.conllu936 kB -
        • -
        -
      • -
      • - UD_Old_East_Slavic-RNC -
          -
        • - README.md20 kB -
        • -
        • - orv_rnc-ud-dev.txt87 kB -
        • -
        • - orv_rnc-ud-dev.conllu945 kB -
        • -
        • - orv_rnc-ud-test.conllu1 MB -
        • -
        • - stats.xml17 kB -
        • -
        • - orv_rnc-ud-train.txt175 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - orv_rnc-ud-test.txt183 kB -
        • -
        • - orv_rnc-ud-train.conllu1 MB -
        • -
        -
      • -
      • - UD_Old_Irish-DipSGG -
          -
        • - stats.xml8 kB -
        • -
        • - README.md3 kB -
        • -
        • - sga_dipsgg-ud-test.txt2 kB -
        • -
        • - LICENSE.txt15 B -
        • -
        • - sga_dipsgg-ud-test.conllu34 kB -
        • -
        -
      • -
      • - UD_Latin-LLCT -
          -
        • - la_llct-ud-dev.conllu2 MB -
        • -
        • - README.md9 kB -
        • -
        • - la_llct-ud-test.conllu2 MB -
        • -
        • - la_llct-ud-train.conllu17 MB -
        • -
        • - stats.xml13 kB -
        • -
        • - la_llct-ud-dev.txt136 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - la_llct-ud-test.txt136 kB -
        • -
        • - la_llct-ud-train.txt1 MB -
        • -
        -
      • -
      • - UD_Japanese-BCCWJ -
          -
        • - ja_bccwj-ud-train.txt902 kB -
        • -
        • - ja_bccwj-ud-train.conllu67 MB -
        • -
        • - ja_bccwj-ud-dev.txt177 kB -
        • -
        • - ja_bccwj-ud-test.conllu12 MB -
        • -
        • - merge -
            -
          • - test_pos.pkl2 MB -
          • -
          • - dev_pos.pkl2 MB -
          • -
          • - script -
              -
            • - lib.py5 kB -
            • -
            • - restore_word_unit_bccwj.py7 kB -
            • -
            • - convert_core_bccwj_pkl.py746 B -
            • -
            -
          • -
          • - misc_mapping.pkl23 MB -
          • -
          • - merge.sh1 kB -
          • -
          • - train_pos.pkl13 MB -
          • -
          -
        • -
        • - stats.xml3 kB -
        • -
        • - LICENSE.txt18 kB -
        • -
        • - README.txt3 kB -
        • -
        • - ja_bccwj-ud-test.txt165 kB -
        • -
        • - ja_bccwj-ud-dev.conllu13 MB -
        • -
        -
      • -
      • - UD_Latin-ITTB -
          -
        • - la_ittb-ud-train.txt2 MB -
        • -
        • - README.md11 kB -
        • -
        • - la_ittb-ud-dev.txt168 kB -
        • -
        • - la_ittb-ud-test.conllu2 MB -
        • -
        • - la_ittb-ud-dev.conllu2 MB -
        • -
        • - stats.xml17 kB -
        • -
        • - LICENSE.txt19 kB -
        • -
        • - la_ittb-ud-test.txt169 kB -
        • -
        • - la_ittb-ud-train.conllu37 MB -
        • -
        -
      • -
      • - UD_Italian-ParlaMint -
          -
        • - stats.xml8 kB -
        • -
        • - it_parlamint-ud-train.txt52 kB -
        • -
        • - README.md2 kB -
        • -
        • - it_parlamint-ud-train.conllu640 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - it_parlamint-ud-test.conllu669 kB -
        • -
        • - it_parlamint-ud-test.txt55 kB -
        • -
        -
      • -
      • - UD_Armenian-ArmTDP -
          -
        • - README.md4 kB -
        • -
        • - hy_armtdp-ud-train.conllu5 MB -
        • -
        • - hy_armtdp-ud-dev.conllu694 kB -
        • -
        • - hy_armtdp-ud-dev.txt57 kB -
        • -
        • - hy_armtdp-ud-test.txt51 kB -
        • -
        • - hy_armtdp-ud-train.txt434 kB -
        • -
        • - stats.xml24 kB -
        • -
        • - hy_armtdp-ud-test.conllu656 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Vietnamese-VTB -
          -
        • - README.md1 kB -
        • -
        • - vi_vtb-ud-test.txt71 kB -
        • -
        • - vi_vtb-ud-train.txt129 kB -
        • -
        • - vi_vtb-ud-train.conllu924 kB -
        • -
        • - vi_vtb-ud-dev.txt168 kB -
        • -
        • - stats.xml6 kB -
        • -
        • - LICENSE.txt19 kB -
        • -
        • - vi_vtb-ud-test.conllu526 kB -
        • -
        • - vi_vtb-ud-dev.conllu1 MB -
        • -
        -
      • -
      • - UD_Western_Sierra_Puebla_Nahuatl-ITML -
          -
        • - stats.xml12 kB -
        • -
        • - nhi_itml-ud-test.txt51 kB -
        • -
        • - README.md1 kB -
        • -
        • - nhi_itml-ud-test.conllu1 MB -
        • -
        • - LICENSE.txt202 B -
        • -
        -
      • -
      • - UD_Icelandic-IcePaHC -
          -
        • - is_icepahc-ud-dev.conllu11 MB -
        • -
        • - is_icepahc-ud-test.txt738 kB -
        • -
        • - README.md6 kB -
        • -
        • - is_icepahc-ud-dev.txt735 kB -
        • -
        • - is_icepahc-ud-train.conllu58 MB -
        • -
        • - stats.xml11 kB -
        • -
        • - LICENSE.txt202 B -
        • -
        • - is_icepahc-ud-train.txt3 MB -
        • -
        • - is_icepahc-ud-test.conllu11 MB -
        • -
        -
      • -
      -
    • -
    • - -
        -
      • - ... too many files ...0 B -
      • -
      -
    • -
    -
    -
    -
    -
    +
    + +
    \ No newline at end of file diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts b/src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts index f4aeef26dd9..e88b994e9f0 100644 --- a/src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts @@ -1,25 +1,71 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { BehaviorSubject, of } from 'rxjs'; +import { MetadataBitstream } from 'src/app/core/metadata/metadata-bitstream.model'; +import { RegistryService } from 'src/app/core/registry/registry.service'; import { PreviewSectionComponent } from './preview-section.component'; +import { ResourceType } from 'src/app/core/shared/resource-type'; +import { HALLink } from 'src/app/core/shared/hal-link.model'; describe('PreviewSectionComponent', () => { let component: PreviewSectionComponent; let fixture: ComponentFixture; + let mockRegistryService: any; beforeEach(async () => { + mockRegistryService = jasmine.createSpyObj('RegistryService', [ + 'getMetadataBitstream', + ]); + await TestBed.configureTestingModule({ - declarations: [ PreviewSectionComponent ] - }) - .compileComponents(); + declarations: [PreviewSectionComponent], + providers: [{ provide: RegistryService, useValue: mockRegistryService }], + }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(PreviewSectionComponent); component = fixture.componentInstance; + + // Set up the mock service's getMetadataBitstream method to return a simple stream + const metadatabitstream = new MetadataBitstream(); + metadatabitstream.id = 123; + metadatabitstream.name = 'test'; + metadatabitstream.description = 'test'; + metadatabitstream.fileSize = '1MB'; + metadatabitstream.checksum = 'abc'; + metadatabitstream.type = new ResourceType('item'); + metadatabitstream.fileInfo = []; + metadatabitstream.format = 'text'; + metadatabitstream.canPreview = false; + metadatabitstream._links = { + self: new HALLink(), + schema: new HALLink(), + }; + + metadatabitstream._links.self.href = ''; + metadatabitstream._links.schema.href = ''; + const metadataBitstreams: MetadataBitstream[] = [metadatabitstream]; + const bitstreamStream = new BehaviorSubject(metadataBitstreams); + mockRegistryService.getMetadataBitstream.and.returnValue( + of(bitstreamStream) + ); + fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should call getMetadataBitstream on init', () => { + expect(mockRegistryService.getMetadataBitstream).toHaveBeenCalled(); + }); + + it('should set listOfFiles on init', (done) => { + component.listOfFiles.subscribe((files) => { + expect(files).toEqual([]); + done(); + }); + }); }); diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.ts b/src/app/item-page/simple/field-components/preview-section/preview-section.component.ts index f7cf45a6413..a515c30306b 100644 --- a/src/app/item-page/simple/field-components/preview-section/preview-section.component.ts +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.ts @@ -1,67 +1,30 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; +import { MetadataBitstream } from 'src/app/core/metadata/metadata-bitstream.model'; import { RegistryService } from 'src/app/core/registry/registry.service'; +import { Item } from 'src/app/core/shared/item.model'; +import { getAllSucceededRemoteListPayload } from 'src/app/core/shared/operators'; @Component({ selector: 'ds-preview-section', templateUrl: './preview-section.component.html', - styleUrls: ['./preview-section.component.scss'] + styleUrls: ['./preview-section.component.scss'], }) export class PreviewSectionComponent implements OnInit { + @Input() item: Item; - file = { - previewImageUrl: - 'https://lindat.mff.cuni.cz/repository/xmlui/themes/UFAL/images/mime/application-x-gzip.png', // replace with your image URL - name: 'ud-treebanks-v2.12.tgz', - size: '497.82 MB', - format: 'application/x-gzip', - description: 'Treebank data', - md5: 'afb7546d9591a82f372686bcc100db52', - }; - - fileList: any[] = []; // Modified - - isPreviewVisible = false; + listOfFiles: BehaviorSubject = new BehaviorSubject< + MetadataBitstream[] + >([] as any); constructor(protected registryService: RegistryService) {} // Modified ngOnInit(): void { this.registryService .getMetadataBitstream('123456789/36', 'ORIGINAL,TEXT,THUMBNAIL') - .subscribe( - (remoteData: any) => { - console.log('Received data:', remoteData); - // if ( - // remoteData && - // remoteData._embedded && - // remoteData._embedded.metadatabitstreams - // ) { - // this.fileList = this.parseFiles( - // remoteData._embedded.metadatabitstreams[0].fileInfo - // ); - // } - }, - (error: any) => { - console.log('Received error:', error); - } - ); + .pipe(getAllSucceededRemoteListPayload()) + .subscribe((data: MetadataBitstream[]) => { + this.listOfFiles.next(data); + }); } - - // togglePreview() { - // this.isPreviewVisible = !this.isPreviewVisible; - // } - - // parseFiles(files: any[]): any[] { - // let parsedFiles: any[] = []; - // for (let file of files) { - // let parsedFile: any = {}; - // parsedFile.name = file.name; - // parsedFile.size = file.size; - // parsedFile.isDirectory = file.isDirectory; - // if (file.isDirectory && file.sub) { - // parsedFile.sub = this.parseFiles(Object.values(file.sub)); - // } - // parsedFiles.push(parsedFile); - // } - // return parsedFiles; - // } } diff --git a/src/app/item-page/simple/item-page.component.html b/src/app/item-page/simple/item-page.component.html index 44ebca5cc0a..a819e3f91c2 100644 --- a/src/app/item-page/simple/item-page.component.html +++ b/src/app/item-page/simple/item-page.component.html @@ -11,7 +11,7 @@ - + diff --git a/src/app/item-page/simple/item-types/shared/item-relationships-utils.ts b/src/app/item-page/simple/item-types/shared/item-relationships-utils.ts index b4c3da2cdc3..33a97493358 100644 --- a/src/app/item-page/simple/item-types/shared/item-relationships-utils.ts +++ b/src/app/item-page/simple/item-types/shared/item-relationships-utils.ts @@ -1,4 +1,8 @@ -import { combineLatest as observableCombineLatest, Observable, zip as observableZip } from 'rxjs'; +import { + combineLatest as observableCombineLatest, + Observable, + zip as observableZip, +} from 'rxjs'; import { distinctUntilChanged, map, mergeMap, switchMap } from 'rxjs/operators'; import { PaginatedList } from '../../../../core/data/paginated-list.model'; import { RemoteData } from '../../../../core/data/remote-data'; @@ -6,14 +10,20 @@ import { Relationship } from '../../../../core/shared/item-relationships/relatio import { Item } from '../../../../core/shared/item.model'; import { getFirstSucceededRemoteDataPayload, - getFirstSucceededRemoteData + getFirstSucceededRemoteData, } from '../../../../core/shared/operators'; import { hasValue } from '../../../../shared/empty.util'; import { InjectionToken } from '@angular/core'; -export const PAGINATED_RELATIONS_TO_ITEMS_OPERATOR = new InjectionToken<(thisId: string) => (source: Observable>>) => Observable>>>('paginatedRelationsToItems', { +export const PAGINATED_RELATIONS_TO_ITEMS_OPERATOR = new InjectionToken< + ( + thisId: string + ) => ( + source: Observable>> + ) => Observable>> +>('paginatedRelationsToItems', { providedIn: 'root', - factory: () => paginatedRelationsToItems + factory: () => paginatedRelationsToItems, }); /** @@ -23,42 +33,51 @@ export const PAGINATED_RELATIONS_TO_ITEMS_OPERATOR = new InjectionToken<(thisId: * For example: "(o) => o.id" will compare the two arrays by comparing their content by id. * @param mapFn Function for mapping the arrays */ -export const compareArraysUsing = (mapFn: (t: T) => any) => +export const compareArraysUsing = + (mapFn: (t: T) => any) => (a: T[], b: T[]): boolean => { - if (!Array.isArray(a) || ! Array.isArray(b)) { + if (!Array.isArray(a) || !Array.isArray(b)) { return false; } const aIds = a.map(mapFn); const bIds = b.map(mapFn); - return aIds.length === bIds.length && + return ( + aIds.length === bIds.length && aIds.every((e) => bIds.includes(e)) && - bIds.every((e) => aIds.includes(e)); + bIds.every((e) => aIds.includes(e)) + ); }; /** * Operator for comparing arrays using the object's ids */ export const compareArraysUsingIds = () => - compareArraysUsing((t: T) => hasValue(t) ? t.id : undefined); + compareArraysUsing((t: T) => (hasValue(t) ? t.id : undefined)); /** * Operator for turning a list of relationships into a list of the relevant items * @param {string} thisId The item's id of which the relations belong to * @returns {(source: Observable) => Observable} */ -export const relationsToItems = (thisId: string) => +export const relationsToItems = + (thisId: string) => (source: Observable): Observable => source.pipe( mergeMap((rels: Relationship[]) => observableZip( - ...rels.map((rel: Relationship) => observableCombineLatest(rel.leftItem, rel.rightItem)) + ...rels.map((rel: Relationship) => + observableCombineLatest(rel.leftItem, rel.rightItem) + ) ) ), map((arr) => arr - .filter(([leftItem, rightItem]) => leftItem.hasSucceeded && rightItem.hasSucceeded) + .filter( + ([leftItem, rightItem]) => + leftItem.hasSucceeded && rightItem.hasSucceeded + ) .map(([leftItem, rightItem]) => { if (leftItem.payload.id === thisId) { return rightItem.payload; @@ -68,7 +87,7 @@ export const relationsToItems = (thisId: string) => }) .filter((item: Item) => hasValue(item)) ), - distinctUntilChanged(compareArraysUsingIds()), + distinctUntilChanged(compareArraysUsingIds()) ); /** @@ -77,8 +96,11 @@ export const relationsToItems = (thisId: string) => * @param {string} thisId The item's id of which the relations belong to * @returns {(source: Observable) => Observable} */ -export const paginatedRelationsToItems = (thisId: string) => - (source: Observable>>): Observable>> => +export const paginatedRelationsToItems = + (thisId: string) => + ( + source: Observable>> + ): Observable>> => source.pipe( getFirstSucceededRemoteData(), switchMap((relationshipsRD: RemoteData>) => { @@ -86,9 +108,10 @@ export const paginatedRelationsToItems = (thisId: string) => relationshipsRD.payload.page.map((rel: Relationship) => observableCombineLatest([ rel.leftItem.pipe(getFirstSucceededRemoteDataPayload()), - rel.rightItem.pipe(getFirstSucceededRemoteDataPayload())] - ) - )).pipe( + rel.rightItem.pipe(getFirstSucceededRemoteDataPayload()), + ]) + ) + ).pipe( map((arr) => arr .map(([leftItem, rightItem]) => { @@ -102,7 +125,11 @@ export const paginatedRelationsToItems = (thisId: string) => ), distinctUntilChanged(compareArraysUsingIds()), map((relatedItems: Item[]) => - Object.assign(relationshipsRD, { payload: Object.assign(relationshipsRD.payload, { page: relatedItems } )}) + Object.assign(relationshipsRD, { + payload: Object.assign(relationshipsRD.payload, { + page: relatedItems, + }), + }) ) ); }) From e3df2d3bfb537ba88adbb5b57cae956ed62b0f40 Mon Sep 17 00:00:00 2001 From: HuynhKhoa1601 Date: Mon, 17 Jul 2023 16:52:35 +0700 Subject: [PATCH 04/26] fix the lint error and fix the collapse/hide behaviour --- .../builders/remote-data-build.service.ts | 233 +++++++++++++----- .../data/metadata-bitstream-data.service.ts | 56 ++--- src/app/core/metadata/file-info.model.ts | 9 + .../core/metadata/metadata-bitstream.model.ts | 30 ++- .../file-tree-view.component.html | 4 +- 5 files changed, 218 insertions(+), 114 deletions(-) create mode 100644 src/app/core/metadata/file-info.model.ts diff --git a/src/app/core/cache/builders/remote-data-build.service.ts b/src/app/core/cache/builders/remote-data-build.service.ts index 72acde8df9b..f8bb6ecba0e 100644 --- a/src/app/core/cache/builders/remote-data-build.service.ts +++ b/src/app/core/cache/builders/remote-data-build.service.ts @@ -3,22 +3,39 @@ import { combineLatest as observableCombineLatest, Observable, of as observableOf, - race as observableRace + race as observableRace, } from 'rxjs'; -import { map, switchMap, filter, distinctUntilKeyChanged } from 'rxjs/operators'; -import { hasValue, isEmpty, isNotEmpty, hasNoValue, isUndefined } from '../../../shared/empty.util'; +import { + map, + switchMap, + filter, + distinctUntilKeyChanged, +} from 'rxjs/operators'; +import { + hasValue, + isEmpty, + isNotEmpty, + hasNoValue, + isUndefined, +} from '../../../shared/empty.util'; import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; -import { FollowLinkConfig, followLink } from '../../../shared/utils/follow-link-config.model'; +import { + FollowLinkConfig, + followLink, +} from '../../../shared/utils/follow-link-config.model'; import { PaginatedList } from '../../data/paginated-list.model'; import { RemoteData } from '../../data/remote-data'; import { RequestEntry, ResponseState, RequestEntryState, - hasSucceeded + hasSucceeded, } from '../../data/request.reducer'; import { RequestService } from '../../data/request.service'; -import { getRequestFromRequestHref, getRequestFromRequestUUID } from '../../shared/operators'; +import { + getRequestFromRequestHref, + getRequestFromRequestUUID, +} from '../../shared/operators'; import { ObjectCacheService } from '../object-cache.service'; import { LinkService } from './link.service'; import { HALLink } from '../../shared/hal-link.model'; @@ -31,10 +48,11 @@ import { getResourceTypeValueFor } from '../object-cache.reducer'; @Injectable() export class RemoteDataBuildService { - constructor(protected objectCache: ObjectCacheService, - protected linkService: LinkService, - protected requestService: RequestService) { - } + constructor( + protected objectCache: ObjectCacheService, + protected linkService: LinkService, + protected requestService: RequestService + ) {} /** * Creates an Observable with the payload for a RemoteData object @@ -48,21 +66,36 @@ export class RemoteDataBuildService { * should be automatically resolved * @private */ - private buildPayload(requestEntry$: Observable, href$?: Observable, ...linksToFollow: FollowLinkConfig[]): Observable { + private buildPayload( + requestEntry$: Observable, + href$?: Observable, + ...linksToFollow: FollowLinkConfig[] + ): Observable { if (hasNoValue(href$)) { href$ = observableOf(undefined); } return observableCombineLatest([href$, requestEntry$]).pipe( switchMap(([href, entry]: [string, RequestEntry]) => { - const hasExactMatchInObjectCache = this.hasExactMatchInObjectCache(href, entry); - if (hasValue(entry.response) && - (hasExactMatchInObjectCache || this.isCacheablePayload(entry) || this.isUnCacheablePayload(entry))) { + const hasExactMatchInObjectCache = this.hasExactMatchInObjectCache( + href, + entry + ); + if ( + hasValue(entry.response) && + (hasExactMatchInObjectCache || + this.isCacheablePayload(entry) || + this.isUnCacheablePayload(entry)) + ) { if (hasExactMatchInObjectCache) { return this.objectCache.getObjectByHref(href); } else if (this.isCacheablePayload(entry)) { - return this.objectCache.getObjectByHref(entry.response.payloadLink.href); + return this.objectCache.getObjectByHref( + entry.response.payloadLink.href + ); } else { - return [this.plainObjectToInstance(entry.response.unCacheableObject)]; + return [ + this.plainObjectToInstance(entry.response.unCacheableObject), + ]; } } else if (hasSucceeded(entry.state)) { return [null]; @@ -72,7 +105,9 @@ export class RemoteDataBuildService { }), switchMap((obj: T) => { if (hasValue(obj)) { - if (getResourceTypeValueFor((obj as any).type) === PAGINATED_LIST.value) { + if ( + getResourceTypeValueFor((obj as any).type) === PAGINATED_LIST.value + ) { return this.buildPaginatedList(obj, ...linksToFollow); } else if (isNotEmpty(linksToFollow)) { return [this.linkService.resolveLinks(obj, ...linksToFollow)]; @@ -109,9 +144,17 @@ export class RemoteDataBuildService { * @param entry the request entry the object has to match * @private */ - private hasExactMatchInObjectCache(href: string, entry: RequestEntry): boolean { - return hasValue(entry) && hasValue(entry.request) && isNotEmpty(entry.request.uuid) && - hasValue(href) && this.objectCache.hasByHref(href, entry.request.uuid); + private hasExactMatchInObjectCache( + href: string, + entry: RequestEntry + ): boolean { + return ( + hasValue(entry) && + hasValue(entry.request) && + isNotEmpty(entry.request.uuid) && + hasValue(href) && + this.objectCache.hasByHref(href, entry.request.uuid) + ); } /** @@ -120,7 +163,10 @@ export class RemoteDataBuildService { * @private */ private isCacheablePayload(entry: RequestEntry): boolean { - return hasValue(entry.response.payloadLink) && isNotEmpty(entry.response.payloadLink.href); + return ( + hasValue(entry.response.payloadLink) && + isNotEmpty(entry.response.payloadLink.href) + ); } /** @@ -140,26 +186,40 @@ export class RemoteDataBuildService { * @param object A plain object to be turned in to a {@link PaginatedList} * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved */ - private buildPaginatedList(object: any, ...linksToFollow: FollowLinkConfig[]): Observable { - const pageLink = linksToFollow.find((linkToFollow: FollowLinkConfig) => linkToFollow.name === 'page'); - const otherLinks = linksToFollow.filter((linkToFollow: FollowLinkConfig) => linkToFollow.name !== 'page'); + private buildPaginatedList( + object: any, + ...linksToFollow: FollowLinkConfig[] + ): Observable { + const pageLink = linksToFollow.find( + (linkToFollow: FollowLinkConfig) => linkToFollow.name === 'page' + ); + const otherLinks = linksToFollow.filter( + (linkToFollow: FollowLinkConfig) => linkToFollow.name !== 'page' + ); const paginatedList = Object.assign(new PaginatedList(), object); if (hasValue(pageLink)) { if (isEmpty(paginatedList.page)) { - const pageSelfLinks = paginatedList._links.page.map((link: HALLink) => link.href); - return this.objectCache.getList(pageSelfLinks).pipe(map((page: any[]) => { - paginatedList.page = page - .map((obj: any) => this.plainObjectToInstance(obj)) - .map((obj: any) => - this.linkService.resolveLinks(obj, ...pageLink.linksToFollow) - ); - if (isNotEmpty(otherLinks)) { - return this.linkService.resolveLinks(paginatedList, ...otherLinks); - } - return paginatedList; - })); + const pageSelfLinks = paginatedList._links.page.map( + (link: HALLink) => link.href + ); + return this.objectCache.getList(pageSelfLinks).pipe( + map((page: any[]) => { + paginatedList.page = page + .map((obj: any) => this.plainObjectToInstance(obj)) + .map((obj: any) => + this.linkService.resolveLinks(obj, ...pageLink.linksToFollow) + ); + if (isNotEmpty(otherLinks)) { + return this.linkService.resolveLinks( + paginatedList, + ...otherLinks + ); + } + return paginatedList; + }) + ); } else { // in case the elements of the paginated list were already filled in, because they're UnCacheableObjects paginatedList.page = paginatedList.page @@ -168,7 +228,9 @@ export class RemoteDataBuildService { this.linkService.resolveLinks(obj, ...pageLink.linksToFollow) ); if (isNotEmpty(otherLinks)) { - return observableOf(this.linkService.resolveLinks(paginatedList, ...otherLinks)); + return observableOf( + this.linkService.resolveLinks(paginatedList, ...otherLinks) + ); } } } @@ -181,13 +243,22 @@ export class RemoteDataBuildService { * @param requestUUID$ The UUID of the request we want to retrieve * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved */ - buildFromRequestUUID(requestUUID$: string | Observable, ...linksToFollow: FollowLinkConfig[]): Observable> { + buildFromRequestUUID( + requestUUID$: string | Observable, + ...linksToFollow: FollowLinkConfig[] + ): Observable> { if (typeof requestUUID$ === 'string') { requestUUID$ = observableOf(requestUUID$); } - const requestEntry$ = requestUUID$.pipe(getRequestFromRequestUUID(this.requestService)); + const requestEntry$ = requestUUID$.pipe( + getRequestFromRequestUUID(this.requestService) + ); - const payload$ = this.buildPayload(requestEntry$, undefined, ...linksToFollow); + const payload$ = this.buildPayload( + requestEntry$, + undefined, + ...linksToFollow + ); return this.toRemoteDataObservable(requestEntry$, payload$); } @@ -198,7 +269,10 @@ export class RemoteDataBuildService { * @param href$ self link of object we want to retrieve * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved */ - buildFromHref(href$: string | Observable, ...linksToFollow: FollowLinkConfig[]): Observable> { + buildFromHref( + href$: string | Observable, + ...linksToFollow: FollowLinkConfig[] + ): Observable> { if (typeof href$ === 'string') { href$ = observableOf(href$); } @@ -207,18 +281,21 @@ export class RemoteDataBuildService { const requestUUID$ = href$.pipe( switchMap((href: string) => - this.objectCache.getRequestUUIDBySelfLink(href)), + this.objectCache.getRequestUUIDBySelfLink(href) + ) ); const requestEntry$ = observableRace( href$.pipe(getRequestFromRequestHref(this.requestService)), - requestUUID$.pipe(getRequestFromRequestUUID(this.requestService)), - ).pipe( - distinctUntilKeyChanged('lastUpdated') + requestUUID$.pipe(getRequestFromRequestUUID(this.requestService)) + ).pipe(distinctUntilKeyChanged('lastUpdated')); + + const payload$ = this.buildPayload( + requestEntry$, + href$, + ...linksToFollow ); - const payload$ = this.buildPayload(requestEntry$, href$, ...linksToFollow); - return this.toRemoteDataObservable(requestEntry$, payload$); } @@ -228,19 +305,23 @@ export class RemoteDataBuildService { * @param href$ Observable href of object we want to retrieve * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved */ - buildSingle(href$: string | Observable, ...linksToFollow: FollowLinkConfig[]): Observable> { + buildSingle( + href$: string | Observable, + ...linksToFollow: FollowLinkConfig[] + ): Observable> { return this.buildFromHref(href$, ...linksToFollow); } - toRemoteDataObservable(requestEntry$: Observable, payload$: Observable) { - return observableCombineLatest([ - requestEntry$, - payload$ - ]).pipe( - filter(([entry,payload]: [RequestEntry, T]) => - hasValue(entry) && - // filter out cases where the state is successful, but the payload isn't yet set - !(hasSucceeded(entry.state) && isUndefined(payload)) + toRemoteDataObservable( + requestEntry$: Observable, + payload$: Observable + ) { + return observableCombineLatest([requestEntry$, payload$]).pipe( + filter( + ([entry, payload]: [RequestEntry, T]) => + hasValue(entry) && + // filter out cases where the state is successful, but the payload isn't yet set + !(hasSucceeded(entry.state) && isUndefined(payload)) ), map(([entry, payload]: [RequestEntry, T]) => { let response = entry.response; @@ -270,8 +351,14 @@ export class RemoteDataBuildService { * @param href$ Observable href of objects we want to retrieve * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved */ - buildList(href$: string | Observable, ...linksToFollow: FollowLinkConfig[]): Observable>> { - return this.buildFromHref>(href$, followLink('page', { shouldEmbed: false }, ...linksToFollow)); + buildList( + href$: string | Observable, + ...linksToFollow: FollowLinkConfig[] + ): Observable>> { + return this.buildFromHref>( + href$, + followLink('page', { shouldEmbed: false }, ...linksToFollow) + ); } /** @@ -284,8 +371,9 @@ export class RemoteDataBuildService { * * @param input the array of RemoteData observables to start from */ - aggregate(input: Observable>[]): Observable> { - + aggregate( + input: Observable>[] + ): Observable> { if (isEmpty(input)) { return createSuccessfulRemoteDataObject$([], new Date().getTime()); } @@ -294,15 +382,21 @@ export class RemoteDataBuildService { map((arr) => { const timeCompleted = arr .map((d: RemoteData) => d.timeCompleted) - .reduce((max: number, current: number) => current > max ? current : max); + .reduce((max: number, current: number) => + current > max ? current : max + ); const msToLive = arr .map((d: RemoteData) => d.msToLive) - .reduce((min: number, current: number) => current < min ? current : min); + .reduce((min: number, current: number) => + current < min ? current : min + ); const lastUpdated = arr .map((d: RemoteData) => d.lastUpdated) - .reduce((max: number, current: number) => current > max ? current : max); + .reduce((max: number, current: number) => + current > max ? current : max + ); let state: RequestEntryState; if (arr.some((d: RemoteData) => d.isRequestPending)) { @@ -325,11 +419,13 @@ export class RemoteDataBuildService { if (hasValue(e)) { return `[${idx}]: ${e}`; } - }).filter((e: string) => hasValue(e)) + }) + .filter((e: string) => hasValue(e)) .join(', '); - const statusCodes = new Set(arr - .map((d: RemoteData) => d.statusCode)); + const statusCodes = new Set( + arr.map((d: RemoteData) => d.statusCode) + ); let statusCode: number; @@ -350,6 +446,7 @@ export class RemoteDataBuildService { payload, statusCode ); - })); + }) + ); } } diff --git a/src/app/core/data/metadata-bitstream-data.service.ts b/src/app/core/data/metadata-bitstream-data.service.ts index 4d51f3f05d9..7e583eb99bf 100644 --- a/src/app/core/data/metadata-bitstream-data.service.ts +++ b/src/app/core/data/metadata-bitstream-data.service.ts @@ -39,54 +39,44 @@ export class MetadataBitstreamDataService extends DataService protected rdbService: RemoteDataBuildService, protected objectCache: ObjectCacheService, protected halService: HALEndpointService, - protected notificationsService: NotificationsService, + protected notificationsService: NotificationsService ) { super(); } - /** * Find metadata fields with either the partial metadata field name (e.g. "dc.ti") as query or an exact match to * at least the schema, element or qualifier - * @param schema optional; an exact match of the prefix of the metadata schema (e.g. "dc", "dcterms", "eperson") - * @param element optional; an exact match of the field's element (e.g. "contributor", "title") - * @param qualifier optional; an exact match of the field's qualifier (e.g. "author", "alternative") - * @param query optional (if any of schema, element or qualifier used) - part of the fully qualified field, - * should start with the start of the schema, element or qualifier (e.g. “dc.ti”, “contributor”, “auth”, “contributor.ot”) - * @param exactName optional; the exact fully qualified field, should use the syntax schema.element.qualifier or - * schema.element if no qualifier exists (e.g. "dc.title", "dc.contributor.author"). It will only return one value - * if there's an exact match + * @param handle optional; an exact match of the prefix of the item identifier (e.g. "123456789/1126") + * @param fileGrpType optional; an exact match of the type of the file(e.g. "TEXT", "THUMBNAIL") * @param options The options info used to retrieve the fields * @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's no valid cached version. Defaults to true * @param reRequestOnStale Whether or not the request should automatically be re-requested after the response becomes stale * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved */ - searchByHandleParams(handle: string, fileGrpType: string, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable> { + searchByHandleParams( + handle: string, + fileGrpType: string, + options: FindListOptions = {}, + useCachedVersionIfAvailable = true, + reRequestOnStale = true, + ...linksToFollow: FollowLinkConfig[] + ): Observable> { const optionParams = Object.assign(new FindListOptions(), options, { searchParams: [ new RequestParam('handle', hasValue(handle) ? handle : ''), - new RequestParam('fileGrpType', hasValue(fileGrpType) ? fileGrpType : ''), + new RequestParam( + 'fileGrpType', + hasValue(fileGrpType) ? fileGrpType : '' + ), ], }); - return this.searchBy(this.searchByHandleLinkPath, optionParams, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + return this.searchBy( + this.searchByHandleLinkPath, + optionParams, + useCachedVersionIfAvailable, + reRequestOnStale, + ...linksToFollow + ); } - - // /** - // * Make a new FindListRequest with given search method - // * - // * @param searchMethod The search method for the object - // * @param options The [[FindListOptions]] object - // * @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's - // * no valid cached version. Defaults to true - // * @param reRequestOnStale Whether or not the request should automatically be re- - // * requested after the response becomes stale - // * @param linksToFollow List of {@link FollowLinkConfig} that indicate which - // * {@link HALLink}s should be automatically resolved - // * @return {Observable>} - // * Return an observable that emits response from the server - // */ - // public searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig[]): Observable>> { - // return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); - // } - -} \ No newline at end of file +} diff --git a/src/app/core/metadata/file-info.model.ts b/src/app/core/metadata/file-info.model.ts new file mode 100644 index 00000000000..cdcccd5c97b --- /dev/null +++ b/src/app/core/metadata/file-info.model.ts @@ -0,0 +1,9 @@ +import { autoserialize, autoserializeAs } from 'cerialize'; + +export class FileInfo { + @autoserialize name: string; + @autoserialize content: any; + @autoserialize size: string; + @autoserialize isDirectory: boolean; + @autoserializeAs('sub') sub: { [key: string]: FileInfo }; +} diff --git a/src/app/core/metadata/metadata-bitstream.model.ts b/src/app/core/metadata/metadata-bitstream.model.ts index de51e91dad6..eb6c2d0c011 100644 --- a/src/app/core/metadata/metadata-bitstream.model.ts +++ b/src/app/core/metadata/metadata-bitstream.model.ts @@ -1,4 +1,9 @@ -import { autoserialize, autoserializeAs, deserialize, deserializeAs } from 'cerialize'; +import { + autoserialize, + autoserializeAs, + deserialize, + deserializeAs, +} from 'cerialize'; import { ListableObject } from '../../shared/object-collection/shared/listable-object.model'; import { typedObject } from '../cache/builders/build-decorators'; import { GenericConstructor } from '../shared/generic-constructor'; @@ -7,17 +12,18 @@ import { HALResource } from '../shared/hal-resource.model'; import { ResourceType } from '../shared/resource-type'; import { excludeFromEquals } from '../utilities/equals.decorators'; import { METADATA_BITSTREAM } from './metadata-bitstream.resource-type'; +import { FileInfo } from './file-info.model'; /** * Class the represents a File */ -export class FileInfo { - @autoserialize name: string; - @autoserialize content: any; - @autoserialize size: string; - @autoserialize isDirectory: boolean; - @autoserializeAs('sub') sub: {[key: string]: FileInfo}; -} +// export class FileInfo { +// @autoserialize name: string; +// @autoserialize content: any; +// @autoserialize size: string; +// @autoserialize isDirectory: boolean; +// @autoserializeAs('sub') sub: { [key: string]: FileInfo }; +// } /** * Class that represents a MetadataBitstream @@ -91,11 +97,13 @@ export class MetadataBitstream extends ListableObject implements HALResource { */ @deserialize _links: { - self: HALLink, - schema: HALLink + self: HALLink; + schema: HALLink; }; getRenderTypes(): (string | GenericConstructor)[] { return [this.constructor as GenericConstructor]; } -} \ No newline at end of file +} +export { FileInfo }; + diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.html b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.html index b61251030b7..6644016bb99 100644 --- a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.html +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.html @@ -1,5 +1,5 @@
  • - + {{ node.name }} @@ -12,7 +12,7 @@
      From 060bf5130b4e004b4accccff9725380e572ce12e Mon Sep 17 00:00:00 2001 From: HuynhKhoa1601 Date: Tue, 18 Jul 2023 18:33:20 +0700 Subject: [PATCH 05/26] add UI for download buttons and fix UI for the ZIP Preview --- .../file-description.component.scss | 7 ++ .../item-page/simple/item-page.component.html | 74 ++++++++++++++++--- .../item-page/simple/item-page.component.scss | 55 ++++++++++++++ .../item-page/simple/item-page.component.ts | 10 +++ 4 files changed, 137 insertions(+), 9 deletions(-) diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.scss b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.scss index 2336ee20794..a561b7b903d 100644 --- a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.scss +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.scss @@ -48,6 +48,9 @@ } .button-container { + a { + text-decoration: none; + } .download-btn, .preview-btn { display: inline; padding: .2em .6em .3em; @@ -63,6 +66,10 @@ cursor: pointer; background-color: #5bc0de; } + + .download-btn:hover, .preview-btn:hover { + background-color: #31b0d5; + } } .panel { diff --git a/src/app/item-page/simple/item-page.component.html b/src/app/item-page/simple/item-page.component.html index a819e3f91c2..06e06b9180d 100644 --- a/src/app/item-page/simple/item-page.component.html +++ b/src/app/item-page/simple/item-page.component.html @@ -1,19 +1,75 @@ -
      -
      -
      +
      +
      +
      - - - + + +

       Files in this item

      +  Download instructions for command line +
      + +
      +curl --remote-name-all https://lindat.mff.cuni.cz/repository/xmlui/bitstream/handle/11234/1-5150{{
      +            "{"
      +          }}/ud-treebanks-v2.12.tgz,/ud-documentation-v2.12.tgz,/ud-tools-v2.12.tgz{{
      +            "}"
      +          }}
      +
      + +  Download all files in item (598.92 MB) +
      - - + +
      diff --git a/src/app/item-page/simple/item-page.component.scss b/src/app/item-page/simple/item-page.component.scss index f28ce613865..d86eec4771f 100644 --- a/src/app/item-page/simple/item-page.component.scss +++ b/src/app/item-page/simple/item-page.component.scss @@ -27,3 +27,58 @@ .clarin-cut-top-1 { margin-top: -16px; } + +.btn-download{ + color: #fff !important; + background-color: #428bca; + border-color: #357ebd; + cursor: pointer; +} + +.btn-download:hover { + color: #fff; + background-color: #3276b1; + border-color: #285e8e; +} + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.428571429; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; + white-space: pre-wrap; +} + +#command-div .repo-copy-btn { + opacity: 0; + -webkit-transition: opacity .3s ease-in-out; + -o-transition: opacity .3s ease-in-out; + transition: opacity .3s ease-in-out; +} + +.repo-copy-btn { + width: 20px; + height: 20px; + position: relative; + display: inline-block; + padding: 0 !important; +} + +.repo-copy-btn:before { + content: " "; + background-image: url('https://lindat.mff.cuni.cz/repository/xmlui/themes/UFAL/images/clippy.svg'); + background-size: 13px 15px; + background-repeat: no-repeat; + background-color: red; + display: inline-block; + width: 13px; + height: 15px; + padding: 0 !important; +} diff --git a/src/app/item-page/simple/item-page.component.ts b/src/app/item-page/simple/item-page.component.ts index 41f4b945822..82a4279aed6 100644 --- a/src/app/item-page/simple/item-page.component.ts +++ b/src/app/item-page/simple/item-page.component.ts @@ -66,6 +66,11 @@ export class ItemPageComponent implements OnInit { */ withdrawnTombstone = false; + /** + * If download by command button is click, the command line will be shown + */ + isCommandLineVisible = false + constructor( protected route: ActivatedRoute, private router: Router, @@ -124,4 +129,9 @@ export class ItemPageComponent implements OnInit { } }); } + + setCommandline() { + console.log('Hello'); + this.isCommandLineVisible = !this.isCommandLineVisible; + } } From a537c0523a280a2ae8a745a3d6ebf3a4028654d4 Mon Sep 17 00:00:00 2001 From: HuynhKhoa1601 Date: Wed, 19 Jul 2023 19:20:05 +0700 Subject: [PATCH 06/26] getting data from backend and make the download feature --- .../full/full-item-page.component.ts | 4 +- .../file-description.component.html | 1 + .../file-description.component.ts | 7 +++- .../item-page/simple/item-page.component.html | 10 +---- .../item-page/simple/item-page.component.ts | 41 +++++++++++++++++-- 5 files changed, 50 insertions(+), 13 deletions(-) diff --git a/src/app/item-page/full/full-item-page.component.ts b/src/app/item-page/full/full-item-page.component.ts index 369769c77d1..c549b3678f4 100644 --- a/src/app/item-page/full/full-item-page.component.ts +++ b/src/app/item-page/full/full-item-page.component.ts @@ -16,6 +16,7 @@ import { hasValue } from '../../shared/empty.util'; import { AuthService } from '../../core/auth/auth.service'; import { Location } from '@angular/common'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; +import { RegistryService } from 'src/app/core/registry/registry.service'; /** @@ -48,8 +49,9 @@ export class FullItemPageComponent extends ItemPageComponent implements OnInit, items: ItemDataService, authService: AuthService, authorizationService: AuthorizationDataService, + protected registryService: RegistryService, private _location: Location) { - super(route, router, items, authService, authorizationService); + super(route, router, items, authService, authorizationService, registryService); } /*** AoT inheritance fix, will hopefully be resolved in the near future **/ diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html index 8a5cd15c580..54cd8e9c1f5 100644 --- a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html @@ -41,6 +41,7 @@
       Download file diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts index 68145d2fff4..be3cf3b6a17 100644 --- a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts @@ -11,6 +11,11 @@ export class FileDescriptionComponent implements OnInit { fileInput: MetadataBitstream; ngOnInit(): void { - console.log(this.fileInput); + console.log('fileInput', this.fileInput); + } + + public downloadFiles() { + //window.location.href = `http://localhost:8080${this.fileInput}` + window.location.href = 'http://localhost:8080/server/bitstream/handle/123456789/1128/Folder1.zip?sequence=1&isAllowed=y'; } } diff --git a/src/app/item-page/simple/item-page.component.html b/src/app/item-page/simple/item-page.component.html index 06e06b9180d..0f89155c885 100644 --- a/src/app/item-page/simple/item-page.component.html +++ b/src/app/item-page/simple/item-page.component.html @@ -38,20 +38,14 @@

       Files in this item

      class="repo-copy-btn pull-right" data-clipboard-target="#command-div" > --> -
      -curl --remote-name-all https://lindat.mff.cuni.cz/repository/xmlui/bitstream/handle/11234/1-5150{{
      -            "{"
      -          }}/ud-treebanks-v2.12.tgz,/ud-documentation-v2.12.tgz,/ud-tools-v2.12.tgz{{
      -            "}"
      -          }}
      {{command}}
       ; + /** + * handle of the specific item + */ + itemHandle: string; + /** + * handle of the specific item + */ + fileName: string; + command: string; /** * Whether the current user is an admin or not @@ -70,6 +81,9 @@ export class ItemPageComponent implements OnInit { * If download by command button is click, the command line will be shown */ isCommandLineVisible = false + listOfFiles: any; + + constructor( protected route: ActivatedRoute, @@ -77,6 +91,7 @@ export class ItemPageComponent implements OnInit { private items: ItemDataService, private authService: AuthService, private authorizationService: AuthorizationDataService, + protected registryService: RegistryService ) { } /** @@ -93,6 +108,14 @@ export class ItemPageComponent implements OnInit { ); this.showTombstone(); + + this.registryService +.getMetadataBitstream(this.itemHandle, 'ORIGINAL,TEXT,THUMBNAIL') + .pipe(getAllSucceededRemoteListPayload()) + .subscribe((data: MetadataBitstream[]) => { + this.listOfFiles = data; + this.generateCurlCommand(); + }); } showTombstone() { @@ -106,6 +129,7 @@ export class ItemPageComponent implements OnInit { take(1), getAllSucceededRemoteDataPayload()) .subscribe((item: Item) => { + this.itemHandle = item.handle; isWithdrawn = item.isWithdrawn; isReplaced = item.metadata['dc.relation.isreplacedby']?.[0]?.value; }); @@ -131,7 +155,18 @@ export class ItemPageComponent implements OnInit { } setCommandline() { - console.log('Hello'); this.isCommandLineVisible = !this.isCommandLineVisible; } + + generateCurlCommand() { + let fileNames = this.listOfFiles + .filter((file: MetadataBitstream) => file.format === 'application/octet-stream' || file.format === 'application/pdf') + .map((file: MetadataBitstream) => file.name); + + this.command =`curl --remote-name-all http://localhost:8080/server/bitstream/handle/${this.itemHandle}/{${fileNames.join(',')}}`; + } + + downloadFiles() { + window.location.href = `http://localhost:8080/server/bitstream/allzip?handleId=${this.itemHandle}`; + } } From bafb92b138684203a3b6ef549d484d332ef40430 Mon Sep 17 00:00:00 2001 From: HuynhKhoa1601 Date: Fri, 21 Jul 2023 19:15:28 +0700 Subject: [PATCH 07/26] handle with the dynamic input --- .../file-description/file-description.component.html | 2 +- .../file-description/file-description.component.ts | 3 +-- .../preview-section/preview-section.component.ts | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html index 54cd8e9c1f5..7e7a9c22523 100644 --- a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html @@ -79,7 +79,7 @@
    • + + {{ node.name }} @@ -12,7 +15,8 @@
        diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.scss b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.scss index 1aaef2bf84c..53ef730cabb 100644 --- a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.scss +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.scss @@ -20,4 +20,12 @@ .pull-right { float: right !important; +} + +.foldername a { + cursor: pointer; +} + +.foldername a:hover { + text-decoration: underline; } \ No newline at end of file diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts index 4471ebb25b7..71f6553f9dd 100644 --- a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, OnInit } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { FileInfo } from 'src/app/core/metadata/metadata-bitstream.model'; @Component({ @@ -6,15 +6,13 @@ import { FileInfo } from 'src/app/core/metadata/metadata-bitstream.model'; templateUrl: './file-tree-view.component.html', styleUrls: ['./file-tree-view.component.scss'], }) -export class FileTreeViewComponent implements OnInit { +export class FileTreeViewComponent { @Input() node: FileInfo; + isCollapsed = false; // add this line + getKeys(obj: any): string[] { return Object.keys(obj); } - - ngOnInit(): void { - console.log(this.node); - } } diff --git a/src/app/item-page/simple/item-page.component.html b/src/app/item-page/simple/item-page.component.html index 0f89155c885..d5a19e9382f 100644 --- a/src/app/item-page/simple/item-page.component.html +++ b/src/app/item-page/simple/item-page.component.html @@ -49,7 +49,7 @@

         Files in this item

        style="visibility: visible" >  Download all files in item (598.92 MB)Download all files in item ({{totalFileSizes}}) ; - /** - * handle of the specific item + /** + * handle of the specific item */ itemHandle: string; - /** - * handle of the specific item + /** + * handle of the specific item */ fileName: string; + /** + * command for the download command feature + */ command: string; /** @@ -80,10 +87,15 @@ export class ItemPageComponent implements OnInit { /** * If download by command button is click, the command line will be shown */ - isCommandLineVisible = false - listOfFiles: any; - - + isCommandLineVisible = false; + /** + * list of files uploaded by users to this item + */ + listOfFiles: MetadataBitstream[]; + /** + * total size of list of files uploaded by users to this item + */ + totalFileSizes: string; constructor( protected route: ActivatedRoute, @@ -92,7 +104,7 @@ export class ItemPageComponent implements OnInit { private authService: AuthService, private authorizationService: AuthorizationDataService, protected registryService: RegistryService - ) { } + ) {} /** * Initialize instance variables @@ -110,14 +122,43 @@ export class ItemPageComponent implements OnInit { this.showTombstone(); this.registryService -.getMetadataBitstream(this.itemHandle, 'ORIGINAL,TEXT,THUMBNAIL') + .getMetadataBitstream(this.itemHandle, 'ORIGINAL,TEXT,THUMBNAIL') .pipe(getAllSucceededRemoteListPayload()) .subscribe((data: MetadataBitstream[]) => { this.listOfFiles = data; this.generateCurlCommand(); + this.sumFileSizes(); }); } + sumFileSizes() { + const sizeUnits = { + B: 1, + KB: 1000, + MB: 1000 * 1000, + GB: 1000 * 1000 * 1000, + TB: 1000 * 1000 * 1000 * 1000, + }; + + let totalBytes = this.listOfFiles.reduce((total, file) => { + const [valueStr, unit] = file.fileSize.split(' '); + const value = parseFloat(valueStr); + const bytes = value * sizeUnits[unit.toUpperCase()]; + return total + bytes; + }, 0); + + let finalUnit = 'B'; + for (const unit of ['KB', 'MB', 'GB', 'TB']) { + if (totalBytes < 1000) { + break; + } + totalBytes /= 1000; + finalUnit = unit; + } + + this.totalFileSizes = totalBytes.toFixed(2) + ' ' + finalUnit; + } + showTombstone() { // if the item is withdrawn let isWithdrawn = false; @@ -125,9 +166,8 @@ export class ItemPageComponent implements OnInit { let isReplaced = ''; // load values from item - this.itemRD$.pipe( - take(1), - getAllSucceededRemoteDataPayload()) + this.itemRD$ + .pipe(take(1), getAllSucceededRemoteDataPayload()) .subscribe((item: Item) => { this.itemHandle = item.handle; isWithdrawn = item.isWithdrawn; @@ -141,8 +181,10 @@ export class ItemPageComponent implements OnInit { // for users navigate to the custom tombstone // for admin stay on the item page with tombstone flag - this.isAdmin$ = this.authorizationService.isAuthorized(FeatureID.AdministratorOf); - this.isAdmin$.subscribe(isAdmin => { + this.isAdmin$ = this.authorizationService.isAuthorized( + FeatureID.AdministratorOf + ); + this.isAdmin$.subscribe((isAdmin) => { // do not show tombstone for admin but show it for users if (!isAdmin) { if (isNotEmpty(isReplaced)) { @@ -159,14 +201,16 @@ export class ItemPageComponent implements OnInit { } generateCurlCommand() { - let fileNames = this.listOfFiles - .filter((file: MetadataBitstream) => file.format === 'application/octet-stream' || file.format === 'application/pdf') - .map((file: MetadataBitstream) => file.name); + let fileNames = this.listOfFiles.map( + (file: MetadataBitstream) => file.name + ); - this.command =`curl --remote-name-all http://localhost:8080/server/bitstream/handle/${this.itemHandle}/{${fileNames.join(',')}}`; + this.command = `curl --remote-name-all ${BASE_LOCAL_URL}/server/bitstream/handle/${ + this.itemHandle + }/{${fileNames.join(',')}}`; } downloadFiles() { - window.location.href = `http://localhost:8080/server/bitstream/allzip?handleId=${this.itemHandle}`; + window.location.href = `${BASE_LOCAL_URL}/server/bitstream/allzip?handleId=${this.itemHandle}`; } } From 52a07b232ab71c2419f0e47266cc076d0cbcba81 Mon Sep 17 00:00:00 2001 From: HuynhKhoa1601 Date: Wed, 26 Jul 2023 16:12:25 +0700 Subject: [PATCH 09/26] add more conditions for checking permission to preview and download files --- .../file-description.component.html | 45 ++++++++++++------- .../file-tree-view.component.ts | 2 +- .../item-page/simple/item-page.component.html | 16 ++++--- .../item-page/simple/item-page.component.ts | 12 ++++- 4 files changed, 52 insertions(+), 23 deletions(-) diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html index 6ff0cf9d8b4..0fb29830901 100644 --- a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html @@ -1,9 +1,12 @@
        -
        +
        + + Your browser does not support the video tag. +
        @@ -32,26 +35,27 @@
        Preview
        - +  Download file @@ -59,7 +63,7 @@
        @@ -72,7 +76,7 @@ class="pull-right collapsed" data-toggle="collapse" role="button" - href="#file_file_{{fileInput.id}}" + href="#file_file_{{ fileInput.id }}" >   @@ -80,13 +84,22 @@
          - + -
          {{fileInput.fileInfo[0].content}}
          +
          {{ fileInput.fileInfo[0].content }}
          -
        diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts index 71f6553f9dd..96129517885 100644 --- a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts @@ -10,7 +10,7 @@ export class FileTreeViewComponent { @Input() node: FileInfo; - isCollapsed = false; // add this line + isCollapsed = false; getKeys(obj: any): string[] { return Object.keys(obj); diff --git a/src/app/item-page/simple/item-page.component.html b/src/app/item-page/simple/item-page.component.html index d5a19e9382f..65fc101db43 100644 --- a/src/app/item-page/simple/item-page.component.html +++ b/src/app/item-page/simple/item-page.component.html @@ -29,7 +29,11 @@ [displayActions]="false" >

         Files in this item

        -  Download instructions for command line @@ -38,18 +42,20 @@

         Files in this item

        class="repo-copy-btn pull-right" data-clipboard-target="#command-div" > --> -
        {{command}}
        +
        {{
        +          command
        +        }}
         Download all files in item ({{totalFileSizes}})Download all files in item ({{ totalFileSizes }}) file.name + (file: MetadataBitstream) => { + if (!file.canPreview) { + this.canDownloadAllFiles = file.canPreview; + } + + return file.name; + } ); this.command = `curl --remote-name-all ${BASE_LOCAL_URL}/server/bitstream/handle/${ From 9ddbb6ee822c3970c0294441501048ca9a91742e Mon Sep 17 00:00:00 2001 From: HuynhKhoa1601 Date: Wed, 26 Jul 2023 18:12:41 +0700 Subject: [PATCH 10/26] fix lint error --- .../core/registry/registry.service.spec.ts | 227 ++++++++++++------ .../full/full-item-page.component.spec.ts | 6 +- .../file-description.component.ts | 4 +- .../preview-section.component.spec.ts | 4 + .../simple/item-page.component.spec.ts | 45 ++-- .../item-page/simple/item-page.component.ts | 14 +- 6 files changed, 190 insertions(+), 110 deletions(-) diff --git a/src/app/core/registry/registry.service.spec.ts b/src/app/core/registry/registry.service.spec.ts index 199f43e98e2..b3b5adc1515 100644 --- a/src/app/core/registry/registry.service.spec.ts +++ b/src/app/core/registry/registry.service.spec.ts @@ -3,7 +3,7 @@ import { Component } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { Store, StoreModule } from '@ngrx/store'; import { TranslateModule } from '@ngx-translate/core'; -import { Observable, of as observableOf } from 'rxjs'; +import { Observable, of as observableOf, of } from 'rxjs'; import { MetadataRegistryCancelFieldAction, MetadataRegistryCancelSchemaAction, @@ -14,7 +14,7 @@ import { MetadataRegistryEditFieldAction, MetadataRegistryEditSchemaAction, MetadataRegistrySelectFieldAction, - MetadataRegistrySelectSchemaAction + MetadataRegistrySelectSchemaAction, } from '../../admin/admin-registries/metadata-registry/metadata-registry.actions'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { StoreMock } from '../../shared/testing/store.mock'; @@ -26,20 +26,24 @@ import { storeModuleConfig } from '../../app.reducer'; import { FindListOptions } from '../data/request.models'; import { MetadataSchemaDataService } from '../data/metadata-schema-data.service'; import { MetadataFieldDataService } from '../data/metadata-field-data.service'; -import { createNoContentRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; +import { + createNoContentRemoteDataObject$, + createSuccessfulRemoteDataObject$, +} from '../../shared/remote-data.utils'; import { createPaginatedList } from '../../shared/testing/utils.test'; import { RemoteData } from '../data/remote-data'; import { NoContent } from '../shared/NoContent.model'; +import { MetadataBitstreamDataService } from '../data/metadata-bitstream-data.service'; @Component({ template: '' }) -class DummyComponent { -} +class DummyComponent {} describe('RegistryService', () => { let registryService: RegistryService; let mockStore; let metadataSchemaService: MetadataSchemaDataService; let metadataFieldService: MetadataFieldDataService; + let metadataBitstreamDataService: MetadataBitstreamDataService; let options: FindListOptions; let mockSchemasList: MetadataSchema[]; @@ -48,113 +52,144 @@ describe('RegistryService', () => { function init() { options = Object.assign(new FindListOptions(), { currentPage: 1, - elementsPerPage: 20 + elementsPerPage: 20, }); mockSchemasList = [ Object.assign(new MetadataSchema(), { id: 1, _links: { - self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/1' } + self: { + href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/1', + }, }, prefix: 'dc', namespace: 'http://dublincore.org/documents/dcmi-terms/', - type: MetadataSchema.type + type: MetadataSchema.type, }), Object.assign(new MetadataSchema(), { id: 2, _links: { - self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/2' } + self: { + href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/2', + }, }, prefix: 'mock', namespace: 'http://dspace.org/mockschema', - type: MetadataSchema.type - }) + type: MetadataSchema.type, + }), ]; mockFieldsList = [ - Object.assign(new MetadataField(), - { - id: 1, - _links: { - self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/8' } + Object.assign(new MetadataField(), { + id: 1, + _links: { + self: { + href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/8', }, - element: 'contributor', - qualifier: 'advisor', - scopeNote: null, - schema: createSuccessfulRemoteDataObject$(mockSchemasList[0]), - type: MetadataField.type - }), - Object.assign(new MetadataField(), - { - id: 2, - _links: { - self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/9' } + }, + element: 'contributor', + qualifier: 'advisor', + scopeNote: null, + schema: createSuccessfulRemoteDataObject$(mockSchemasList[0]), + type: MetadataField.type, + }), + Object.assign(new MetadataField(), { + id: 2, + _links: { + self: { + href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/9', }, - element: 'contributor', - qualifier: 'author', - scopeNote: null, - schema: createSuccessfulRemoteDataObject$(mockSchemasList[0]), - type: MetadataField.type - }), - Object.assign(new MetadataField(), - { - id: 3, - _links: { - self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/10' } + }, + element: 'contributor', + qualifier: 'author', + scopeNote: null, + schema: createSuccessfulRemoteDataObject$(mockSchemasList[0]), + type: MetadataField.type, + }), + Object.assign(new MetadataField(), { + id: 3, + _links: { + self: { + href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/10', }, - element: 'contributor', - qualifier: 'editor', - scopeNote: 'test scope note', - schema: createSuccessfulRemoteDataObject$(mockSchemasList[1]), - type: MetadataField.type - }), - Object.assign(new MetadataField(), - { - id: 4, - _links: { - self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/11' } + }, + element: 'contributor', + qualifier: 'editor', + scopeNote: 'test scope note', + schema: createSuccessfulRemoteDataObject$(mockSchemasList[1]), + type: MetadataField.type, + }), + Object.assign(new MetadataField(), { + id: 4, + _links: { + self: { + href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/11', }, - element: 'contributor', - qualifier: 'illustrator', - scopeNote: null, - schema: createSuccessfulRemoteDataObject$(mockSchemasList[1]), - type: MetadataField.type - }) + }, + element: 'contributor', + qualifier: 'illustrator', + scopeNote: null, + schema: createSuccessfulRemoteDataObject$(mockSchemasList[1]), + type: MetadataField.type, + }), ]; metadataSchemaService = jasmine.createSpyObj('metadataSchemaService', { - findAll: createSuccessfulRemoteDataObject$(createPaginatedList(mockSchemasList)), + findAll: createSuccessfulRemoteDataObject$( + createPaginatedList(mockSchemasList) + ), findById: createSuccessfulRemoteDataObject$(mockSchemasList[0]), - createOrUpdateMetadataSchema: createSuccessfulRemoteDataObject$(mockSchemasList[0]), + createOrUpdateMetadataSchema: createSuccessfulRemoteDataObject$( + mockSchemasList[0] + ), delete: createNoContentRemoteDataObject$(), - clearRequests: observableOf('href') + clearRequests: observableOf('href'), }); metadataFieldService = jasmine.createSpyObj('metadataFieldService', { - findAll: createSuccessfulRemoteDataObject$(createPaginatedList(mockFieldsList)), + findAll: createSuccessfulRemoteDataObject$( + createPaginatedList(mockFieldsList) + ), findById: createSuccessfulRemoteDataObject$(mockFieldsList[0]), create: createSuccessfulRemoteDataObject$(mockFieldsList[0]), put: createSuccessfulRemoteDataObject$(mockFieldsList[0]), delete: createNoContentRemoteDataObject$(), - clearRequests: observableOf('href') + clearRequests: observableOf('href'), }); + metadataBitstreamDataService = jasmine.createSpyObj( + 'metadataBitstreamDataService', + { + searchByHandleParams: of({ + /* Your Mock Data */ + }), + } + ); } beforeEach(() => { init(); TestBed.configureTestingModule({ - imports: [CommonModule, StoreModule.forRoot({}, storeModuleConfig), TranslateModule.forRoot()], - declarations: [ - DummyComponent + imports: [ + CommonModule, + StoreModule.forRoot({}, storeModuleConfig), + TranslateModule.forRoot(), ], + declarations: [DummyComponent], providers: [ { provide: Store, useClass: StoreMock }, - { provide: NotificationsService, useValue: new NotificationsServiceStub() }, + { + provide: NotificationsService, + useValue: new NotificationsServiceStub(), + }, { provide: MetadataSchemaDataService, useValue: metadataSchemaService }, { provide: MetadataFieldDataService, useValue: metadataFieldService }, - RegistryService - ] + { + provide: MetadataBitstreamDataService, + useValue: metadataBitstreamDataService, + }, + RegistryService, + ], }); registryService = TestBed.inject(RegistryService); mockStore = TestBed.inject(Store); @@ -179,12 +214,18 @@ describe('RegistryService', () => { let result; beforeEach(() => { - result = registryService.getMetadataSchemaByPrefix(mockSchemasList[0].prefix); + result = registryService.getMetadataSchemaByPrefix( + mockSchemasList[0].prefix + ); }); it('should call metadataSchemaService.findById with the correct ID', (done) => { result.subscribe(() => { - expect(metadataSchemaService.findById).toHaveBeenCalledWith(`${mockSchemasList[0].id}`, true, true); + expect(metadataSchemaService.findById).toHaveBeenCalledWith( + `${mockSchemasList[0].id}`, + true, + true + ); done(); }); }); @@ -201,7 +242,9 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryEditSchemaAction with the correct schema', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryEditSchemaAction(mockSchemasList[0])); + expect(mockStore.dispatch).toHaveBeenCalledWith( + new MetadataRegistryEditSchemaAction(mockSchemasList[0]) + ); }); }); @@ -211,7 +254,9 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryCancelSchemaAction', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryCancelSchemaAction()); + expect(mockStore.dispatch).toHaveBeenCalledWith( + new MetadataRegistryCancelSchemaAction() + ); }); }); @@ -221,7 +266,9 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistrySelectSchemaAction with the correct schema', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistrySelectSchemaAction(mockSchemasList[0])); + expect(mockStore.dispatch).toHaveBeenCalledWith( + new MetadataRegistrySelectSchemaAction(mockSchemasList[0]) + ); }); }); @@ -231,7 +278,9 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryDeselectSchemaAction with the correct schema', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryDeselectSchemaAction(mockSchemasList[0])); + expect(mockStore.dispatch).toHaveBeenCalledWith( + new MetadataRegistryDeselectSchemaAction(mockSchemasList[0]) + ); }); }); @@ -241,7 +290,9 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryDeselectAllSchemaAction', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryDeselectAllSchemaAction()); + expect(mockStore.dispatch).toHaveBeenCalledWith( + new MetadataRegistryDeselectAllSchemaAction() + ); }); }); @@ -251,7 +302,9 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryEditFieldAction with the correct Field', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryEditFieldAction(mockFieldsList[0])); + expect(mockStore.dispatch).toHaveBeenCalledWith( + new MetadataRegistryEditFieldAction(mockFieldsList[0]) + ); }); }); @@ -261,7 +314,9 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryCancelFieldAction', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryCancelFieldAction()); + expect(mockStore.dispatch).toHaveBeenCalledWith( + new MetadataRegistryCancelFieldAction() + ); }); }); @@ -271,7 +326,9 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistrySelectFieldAction with the correct Field', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistrySelectFieldAction(mockFieldsList[0])); + expect(mockStore.dispatch).toHaveBeenCalledWith( + new MetadataRegistrySelectFieldAction(mockFieldsList[0]) + ); }); }); @@ -281,7 +338,9 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryDeselectFieldAction with the correct Field', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryDeselectFieldAction(mockFieldsList[0])); + expect(mockStore.dispatch).toHaveBeenCalledWith( + new MetadataRegistryDeselectFieldAction(mockFieldsList[0]) + ); }); }); @@ -291,7 +350,9 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryDeselectAllFieldAction', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryDeselectAllFieldAction()); + expect(mockStore.dispatch).toHaveBeenCalledWith( + new MetadataRegistryDeselectAllFieldAction() + ); }); }); }); @@ -315,7 +376,10 @@ describe('RegistryService', () => { let result: Observable; beforeEach(() => { - result = registryService.createMetadataField(mockFieldsList[0], mockSchemasList[0]); + result = registryService.createMetadataField( + mockFieldsList[0], + mockSchemasList[0] + ); }); it('should return the created metadata field', (done) => { @@ -333,7 +397,10 @@ describe('RegistryService', () => { beforeEach(() => { metadataField = mockFieldsList[0]; metadataField.qualifier = ''; - result = registryService.createMetadataField(metadataField, mockSchemasList[0]); + result = registryService.createMetadataField( + metadataField, + mockSchemasList[0] + ); }); it('should return the created metadata field with a null qualifier', (done) => { diff --git a/src/app/item-page/full/full-item-page.component.spec.ts b/src/app/item-page/full/full-item-page.component.spec.ts index 41236d04767..c25b2f8e6e5 100644 --- a/src/app/item-page/full/full-item-page.component.spec.ts +++ b/src/app/item-page/full/full-item-page.component.spec.ts @@ -18,6 +18,7 @@ import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } f import { AuthService } from '../../core/auth/auth.service'; import { createPaginatedList } from '../../shared/testing/utils.test'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; +import { RegistryService } from 'src/app/core/registry/registry.service'; const mockItem: Item = Object.assign(new Item(), { bundles: createSuccessfulRemoteDataObject$(createPaginatedList([])), @@ -41,14 +42,13 @@ const metadataServiceStub = { describe('FullItemPageComponent', () => { let comp: FullItemPageComponent; let fixture: ComponentFixture; + let registryService: RegistryService; let authService: AuthService; let routeStub: ActivatedRouteStub; let routeData; const authorizationService = jasmine.createSpyObj('authorizationService', ['isAuthorized']); - - beforeEach(waitForAsync(() => { authService = jasmine.createSpyObj('authService', { isAuthenticated: observableOf(true), @@ -77,6 +77,7 @@ describe('FullItemPageComponent', () => { { provide: MetadataService, useValue: metadataServiceStub }, { provide: AuthService, useValue: authService }, { provide: AuthorizationDataService, useValue: authorizationService }, + RegistryService ], schemas: [NO_ERRORS_SCHEMA] @@ -86,6 +87,7 @@ describe('FullItemPageComponent', () => { })); beforeEach(waitForAsync(() => { + registryService = TestBed.inject(RegistryService); fixture = TestBed.createComponent(FullItemPageComponent); comp = fixture.componentInstance; fixture.detectChanges(); diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts index ebf03e76ba2..b893b1f4346 100644 --- a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts @@ -10,9 +10,9 @@ import { BASE_LOCAL_URL } from 'src/app/core/shared/clarin/constants'; export class FileDescriptionComponent implements OnInit { @Input() fileInput: MetadataBitstream; - + ngOnInit(): void { - console.log(this.fileInput); + console.log(this.fileInput); } public downloadFiles() { window.location.href = `${BASE_LOCAL_URL}${this.fileInput.href}`; diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts b/src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts index e88b994e9f0..8258c340d86 100644 --- a/src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts @@ -6,6 +6,7 @@ import { RegistryService } from 'src/app/core/registry/registry.service'; import { PreviewSectionComponent } from './preview-section.component'; import { ResourceType } from 'src/app/core/shared/resource-type'; import { HALLink } from 'src/app/core/shared/hal-link.model'; +import { Item } from 'src/app/core/shared/item.model'; describe('PreviewSectionComponent', () => { let component: PreviewSectionComponent; @@ -51,6 +52,9 @@ describe('PreviewSectionComponent', () => { of(bitstreamStream) ); + component.item = new Item(); + component.item.handle = '12345'; + fixture.detectChanges(); }); diff --git a/src/app/item-page/simple/item-page.component.spec.ts b/src/app/item-page/simple/item-page.component.spec.ts index 387bddf1736..1d8cbd3645a 100644 --- a/src/app/item-page/simple/item-page.component.spec.ts +++ b/src/app/item-page/simple/item-page.component.spec.ts @@ -17,47 +17,53 @@ import { createFailedRemoteDataObject$, createPendingRemoteDataObject$, createSuccessfulRemoteDataObject, - createSuccessfulRemoteDataObject$ + createSuccessfulRemoteDataObject$, } from '../../shared/remote-data.utils'; import { AuthService } from '../../core/auth/auth.service'; import { createPaginatedList } from '../../shared/testing/utils.test'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; +import { RegistryService } from 'src/app/core/registry/registry.service'; const mockItem: Item = Object.assign(new Item(), { bundles: createSuccessfulRemoteDataObject$(createPaginatedList([])), metadata: [], - relationships: createRelationshipsObservable() + relationships: createRelationshipsObservable(), }); describe('ItemPageComponent', () => { let comp: ItemPageComponent; let fixture: ComponentFixture; let authService: AuthService; - const authorizationService = jasmine.createSpyObj('authorizationService', ['isAuthorized']); + let registryService: RegistryService; + const authorizationService = jasmine.createSpyObj('authorizationService', [ + 'isAuthorized', + ]); const mockMetadataService = { /* tslint:disable:no-empty */ - processRemoteData: () => { - } + processRemoteData: () => {}, /* tslint:enable:no-empty */ }; const mockRoute = Object.assign(new ActivatedRouteStub(), { - data: observableOf({ dso: createSuccessfulRemoteDataObject(mockItem) }) + data: observableOf({ dso: createSuccessfulRemoteDataObject(mockItem) }), }); beforeEach(waitForAsync(() => { authService = jasmine.createSpyObj('authService', { isAuthenticated: observableOf(true), - setRedirectUrl: {} + setRedirectUrl: {}, }); TestBed.configureTestingModule({ - imports: [TranslateModule.forRoot({ - loader: { - provide: TranslateLoader, - useClass: TranslateLoaderMock - } - }), BrowserAnimationsModule], + imports: [ + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock, + }, + }), + BrowserAnimationsModule, + ], declarations: [ItemPageComponent, VarDirective], providers: [ { provide: ActivatedRoute, useValue: mockRoute }, @@ -66,15 +72,19 @@ describe('ItemPageComponent', () => { { provide: Router, useValue: {} }, { provide: AuthService, useValue: authService }, { provide: AuthorizationDataService, useValue: authorizationService }, + RegistryService, ], - schemas: [NO_ERRORS_SCHEMA] - }).overrideComponent(ItemPageComponent, { - set: { changeDetection: ChangeDetectionStrategy.Default } - }).compileComponents(); + schemas: [NO_ERRORS_SCHEMA], + }) + .overrideComponent(ItemPageComponent, { + set: { changeDetection: ChangeDetectionStrategy.Default }, + }) + .compileComponents(); })); beforeEach(waitForAsync(() => { + registryService = TestBed.inject(RegistryService); fixture = TestBed.createComponent(ItemPageComponent); comp = fixture.componentInstance; fixture.detectChanges(); @@ -104,5 +114,4 @@ describe('ItemPageComponent', () => { expect(error.nativeElement).toBeDefined(); }); }); - }); diff --git a/src/app/item-page/simple/item-page.component.ts b/src/app/item-page/simple/item-page.component.ts index 9c71ead33b9..96871ae48e0 100644 --- a/src/app/item-page/simple/item-page.component.ts +++ b/src/app/item-page/simple/item-page.component.ts @@ -205,15 +205,13 @@ export class ItemPageComponent implements OnInit { } generateCurlCommand() { - let fileNames = this.listOfFiles.map( - (file: MetadataBitstream) => { - if (!file.canPreview) { - this.canDownloadAllFiles = file.canPreview; - } - - return file.name; + const fileNames = this.listOfFiles.map((file: MetadataBitstream) => { + if (!file.canPreview) { + this.canDownloadAllFiles = file.canPreview; } - ); + + return file.name; + }); this.command = `curl --remote-name-all ${BASE_LOCAL_URL}/server/bitstream/handle/${ this.itemHandle From 395db4ecab3c6959e43d89437a6ab17da20d5c81 Mon Sep 17 00:00:00 2001 From: HuynhKhoa1601 Date: Thu, 27 Jul 2023 14:59:32 +0700 Subject: [PATCH 11/26] fix failed test --- .../full/full-item-page.component.spec.ts | 22 ++++++++++++++++--- .../simple/item-page.component.spec.ts | 22 +++++++++++++++++-- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/app/item-page/full/full-item-page.component.spec.ts b/src/app/item-page/full/full-item-page.component.spec.ts index c25b2f8e6e5..5b695607b7c 100644 --- a/src/app/item-page/full/full-item-page.component.spec.ts +++ b/src/app/item-page/full/full-item-page.component.spec.ts @@ -1,6 +1,6 @@ import { ComponentFixture, fakeAsync, TestBed, waitForAsync } from '@angular/core/testing'; import { ItemDataService } from '../../core/data/item-data.service'; -import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core'; import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { TruncatePipe } from '../../shared/utils/truncate.pipe'; @@ -11,7 +11,7 @@ import { ActivatedRouteStub } from '../../shared/testing/active-router.stub'; import { VarDirective } from '../../shared/utils/var.directive'; import { RouterTestingModule } from '@angular/router/testing'; import { Item } from '../../core/shared/item.model'; -import { of as observableOf } from 'rxjs'; +import { of as observableOf, of } from 'rxjs'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { By } from '@angular/platform-browser'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; @@ -19,6 +19,12 @@ import { AuthService } from '../../core/auth/auth.service'; import { createPaginatedList } from '../../shared/testing/utils.test'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { RegistryService } from 'src/app/core/registry/registry.service'; +import { Store } from '@ngrx/store'; +import { NotificationsService } from 'src/app/shared/notifications/notifications.service'; +import { MetadataFieldDataService } from 'src/app/core/data/metadata-field-data.service'; +import { MetadataSchemaDataService } from 'src/app/core/data/metadata-schema-data.service'; +import { MetadataBitstreamDataService } from 'src/app/core/data/metadata-bitstream-data.service'; +import { getMockTranslateService } from 'src/app/shared/mocks/translate.service.mock'; const mockItem: Item = Object.assign(new Item(), { bundles: createSuccessfulRemoteDataObject$(createPaginatedList([])), @@ -43,7 +49,7 @@ describe('FullItemPageComponent', () => { let comp: FullItemPageComponent; let fixture: ComponentFixture; let registryService: RegistryService; - + let translateService: TranslateService; let authService: AuthService; let routeStub: ActivatedRouteStub; let routeData; @@ -63,6 +69,11 @@ describe('FullItemPageComponent', () => { data: observableOf(routeData) }); + const mockMetadataBitstreamDataService = { + searchByHandleParams: () => of({}) // Returns a mock Observable + }; + + translateService = getMockTranslateService(); TestBed.configureTestingModule({ imports: [TranslateModule.forRoot({ loader: { @@ -77,6 +88,11 @@ describe('FullItemPageComponent', () => { { provide: MetadataService, useValue: metadataServiceStub }, { provide: AuthService, useValue: authService }, { provide: AuthorizationDataService, useValue: authorizationService }, + { provide: MetadataBitstreamDataService, useValue: mockMetadataBitstreamDataService }, + { provide: Store, useValue: {} }, + { provide: NotificationsService, useValue: {} }, + { provide: MetadataSchemaDataService, useValue: {} }, + { provide: MetadataFieldDataService, useValue: {} }, RegistryService ], diff --git a/src/app/item-page/simple/item-page.component.spec.ts b/src/app/item-page/simple/item-page.component.spec.ts index 1d8cbd3645a..e266013a0dd 100644 --- a/src/app/item-page/simple/item-page.component.spec.ts +++ b/src/app/item-page/simple/item-page.component.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core'; import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; import { ItemDataService } from '../../core/data/item-data.service'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; @@ -12,7 +12,7 @@ import { Item } from '../../core/shared/item.model'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { By } from '@angular/platform-browser'; import { createRelationshipsObservable } from './item-types/shared/item.component.spec'; -import { of as observableOf } from 'rxjs'; +import { of as observableOf, of } from 'rxjs'; import { createFailedRemoteDataObject$, createPendingRemoteDataObject$, @@ -23,6 +23,12 @@ import { AuthService } from '../../core/auth/auth.service'; import { createPaginatedList } from '../../shared/testing/utils.test'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { RegistryService } from 'src/app/core/registry/registry.service'; +import { Store } from '@ngrx/store'; +import { NotificationsService } from 'src/app/shared/notifications/notifications.service'; +import { MetadataSchemaDataService } from 'src/app/core/data/metadata-schema-data.service'; +import { MetadataFieldDataService } from 'src/app/core/data/metadata-field-data.service'; +import { MetadataBitstreamDataService } from 'src/app/core/data/metadata-bitstream-data.service'; +import { getMockTranslateService } from 'src/app/shared/mocks/translate.service.mock'; const mockItem: Item = Object.assign(new Item(), { bundles: createSuccessfulRemoteDataObject$(createPaginatedList([])), @@ -34,6 +40,7 @@ describe('ItemPageComponent', () => { let comp: ItemPageComponent; let fixture: ComponentFixture; let authService: AuthService; + let translateService: TranslateService; let registryService: RegistryService; const authorizationService = jasmine.createSpyObj('authorizationService', [ 'isAuthorized', @@ -48,12 +55,18 @@ describe('ItemPageComponent', () => { data: observableOf({ dso: createSuccessfulRemoteDataObject(mockItem) }), }); + const mockMetadataBitstreamDataService = { + searchByHandleParams: () => of({}) // Returns a mock Observable + }; + beforeEach(waitForAsync(() => { authService = jasmine.createSpyObj('authService', { isAuthenticated: observableOf(true), setRedirectUrl: {}, }); + translateService = getMockTranslateService(); + TestBed.configureTestingModule({ imports: [ TranslateModule.forRoot({ @@ -72,6 +85,11 @@ describe('ItemPageComponent', () => { { provide: Router, useValue: {} }, { provide: AuthService, useValue: authService }, { provide: AuthorizationDataService, useValue: authorizationService }, + { provide: Store, useValue: {} }, + { provide: NotificationsService, useValue: {} }, + { provide: MetadataSchemaDataService, useValue: {} }, + { provide: MetadataFieldDataService, useValue: {} }, + { provide: MetadataBitstreamDataService, useValue: mockMetadataBitstreamDataService }, RegistryService, ], From a8683313d53facd59694da83b316c4bb446443fa Mon Sep 17 00:00:00 2001 From: milanmajchrak <90026355+milanmajchrak@users.noreply.github.com> Date: Wed, 27 Sep 2023 13:16:07 +0200 Subject: [PATCH 12/26] Lock/download preview (#311) * create new component and add model file and service file * build the user interface and calling the api from backend * add logic for handling data from BE and refactor the UI * fix the lint error and fix the collapse/hide behaviour --------- Co-authored-by: HuynhKhoa1601 --- angular.json | 1 + src/app/core/core.module.ts | 4 + src/app/core/data/data.service.ts | 0 .../data/metadata-bitstream-data.service.ts | 82 ++++++++ src/app/core/metadata/file-info.model.ts | 9 + .../core/metadata/metadata-bitstream.model.ts | 109 ++++++++++ .../metadata-bitstream.resource-type.ts | 10 + src/app/core/registry/registry.service.ts | 192 ++++++++++++++---- src/app/item-page/item-page.module.ts | 11 +- .../file-description.component.html | 91 +++++++++ .../file-description.component.scss | 106 ++++++++++ .../file-description.component.spec.ts | 52 +++++ .../file-description.component.ts | 16 ++ .../file-tree-view.component.html | 24 +++ .../file-tree-view.component.scss | 23 +++ .../file-tree-view.component.spec.ts | 55 +++++ .../file-tree-view.component.ts | 20 ++ .../preview-section.component.html | 3 + .../preview-section.component.scss | 107 ++++++++++ .../preview-section.component.spec.ts | 71 +++++++ .../preview-section.component.ts | 30 +++ .../item-page/simple/item-page.component.html | 1 + .../shared/item-relationships-utils.ts | 65 ++++-- .../untyped-item/untyped-item.component.html | 1 + 24 files changed, 1025 insertions(+), 58 deletions(-) create mode 100644 src/app/core/data/data.service.ts create mode 100644 src/app/core/data/metadata-bitstream-data.service.ts create mode 100644 src/app/core/metadata/file-info.model.ts create mode 100644 src/app/core/metadata/metadata-bitstream.model.ts create mode 100644 src/app/core/metadata/metadata-bitstream.resource-type.ts create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.scss create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.spec.ts create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.html create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.scss create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.spec.ts create mode 100644 src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts create mode 100644 src/app/item-page/simple/field-components/preview-section/preview-section.component.html create mode 100644 src/app/item-page/simple/field-components/preview-section/preview-section.component.scss create mode 100644 src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts create mode 100644 src/app/item-page/simple/field-components/preview-section/preview-section.component.ts diff --git a/angular.json b/angular.json index d828887b214..1afce4bb954 100644 --- a/angular.json +++ b/angular.json @@ -46,6 +46,7 @@ "styles": [ "src/styles/startup.scss", "src/aai/discojuice/discojuice.css", + "node_modules/font-awesome/css/font-awesome.css", "node_modules/bootstrap/dist/css/bootstrap.min.css", { "input": "src/styles/base-theme.scss", diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 175a3fd1609..306b950f8f4 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -64,6 +64,7 @@ import { EPerson } from './eperson/models/eperson.model'; import { Group } from './eperson/models/group.model'; import { JsonPatchOperationsBuilder } from './json-patch/builder/json-patch-operations-builder'; import { MetadataField } from './metadata/metadata-field.model'; +import { MetadataBitstream } from './metadata/metadata-bitstream.model'; import { MetadataSchema } from './metadata/metadata-schema.model'; import { MetadataService } from './metadata/metadata.service'; import { RegistryService } from './registry/registry.service'; @@ -133,6 +134,7 @@ import { import { Registration } from './shared/registration.model'; import { MetadataSchemaDataService } from './data/metadata-schema-data.service'; import { MetadataFieldDataService } from './data/metadata-field-data.service'; +import { MetadataBitstreamDataService } from './data/metadata-bitstream-data.service'; import { DsDynamicTypeBindRelationService } from '../shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service'; import { TokenResponseParsingService } from './auth/token-response-parsing.service'; import { SubmissionCcLicenseDataService } from './submission/submission-cc-license-data.service'; @@ -298,6 +300,7 @@ const PROVIDERS = [ SiteRegisterGuard, MetadataSchemaDataService, MetadataFieldDataService, + MetadataBitstreamDataService, TokenResponseParsingService, ReloadGuard, EndUserAgreementCurrentUserGuard, @@ -341,6 +344,7 @@ export const models = ResourcePolicy, MetadataSchema, MetadataField, + MetadataBitstream, License, WorkflowItem, WorkspaceItem, diff --git a/src/app/core/data/data.service.ts b/src/app/core/data/data.service.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/core/data/metadata-bitstream-data.service.ts b/src/app/core/data/metadata-bitstream-data.service.ts new file mode 100644 index 00000000000..7e583eb99bf --- /dev/null +++ b/src/app/core/data/metadata-bitstream-data.service.ts @@ -0,0 +1,82 @@ +import { Injectable } from '@angular/core'; +import { hasValue } from '../../shared/empty.util'; +import { PaginatedList } from './paginated-list.model'; +import { RemoteData } from './remote-data'; +import { RequestService } from './request.service'; +import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { HALEndpointService } from '../shared/hal-endpoint.service'; +import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { Observable } from 'rxjs'; +import { RequestParam } from '../cache/models/request-param.model'; +import { NoContent } from '../shared/NoContent.model'; +import { NotificationsService } from '../../shared/notifications/notifications.service'; +import { ObjectCacheService } from '../cache/object-cache.service'; +import { METADATA_BITSTREAM } from '../metadata/metadata-bitstream.resource-type'; +import { FindListOptions } from './request.models'; +import { dataService } from '../cache/builders/build-decorators'; +import { MetadataBitstream } from '../metadata/metadata-bitstream.model'; +import { DataService } from './data.service'; +import { HttpClient } from '@angular/common/http'; +import { Store } from '@ngrx/store'; +import { CoreState } from '../core.reducers'; +import { ChangeAnalyzer } from './change-analyzer'; +import { tap } from 'rxjs/operators'; + +/** + * A service responsible for fetching/sending data from/to the REST API on the metadatafields endpoint + */ +@Injectable() +@dataService(METADATA_BITSTREAM) +export class MetadataBitstreamDataService extends DataService { + protected store: Store; + protected http: HttpClient; + protected comparator: ChangeAnalyzer; + protected linkPath = 'metadatabitstreams'; + protected searchByHandleLinkPath = 'byHandle'; + + constructor( + protected requestService: RequestService, + protected rdbService: RemoteDataBuildService, + protected objectCache: ObjectCacheService, + protected halService: HALEndpointService, + protected notificationsService: NotificationsService + ) { + super(); + } + + /** + * Find metadata fields with either the partial metadata field name (e.g. "dc.ti") as query or an exact match to + * at least the schema, element or qualifier + * @param handle optional; an exact match of the prefix of the item identifier (e.g. "123456789/1126") + * @param fileGrpType optional; an exact match of the type of the file(e.g. "TEXT", "THUMBNAIL") + * @param options The options info used to retrieve the fields + * @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's no valid cached version. Defaults to true + * @param reRequestOnStale Whether or not the request should automatically be re-requested after the response becomes stale + * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved + */ + searchByHandleParams( + handle: string, + fileGrpType: string, + options: FindListOptions = {}, + useCachedVersionIfAvailable = true, + reRequestOnStale = true, + ...linksToFollow: FollowLinkConfig[] + ): Observable> { + const optionParams = Object.assign(new FindListOptions(), options, { + searchParams: [ + new RequestParam('handle', hasValue(handle) ? handle : ''), + new RequestParam( + 'fileGrpType', + hasValue(fileGrpType) ? fileGrpType : '' + ), + ], + }); + return this.searchBy( + this.searchByHandleLinkPath, + optionParams, + useCachedVersionIfAvailable, + reRequestOnStale, + ...linksToFollow + ); + } +} diff --git a/src/app/core/metadata/file-info.model.ts b/src/app/core/metadata/file-info.model.ts new file mode 100644 index 00000000000..cdcccd5c97b --- /dev/null +++ b/src/app/core/metadata/file-info.model.ts @@ -0,0 +1,9 @@ +import { autoserialize, autoserializeAs } from 'cerialize'; + +export class FileInfo { + @autoserialize name: string; + @autoserialize content: any; + @autoserialize size: string; + @autoserialize isDirectory: boolean; + @autoserializeAs('sub') sub: { [key: string]: FileInfo }; +} diff --git a/src/app/core/metadata/metadata-bitstream.model.ts b/src/app/core/metadata/metadata-bitstream.model.ts new file mode 100644 index 00000000000..eb6c2d0c011 --- /dev/null +++ b/src/app/core/metadata/metadata-bitstream.model.ts @@ -0,0 +1,109 @@ +import { + autoserialize, + autoserializeAs, + deserialize, + deserializeAs, +} from 'cerialize'; +import { ListableObject } from '../../shared/object-collection/shared/listable-object.model'; +import { typedObject } from '../cache/builders/build-decorators'; +import { GenericConstructor } from '../shared/generic-constructor'; +import { HALLink } from '../shared/hal-link.model'; +import { HALResource } from '../shared/hal-resource.model'; +import { ResourceType } from '../shared/resource-type'; +import { excludeFromEquals } from '../utilities/equals.decorators'; +import { METADATA_BITSTREAM } from './metadata-bitstream.resource-type'; +import { FileInfo } from './file-info.model'; + +/** + * Class the represents a File + */ +// export class FileInfo { +// @autoserialize name: string; +// @autoserialize content: any; +// @autoserialize size: string; +// @autoserialize isDirectory: boolean; +// @autoserializeAs('sub') sub: { [key: string]: FileInfo }; +// } + +/** + * Class that represents a MetadataBitstream + */ +@typedObject +export class MetadataBitstream extends ListableObject implements HALResource { + static type = METADATA_BITSTREAM; + + /** + * The object type + */ + @excludeFromEquals + @autoserialize + type: ResourceType; + + /** + * The identifier of this metadata field + */ + @autoserialize + id: number; + + /** + * The name of this bitstream + */ + @autoserialize + name: string; + + /** + * The description of this bitstream + */ + @autoserialize + description: string; + + /** + * The fileSize of this bitstream + */ + @autoserialize + fileSize: string; + + /** + * The checksum of this bitstream + */ + @autoserialize + checksum: string; + + /** + * The fileInfo of this bitstream + */ + @autoserializeAs(FileInfo, 'fileInfo') fileInfo: FileInfo[]; + + /** + * The format of this bitstream + */ + @autoserialize + format: string; + + /** + * The href of this bitstream + */ + @autoserialize + href: string; + + /** + * The canPreview of this bitstream + */ + @autoserialize + canPreview: boolean; + + /** + * The {@link HALLink}s for this MetadataField + */ + @deserialize + _links: { + self: HALLink; + schema: HALLink; + }; + + getRenderTypes(): (string | GenericConstructor)[] { + return [this.constructor as GenericConstructor]; + } +} +export { FileInfo }; + diff --git a/src/app/core/metadata/metadata-bitstream.resource-type.ts b/src/app/core/metadata/metadata-bitstream.resource-type.ts new file mode 100644 index 00000000000..f023a8c5259 --- /dev/null +++ b/src/app/core/metadata/metadata-bitstream.resource-type.ts @@ -0,0 +1,10 @@ +import { ResourceType } from '../shared/resource-type'; + +/** + * The resource type for MetadataBitstream + * + * Needs to be in a separate file to prevent circular + * dependencies in webpack. + */ + +export const METADATA_BITSTREAM = new ResourceType('metadatabitstream'); diff --git a/src/app/core/registry/registry.service.ts b/src/app/core/registry/registry.service.ts index 7a377405bd0..566533ae65e 100644 --- a/src/app/core/registry/registry.service.ts +++ b/src/app/core/registry/registry.service.ts @@ -17,7 +17,7 @@ import { MetadataRegistryEditFieldAction, MetadataRegistryEditSchemaAction, MetadataRegistrySelectFieldAction, - MetadataRegistrySelectSchemaAction + MetadataRegistrySelectSchemaAction, } from '../../admin/admin-registries/metadata-registry/metadata-registry.actions'; import { map, mergeMap, tap } from 'rxjs/operators'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -26,30 +26,45 @@ import { MetadataSchema } from '../metadata/metadata-schema.model'; import { MetadataField } from '../metadata/metadata-field.model'; import { MetadataSchemaDataService } from '../data/metadata-schema-data.service'; import { MetadataFieldDataService } from '../data/metadata-field-data.service'; +import { MetadataBitstreamDataService } from '../data/metadata-bitstream-data.service'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { RequestParam } from '../cache/models/request-param.model'; import { NoContent } from '../shared/NoContent.model'; import { FindListOptions } from '../data/find-list-options.model'; +import { MetadataBitstream } from '../metadata/metadata-bitstream.model'; -const metadataRegistryStateSelector = (state: AppState) => state.metadataRegistry; -const editMetadataSchemaSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editSchema); -const selectedMetadataSchemasSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.selectedSchemas); -const editMetadataFieldSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editField); -const selectedMetadataFieldsSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.selectedFields); +const metadataRegistryStateSelector = (state: AppState) => + state.metadataRegistry; +const editMetadataSchemaSelector = createSelector( + metadataRegistryStateSelector, + (metadataState: MetadataRegistryState) => metadataState.editSchema +); +const selectedMetadataSchemasSelector = createSelector( + metadataRegistryStateSelector, + (metadataState: MetadataRegistryState) => metadataState.selectedSchemas +); +const editMetadataFieldSelector = createSelector( + metadataRegistryStateSelector, + (metadataState: MetadataRegistryState) => metadataState.editField +); +const selectedMetadataFieldsSelector = createSelector( + metadataRegistryStateSelector, + (metadataState: MetadataRegistryState) => metadataState.selectedFields +); /** * Service for registry related CRUD actions such as metadata schema, metadata field and bitstream format */ @Injectable() export class RegistryService { - - constructor(private store: Store, - private notificationsService: NotificationsService, - private translateService: TranslateService, - private metadataSchemaService: MetadataSchemaDataService, - private metadataFieldService: MetadataFieldDataService) { - - } + constructor( + private store: Store, + private notificationsService: NotificationsService, + private translateService: TranslateService, + private metadataSchemaService: MetadataSchemaDataService, + private metadataFieldService: MetadataFieldDataService, + private metadataBitstreamDataService: MetadataBitstreamDataService + ) {} /** * Retrieves all metadata schemas @@ -61,8 +76,18 @@ export class RegistryService { * @param linksToFollow List of {@link FollowLinkConfig} that indicate which * {@link HALLink}s should be automatically resolved */ - public getMetadataSchemas(options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable>> { - return this.metadataSchemaService.findAll(options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + public getMetadataSchemas( + options: FindListOptions = {}, + useCachedVersionIfAvailable = true, + reRequestOnStale = true, + ...linksToFollow: FollowLinkConfig[] + ): Observable>> { + return this.metadataSchemaService.findAll( + options, + useCachedVersionIfAvailable, + reRequestOnStale, + ...linksToFollow + ); } /** @@ -75,17 +100,32 @@ export class RegistryService { * @param linksToFollow List of {@link FollowLinkConfig} that indicate which * {@link HALLink}s should be automatically resolved */ - public getMetadataSchemaByPrefix(prefix: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable> { + public getMetadataSchemaByPrefix( + prefix: string, + useCachedVersionIfAvailable = true, + reRequestOnStale = true, + ...linksToFollow: FollowLinkConfig[] + ): Observable> { // Temporary options to get ALL metadataschemas until there's a rest api endpoint for fetching a specific schema const options: FindListOptions = Object.assign(new FindListOptions(), { - elementsPerPage: 10000 + elementsPerPage: 10000, }); return this.getMetadataSchemas(options).pipe( getFirstSucceededRemoteDataPayload(), map((schemas: PaginatedList) => schemas.page), isNotEmptyOperator(), - map((schemas: MetadataSchema[]) => schemas.filter((schema) => schema.prefix === prefix)[0]), - mergeMap((schema: MetadataSchema) => this.metadataSchemaService.findById(`${schema.id}`, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow)) + map( + (schemas: MetadataSchema[]) => + schemas.filter((schema) => schema.prefix === prefix)[0] + ), + mergeMap((schema: MetadataSchema) => + this.metadataSchemaService.findById( + `${schema.id}`, + useCachedVersionIfAvailable, + reRequestOnStale, + ...linksToFollow + ) + ) ); } @@ -100,8 +140,49 @@ export class RegistryService { * @param linksToFollow List of {@link FollowLinkConfig} that indicate which * {@link HALLink}s should be automatically resolved */ - public getMetadataFieldsBySchema(schema: MetadataSchema, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable>> { - return this.metadataFieldService.findBySchema(schema, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + public getMetadataFieldsBySchema( + schema: MetadataSchema, + options: FindListOptions = {}, + useCachedVersionIfAvailable = true, + reRequestOnStale = true, + ...linksToFollow: FollowLinkConfig[] + ): Observable>> { + return this.metadataFieldService.findBySchema( + schema, + options, + useCachedVersionIfAvailable, + reRequestOnStale, + ...linksToFollow + ); + } + + /** + * retrieves all metadatabistream that belong to a certain metadata + * @param schema The schema to filter by + * @param options The options info used to retrieve the fields + * @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's + * no valid cached version. Defaults to true + * @param reRequestOnStale Whether or not the request should automatically be re- + * requested after the response becomes stale + * @param linksToFollow List of {@link FollowLinkConfig} that indicate which + * {@link HALLink}s should be automatically resolved + */ + public getMetadataBitstream( + handle: string, + fileGrpType: string, + options: FindListOptions = {}, + useCachedVersionIfAvailable = true, + reRequestOnStale = true, + ...linksToFollow: FollowLinkConfig[] + ): Observable> { + return this.metadataBitstreamDataService.searchByHandleParams( + handle, + fileGrpType, + options, + useCachedVersionIfAvailable, + reRequestOnStale, + ...linksToFollow + ); } public editMetadataSchema(schema: MetadataSchema) { @@ -212,13 +293,17 @@ export class RegistryService { * - On update, a PutRequest is used * @param schema The MetadataSchema to create or update */ - public createOrUpdateMetadataSchema(schema: MetadataSchema): Observable { + public createOrUpdateMetadataSchema( + schema: MetadataSchema + ): Observable { const isUpdate = hasValue(schema.id); return this.metadataSchemaService.createOrUpdateMetadataSchema(schema).pipe( getFirstSucceededRemoteDataPayload(), hasValueOperator(), tap(() => { - this.showNotifications(true, isUpdate, false, { prefix: schema.prefix }); + this.showNotifications(true, isUpdate, false, { + prefix: schema.prefix, + }); }) ); } @@ -244,17 +329,24 @@ export class RegistryService { * @param field The MetadataField to create * @param schema The MetadataSchema to create the field in */ - public createMetadataField(field: MetadataField, schema: MetadataSchema): Observable { + public createMetadataField( + field: MetadataField, + schema: MetadataSchema + ): Observable { if (!field.qualifier) { field.qualifier = null; } - return this.metadataFieldService.create(field, new RequestParam('schemaId', schema.id)).pipe( - getFirstSucceededRemoteDataPayload(), - hasValueOperator(), - tap(() => { - this.showNotifications(true, false, true, { field: field.toString() }); - }) - ); + return this.metadataFieldService + .create(field, new RequestParam('schemaId', schema.id)) + .pipe( + getFirstSucceededRemoteDataPayload(), + hasValueOperator(), + tap(() => { + this.showNotifications(true, false, true, { + field: field.toString(), + }); + }) + ); } /** @@ -290,13 +382,23 @@ export class RegistryService { this.metadataFieldService.clearRequests(); } - private showNotifications(success: boolean, edited: boolean, isField: boolean, options: any) { + private showNotifications( + success: boolean, + edited: boolean, + isField: boolean, + options: any + ) { const prefix = 'admin.registries.schema.notification'; const suffix = success ? 'success' : 'failure'; const editedString = edited ? 'edited' : 'created'; const messages = observableCombineLatest( - this.translateService.get(success ? `${prefix}.${suffix}` : `${prefix}.${suffix}`), - this.translateService.get(`${prefix}${isField ? '.field' : ''}.${editedString}`, options) + this.translateService.get( + success ? `${prefix}.${suffix}` : `${prefix}.${suffix}` + ), + this.translateService.get( + `${prefix}${isField ? '.field' : ''}.${editedString}`, + options + ) ); messages.subscribe(([head, content]) => { if (success) { @@ -321,7 +423,23 @@ export class RegistryService { * {@link HALLink}s should be automatically resolved * @returns an observable that emits a remote data object with a page of metadata fields that match the query */ - queryMetadataFields(query: string, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable>> { - return this.metadataFieldService.searchByFieldNameParams(null, null, null, query, null, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + queryMetadataFields( + query: string, + options: FindListOptions = {}, + useCachedVersionIfAvailable = true, + reRequestOnStale = true, + ...linksToFollow: FollowLinkConfig[] + ): Observable>> { + return this.metadataFieldService.searchByFieldNameParams( + null, + null, + null, + query, + null, + options, + useCachedVersionIfAvailable, + reRequestOnStale, + ...linksToFollow + ); } } diff --git a/src/app/item-page/item-page.module.ts b/src/app/item-page/item-page.module.ts index 3cf3f2bf560..ad6e38f7533 100644 --- a/src/app/item-page/item-page.module.ts +++ b/src/app/item-page/item-page.module.ts @@ -16,6 +16,7 @@ import { ItemPageAbstractFieldComponent } from './simple/field-components/specific-field/abstract/item-page-abstract-field.component'; import { ItemPageUriFieldComponent } from './simple/field-components/specific-field/uri/item-page-uri-field.component'; +import { ItemPageTitleFieldComponent } from './simple/field-components/specific-field/title/item-page-title-field.component'; import { ItemPageFieldComponent } from './simple/field-components/specific-field/item-page-field.component'; import { CollectionsComponent } from './field-components/collections/collections.component'; import { FullItemPageComponent } from './full/full-item-page.component'; @@ -68,11 +69,14 @@ import { FileSectionComponent } from './simple/field-components/file-section/fil import { ItemSharedModule } from './item-shared.module'; import { DsoPageModule } from '../shared/dso-page/dso-page.module'; +import { FileDescriptionComponent } from './simple/field-components/preview-section/file-description/file-description.component'; +import { FileTreeViewComponent } from './simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component'; +import { PreviewSectionComponent } from './simple/field-components/preview-section/preview-section.component'; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator PublicationComponent, - UntypedItemComponent + UntypedItemComponent, ]; const DECLARATIONS = [ @@ -118,7 +122,10 @@ const DECLARATIONS = [ ClarinStatisticsButtonComponent, ClarinGenericItemFieldComponent, ClarinCollectionsItemFieldComponent, - ClarinFilesItemFieldComponent + ClarinFilesItemFieldComponent, + PreviewSectionComponent, + FileDescriptionComponent, + FileTreeViewComponent, ]; @NgModule({ diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html new file mode 100644 index 00000000000..8a5cd15c580 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html @@ -0,0 +1,91 @@ +
        +
        + +
        +
        +
        +
        Name
        +
        + {{ fileInput.name }} +
        +
        Size
        +
        + {{ fileInput.fileSize }} +
        +
        Format
        +
        + {{ fileInput.format }} +
        +
        Description
        +
        + {{ fileInput.description }} +
        +
        MD5
        +
        + {{ fileInput.checksum }} +
        +
        + Preview +
        + +
        +
        +
        +  File Preview +
        +
        +
          + + + + +
          {{fileInput.fileInfo[0].content}}
          +
          +
        +
        +
        +
        +
        diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.scss b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.scss new file mode 100644 index 00000000000..2336ee20794 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.scss @@ -0,0 +1,106 @@ +.file-preview-box { + border: 1px solid #ddd; + padding: 4px; + margin-bottom: 10px; + + video { + margin-left: 100px; + } + + .file-content { + display: flex !important; + width: 100%; + justify-content: space-between; + + .dl-horizontal { + margin-bottom: 0; + } + + .thumbnails dl { + padding: 5px; + display: table; + } + + @media (min-width: 768px){ + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + } + + @media (min-width: 768px) { + .dl-horizontal dd { + margin-left: 180px; + } + } + + + .preview-image { + width: 10%; + height: 10%; + } + + } + + .button-container { + .download-btn, .preview-btn { + display: inline; + padding: .2em .6em .3em; + font-size: 14px; + font-weight: bold; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; + border: none; + color: white; + cursor: pointer; + background-color: #5bc0de; + } + } + + .panel { + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + box-shadow: 0 1px 1px rgba(0,0,0,0.05); + } + + .panel-info { + border-color: #bce8f1; + } + + .panel-info>.panel-heading { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; + } + + .panel-body { + padding: 15px; + + pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.428571429; + color: #333; + white-space: pre-wrap; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; + } + } + + .pull-right { + float: right !important; + } +} \ No newline at end of file diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.spec.ts b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.spec.ts new file mode 100644 index 00000000000..46586a7ce43 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.spec.ts @@ -0,0 +1,52 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { MetadataBitstream } from 'src/app/core/metadata/metadata-bitstream.model'; +import { ResourceType } from 'src/app/core/shared/resource-type'; +import { FileDescriptionComponent } from './file-description.component'; + +describe('FileDescriptionComponent', () => { + let component: FileDescriptionComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [FileDescriptionComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(FileDescriptionComponent); + component = fixture.componentInstance; + + // Mock the input value + const fileInput = new MetadataBitstream(); + fileInput.id = 123; + fileInput.name = 'testFile'; + fileInput.description = 'test description'; + fileInput.fileSize = '5MB'; + fileInput.checksum = 'abc'; + fileInput.type = new ResourceType('item'); + fileInput.fileInfo = []; + fileInput.format = 'application/pdf'; + fileInput.canPreview = false; + fileInput._links = { + self: { href: '' }, + schema: { href: '' }, + }; + + component.fileInput = fileInput; + + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should display the file name', () => { + const fileNameElement = fixture.debugElement.query( + By.css('.file-content dd') + ).nativeElement; + expect(fileNameElement.textContent).toContain('testFile'); + }); +}); diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts new file mode 100644 index 00000000000..68145d2fff4 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.ts @@ -0,0 +1,16 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { MetadataBitstream } from 'src/app/core/metadata/metadata-bitstream.model'; + +@Component({ + selector: 'ds-file-description', + templateUrl: './file-description.component.html', + styleUrls: ['./file-description.component.scss'], +}) +export class FileDescriptionComponent implements OnInit { + @Input() + fileInput: MetadataBitstream; + + ngOnInit(): void { + console.log(this.fileInput); + } +} diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.html b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.html new file mode 100644 index 00000000000..6644016bb99 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.html @@ -0,0 +1,24 @@ +
      • + + + {{ node.name }} + + + + + {{ node.name }}{{ node.size }} + + +
          + +
        +
      • \ No newline at end of file diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.scss b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.scss new file mode 100644 index 00000000000..1aaef2bf84c --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.scss @@ -0,0 +1,23 @@ +.foldername:before { + font-family: FontAwesome; + content: '\f07b'; + margin-right: 5px; + color: #a0a0a0; +} + +.filename:before { + font-family: FontAwesome; + content: '\f016'; + margin-right: 5px; + color: #a0a0a0; +} + + li { + padding: 0 0 0 8px; + margin: 0; + list-style: none; +} + +.pull-right { + float: right !important; +} \ No newline at end of file diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.spec.ts b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.spec.ts new file mode 100644 index 00000000000..606370da57a --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.spec.ts @@ -0,0 +1,55 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { FileInfo, MetadataBitstream } from 'src/app/core/metadata/metadata-bitstream.model'; +import { FileTreeViewComponent } from './file-tree-view.component'; + +describe('FileTreeViewComponent', () => { + let component: FileTreeViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ FileTreeViewComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(FileTreeViewComponent); + component = fixture.componentInstance; + + // Mock the node input value + const fileInfo = new FileInfo(); + fileInfo.name = 'TestFolder'; + fileInfo.isDirectory = true; + fileInfo.size = null; + fileInfo.content = null; // add content property + fileInfo.sub = { + 'TestSubFolder': { + name: 'TestSubFolder', + isDirectory: true, + size: null, + content: null, // add content property + sub: null + } + }; + + const metadataBitstream = new MetadataBitstream(); + metadataBitstream.fileInfo = [fileInfo]; + component.node = fileInfo; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should display the node name', () => { + const nodeNameElement = fixture.debugElement.query(By.css('.foldername')).nativeElement; + expect(nodeNameElement.textContent).toContain('TestFolder'); + }); + + it('should correctly get the keys of the sub object', () => { + expect(component.getKeys(component.node.sub)).toEqual(['TestSubFolder']); + }); +}); diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts new file mode 100644 index 00000000000..4471ebb25b7 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-tree-view/file-tree-view.component.ts @@ -0,0 +1,20 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { FileInfo } from 'src/app/core/metadata/metadata-bitstream.model'; + +@Component({ + selector: 'ds-file-tree-view', + templateUrl: './file-tree-view.component.html', + styleUrls: ['./file-tree-view.component.scss'], +}) +export class FileTreeViewComponent implements OnInit { + @Input() + node: FileInfo; + + getKeys(obj: any): string[] { + return Object.keys(obj); + } + + ngOnInit(): void { + console.log(this.node); + } +} diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.html b/src/app/item-page/simple/field-components/preview-section/preview-section.component.html new file mode 100644 index 00000000000..37ba7d1ce28 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.html @@ -0,0 +1,3 @@ +
        + +
        \ No newline at end of file diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.scss b/src/app/item-page/simple/field-components/preview-section/preview-section.component.scss new file mode 100644 index 00000000000..e4267ba0874 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.scss @@ -0,0 +1,107 @@ +.file-preview-box { + border: 1px solid #ddd; + padding: 4px; + + .file-content { + display: flex !important; + width: 100%; + justify-content: space-between; + + .dl-horizontal { + margin-bottom: 0; + } + + .thumbnails dl { + padding: 5px; + display: table; + } + + @media (min-width: 768px){ + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + } + + @media (min-width: 768px) { + .dl-horizontal dd { + margin-left: 180px; + } + } + + + .preview-image { + width: 10%; + height: 10%; + } + + } + + .button-container { + .download-btn, .preview-btn { + display: inline; + padding: .2em .6em .3em; + font-size: 12px; + font-weight: bold; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; + border: none; + color: white; + cursor: pointer; + background-color: #5bc0de; + } + } + + .panel { + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + box-shadow: 0 1px 1px rgba(0,0,0,0.05); + } + + .panel-info { + border-color: #bce8f1; + } + + .panel-info>.panel-heading { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; + } + + .treeview .foldername:before { + font-family: FontAwesome; + content: '\f07b'; + margin-right: 5px; + color: #a0a0a0; + } + + .treeview .filename:before { + font-family: FontAwesome; + content: '\f016'; + margin-right: 5px; + color: #a0a0a0; + } + + .treeview li { + padding: 0 0 0 8px; + margin: 0; + list-style: none; + } + + .pull-right { + float: right !important; + } + + .panel-body { + padding: 15px; + } +} \ No newline at end of file diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts b/src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts new file mode 100644 index 00000000000..e88b994e9f0 --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.spec.ts @@ -0,0 +1,71 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { BehaviorSubject, of } from 'rxjs'; +import { MetadataBitstream } from 'src/app/core/metadata/metadata-bitstream.model'; +import { RegistryService } from 'src/app/core/registry/registry.service'; + +import { PreviewSectionComponent } from './preview-section.component'; +import { ResourceType } from 'src/app/core/shared/resource-type'; +import { HALLink } from 'src/app/core/shared/hal-link.model'; + +describe('PreviewSectionComponent', () => { + let component: PreviewSectionComponent; + let fixture: ComponentFixture; + let mockRegistryService: any; + + beforeEach(async () => { + mockRegistryService = jasmine.createSpyObj('RegistryService', [ + 'getMetadataBitstream', + ]); + + await TestBed.configureTestingModule({ + declarations: [PreviewSectionComponent], + providers: [{ provide: RegistryService, useValue: mockRegistryService }], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(PreviewSectionComponent); + component = fixture.componentInstance; + + // Set up the mock service's getMetadataBitstream method to return a simple stream + const metadatabitstream = new MetadataBitstream(); + metadatabitstream.id = 123; + metadatabitstream.name = 'test'; + metadatabitstream.description = 'test'; + metadatabitstream.fileSize = '1MB'; + metadatabitstream.checksum = 'abc'; + metadatabitstream.type = new ResourceType('item'); + metadatabitstream.fileInfo = []; + metadatabitstream.format = 'text'; + metadatabitstream.canPreview = false; + metadatabitstream._links = { + self: new HALLink(), + schema: new HALLink(), + }; + + metadatabitstream._links.self.href = ''; + metadatabitstream._links.schema.href = ''; + const metadataBitstreams: MetadataBitstream[] = [metadatabitstream]; + const bitstreamStream = new BehaviorSubject(metadataBitstreams); + mockRegistryService.getMetadataBitstream.and.returnValue( + of(bitstreamStream) + ); + + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should call getMetadataBitstream on init', () => { + expect(mockRegistryService.getMetadataBitstream).toHaveBeenCalled(); + }); + + it('should set listOfFiles on init', (done) => { + component.listOfFiles.subscribe((files) => { + expect(files).toEqual([]); + done(); + }); + }); +}); diff --git a/src/app/item-page/simple/field-components/preview-section/preview-section.component.ts b/src/app/item-page/simple/field-components/preview-section/preview-section.component.ts new file mode 100644 index 00000000000..a515c30306b --- /dev/null +++ b/src/app/item-page/simple/field-components/preview-section/preview-section.component.ts @@ -0,0 +1,30 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; +import { MetadataBitstream } from 'src/app/core/metadata/metadata-bitstream.model'; +import { RegistryService } from 'src/app/core/registry/registry.service'; +import { Item } from 'src/app/core/shared/item.model'; +import { getAllSucceededRemoteListPayload } from 'src/app/core/shared/operators'; + +@Component({ + selector: 'ds-preview-section', + templateUrl: './preview-section.component.html', + styleUrls: ['./preview-section.component.scss'], +}) +export class PreviewSectionComponent implements OnInit { + @Input() item: Item; + + listOfFiles: BehaviorSubject = new BehaviorSubject< + MetadataBitstream[] + >([] as any); + + constructor(protected registryService: RegistryService) {} // Modified + + ngOnInit(): void { + this.registryService + .getMetadataBitstream('123456789/36', 'ORIGINAL,TEXT,THUMBNAIL') + .pipe(getAllSucceededRemoteListPayload()) + .subscribe((data: MetadataBitstream[]) => { + this.listOfFiles.next(data); + }); + } +} diff --git a/src/app/item-page/simple/item-page.component.html b/src/app/item-page/simple/item-page.component.html index fc4aaeffc17..dcac68672c3 100644 --- a/src/app/item-page/simple/item-page.component.html +++ b/src/app/item-page/simple/item-page.component.html @@ -11,6 +11,7 @@ +
        diff --git a/src/app/item-page/simple/item-types/shared/item-relationships-utils.ts b/src/app/item-page/simple/item-types/shared/item-relationships-utils.ts index b4c3da2cdc3..33a97493358 100644 --- a/src/app/item-page/simple/item-types/shared/item-relationships-utils.ts +++ b/src/app/item-page/simple/item-types/shared/item-relationships-utils.ts @@ -1,4 +1,8 @@ -import { combineLatest as observableCombineLatest, Observable, zip as observableZip } from 'rxjs'; +import { + combineLatest as observableCombineLatest, + Observable, + zip as observableZip, +} from 'rxjs'; import { distinctUntilChanged, map, mergeMap, switchMap } from 'rxjs/operators'; import { PaginatedList } from '../../../../core/data/paginated-list.model'; import { RemoteData } from '../../../../core/data/remote-data'; @@ -6,14 +10,20 @@ import { Relationship } from '../../../../core/shared/item-relationships/relatio import { Item } from '../../../../core/shared/item.model'; import { getFirstSucceededRemoteDataPayload, - getFirstSucceededRemoteData + getFirstSucceededRemoteData, } from '../../../../core/shared/operators'; import { hasValue } from '../../../../shared/empty.util'; import { InjectionToken } from '@angular/core'; -export const PAGINATED_RELATIONS_TO_ITEMS_OPERATOR = new InjectionToken<(thisId: string) => (source: Observable>>) => Observable>>>('paginatedRelationsToItems', { +export const PAGINATED_RELATIONS_TO_ITEMS_OPERATOR = new InjectionToken< + ( + thisId: string + ) => ( + source: Observable>> + ) => Observable>> +>('paginatedRelationsToItems', { providedIn: 'root', - factory: () => paginatedRelationsToItems + factory: () => paginatedRelationsToItems, }); /** @@ -23,42 +33,51 @@ export const PAGINATED_RELATIONS_TO_ITEMS_OPERATOR = new InjectionToken<(thisId: * For example: "(o) => o.id" will compare the two arrays by comparing their content by id. * @param mapFn Function for mapping the arrays */ -export const compareArraysUsing = (mapFn: (t: T) => any) => +export const compareArraysUsing = + (mapFn: (t: T) => any) => (a: T[], b: T[]): boolean => { - if (!Array.isArray(a) || ! Array.isArray(b)) { + if (!Array.isArray(a) || !Array.isArray(b)) { return false; } const aIds = a.map(mapFn); const bIds = b.map(mapFn); - return aIds.length === bIds.length && + return ( + aIds.length === bIds.length && aIds.every((e) => bIds.includes(e)) && - bIds.every((e) => aIds.includes(e)); + bIds.every((e) => aIds.includes(e)) + ); }; /** * Operator for comparing arrays using the object's ids */ export const compareArraysUsingIds = () => - compareArraysUsing((t: T) => hasValue(t) ? t.id : undefined); + compareArraysUsing((t: T) => (hasValue(t) ? t.id : undefined)); /** * Operator for turning a list of relationships into a list of the relevant items * @param {string} thisId The item's id of which the relations belong to * @returns {(source: Observable) => Observable} */ -export const relationsToItems = (thisId: string) => +export const relationsToItems = + (thisId: string) => (source: Observable): Observable => source.pipe( mergeMap((rels: Relationship[]) => observableZip( - ...rels.map((rel: Relationship) => observableCombineLatest(rel.leftItem, rel.rightItem)) + ...rels.map((rel: Relationship) => + observableCombineLatest(rel.leftItem, rel.rightItem) + ) ) ), map((arr) => arr - .filter(([leftItem, rightItem]) => leftItem.hasSucceeded && rightItem.hasSucceeded) + .filter( + ([leftItem, rightItem]) => + leftItem.hasSucceeded && rightItem.hasSucceeded + ) .map(([leftItem, rightItem]) => { if (leftItem.payload.id === thisId) { return rightItem.payload; @@ -68,7 +87,7 @@ export const relationsToItems = (thisId: string) => }) .filter((item: Item) => hasValue(item)) ), - distinctUntilChanged(compareArraysUsingIds()), + distinctUntilChanged(compareArraysUsingIds()) ); /** @@ -77,8 +96,11 @@ export const relationsToItems = (thisId: string) => * @param {string} thisId The item's id of which the relations belong to * @returns {(source: Observable) => Observable} */ -export const paginatedRelationsToItems = (thisId: string) => - (source: Observable>>): Observable>> => +export const paginatedRelationsToItems = + (thisId: string) => + ( + source: Observable>> + ): Observable>> => source.pipe( getFirstSucceededRemoteData(), switchMap((relationshipsRD: RemoteData>) => { @@ -86,9 +108,10 @@ export const paginatedRelationsToItems = (thisId: string) => relationshipsRD.payload.page.map((rel: Relationship) => observableCombineLatest([ rel.leftItem.pipe(getFirstSucceededRemoteDataPayload()), - rel.rightItem.pipe(getFirstSucceededRemoteDataPayload())] - ) - )).pipe( + rel.rightItem.pipe(getFirstSucceededRemoteDataPayload()), + ]) + ) + ).pipe( map((arr) => arr .map(([leftItem, rightItem]) => { @@ -102,7 +125,11 @@ export const paginatedRelationsToItems = (thisId: string) => ), distinctUntilChanged(compareArraysUsingIds()), map((relatedItems: Item[]) => - Object.assign(relationshipsRD, { payload: Object.assign(relationshipsRD.payload, { page: relatedItems } )}) + Object.assign(relationshipsRD, { + payload: Object.assign(relationshipsRD.payload, { + page: relatedItems, + }), + }) ) ); }) diff --git a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html index ffd7af5809c..957576583dc 100644 --- a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html +++ b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html @@ -104,5 +104,6 @@ [iconName]="'fa-paperclip'" [separator]="'
        '"> +
        From 9c9149f49395b5f721ff3fdb74299e1ce653204e Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Wed, 27 Sep 2023 14:52:40 +0200 Subject: [PATCH 13/26] Resolved conflicts --- .../data/metadata-bitstream-data.service.ts | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/app/core/data/metadata-bitstream-data.service.ts b/src/app/core/data/metadata-bitstream-data.service.ts index 7e583eb99bf..55144566192 100644 --- a/src/app/core/data/metadata-bitstream-data.service.ts +++ b/src/app/core/data/metadata-bitstream-data.service.ts @@ -1,6 +1,5 @@ import { Injectable } from '@angular/core'; import { hasValue } from '../../shared/empty.util'; -import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; @@ -8,31 +7,33 @@ import { HALEndpointService } from '../shared/hal-endpoint.service'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { Observable } from 'rxjs'; import { RequestParam } from '../cache/models/request-param.model'; -import { NoContent } from '../shared/NoContent.model'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { ObjectCacheService } from '../cache/object-cache.service'; import { METADATA_BITSTREAM } from '../metadata/metadata-bitstream.resource-type'; -import { FindListOptions } from './request.models'; -import { dataService } from '../cache/builders/build-decorators'; import { MetadataBitstream } from '../metadata/metadata-bitstream.model'; -import { DataService } from './data.service'; import { HttpClient } from '@angular/common/http'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ChangeAnalyzer } from './change-analyzer'; -import { tap } from 'rxjs/operators'; +import { IdentifiableDataService } from './base/identifiable-data.service'; +import { SearchData, SearchDataImpl } from './base/search-data'; +import { CoreState } from '../core-state.model'; +import { dataService } from './base/data-service.decorator'; +import { FindListOptions } from './find-list-options.model'; +import { linkName } from './clarin/clarin-license-data.service'; +import { PaginatedList } from './paginated-list.model'; /** * A service responsible for fetching/sending data from/to the REST API on the metadatafields endpoint */ @Injectable() @dataService(METADATA_BITSTREAM) -export class MetadataBitstreamDataService extends DataService { +export class MetadataBitstreamDataService extends IdentifiableDataService implements SearchData { protected store: Store; protected http: HttpClient; protected comparator: ChangeAnalyzer; protected linkPath = 'metadatabitstreams'; protected searchByHandleLinkPath = 'byHandle'; + private searchData: SearchData; constructor( protected requestService: RequestService, @@ -41,7 +42,8 @@ export class MetadataBitstreamDataService extends DataService protected halService: HALEndpointService, protected notificationsService: NotificationsService ) { - super(); + super(linkName, requestService, rdbService, objectCache, halService, undefined); + this.searchData = new SearchDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive); } /** @@ -79,4 +81,8 @@ export class MetadataBitstreamDataService extends DataService ...linksToFollow ); } + + searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig[]): Observable>> { + return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); + } } From 94b62af37210e271e746d4ac24ab9c7db1a15169 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Wed, 27 Sep 2023 16:04:33 +0200 Subject: [PATCH 14/26] Revert unnecessary changes --- .../builders/remote-data-build.service.ts | 218 +++++------------- .../core/registry/registry.service.spec.ts | 215 +++++++---------- src/app/core/registry/registry.service.ts | 167 +++----------- .../simple/item-page.component.spec.ts | 37 ++- .../item-page/simple/item-page.component.ts | 16 +- .../shared/item-relationships-utils.ts | 65 ++---- .../untyped-item/untyped-item.component.html | 1 - 7 files changed, 221 insertions(+), 498 deletions(-) diff --git a/src/app/core/cache/builders/remote-data-build.service.ts b/src/app/core/cache/builders/remote-data-build.service.ts index 607fecad499..76529891d4b 100644 --- a/src/app/core/cache/builders/remote-data-build.service.ts +++ b/src/app/core/cache/builders/remote-data-build.service.ts @@ -5,24 +5,10 @@ import { Observable, of as observableOf, } from 'rxjs'; -import { - map, - switchMap, - filter, - distinctUntilKeyChanged, startWith, -} from 'rxjs/operators'; -import { - hasValue, - isEmpty, - isNotEmpty, - hasNoValue, - isUndefined, -} from '../../../shared/empty.util'; +import { map, switchMap, filter, distinctUntilKeyChanged, startWith } from 'rxjs/operators'; +import { hasValue, isEmpty, isNotEmpty, hasNoValue, isUndefined } from '../../../shared/empty.util'; import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; -import { - FollowLinkConfig, - followLink, -} from '../../../shared/utils/follow-link-config.model'; +import { FollowLinkConfig, followLink } from '../../../shared/utils/follow-link-config.model'; import { PaginatedList } from '../../data/paginated-list.model'; import { RemoteData } from '../../data/remote-data'; import { RequestService } from '../../data/request.service'; @@ -43,11 +29,10 @@ import { getFirstCompletedRemoteData } from '../../shared/operators'; @Injectable() export class RemoteDataBuildService { - constructor( - protected objectCache: ObjectCacheService, - protected linkService: LinkService, - protected requestService: RequestService - ) {} + constructor(protected objectCache: ObjectCacheService, + protected linkService: LinkService, + protected requestService: RequestService) { + } /** * Creates an Observable with the payload for a RemoteData object @@ -61,36 +46,21 @@ export class RemoteDataBuildService { * should be automatically resolved * @private */ - private buildPayload( - requestEntry$: Observable, - href$?: Observable, - ...linksToFollow: FollowLinkConfig[] - ): Observable { + private buildPayload(requestEntry$: Observable, href$?: Observable, ...linksToFollow: FollowLinkConfig[]): Observable { if (hasNoValue(href$)) { href$ = observableOf(undefined); } return observableCombineLatest([href$, requestEntry$]).pipe( switchMap(([href, entry]: [string, RequestEntry]) => { - const hasExactMatchInObjectCache = this.hasExactMatchInObjectCache( - href, - entry - ); - if ( - hasValue(entry.response) && - (hasExactMatchInObjectCache || - this.isCacheablePayload(entry) || - this.isUnCacheablePayload(entry)) - ) { + const hasExactMatchInObjectCache = this.hasExactMatchInObjectCache(href, entry); + if (hasValue(entry.response) && + (hasExactMatchInObjectCache || this.isCacheablePayload(entry) || this.isUnCacheablePayload(entry))) { if (hasExactMatchInObjectCache) { return this.objectCache.getObjectByHref(href); } else if (this.isCacheablePayload(entry)) { - return this.objectCache.getObjectByHref( - entry.response.payloadLink.href - ); + return this.objectCache.getObjectByHref(entry.response.payloadLink.href); } else { - return [ - this.plainObjectToInstance(entry.response.unCacheableObject), - ]; + return [this.plainObjectToInstance(entry.response.unCacheableObject)]; } } else if (hasSucceeded(entry.state)) { return [null]; @@ -100,9 +70,7 @@ export class RemoteDataBuildService { }), switchMap((obj: T) => { if (hasValue(obj)) { - if ( - getResourceTypeValueFor((obj as any).type) === PAGINATED_LIST.value - ) { + if (getResourceTypeValueFor((obj as any).type) === PAGINATED_LIST.value) { return this.buildPaginatedList(obj, ...linksToFollow); } else if (isNotEmpty(linksToFollow)) { return [this.linkService.resolveLinks(obj, ...linksToFollow)]; @@ -139,17 +107,9 @@ export class RemoteDataBuildService { * @param entry the request entry the object has to match * @private */ - private hasExactMatchInObjectCache( - href: string, - entry: RequestEntry - ): boolean { - return ( - hasValue(entry) && - hasValue(entry.request) && - isNotEmpty(entry.request.uuid) && - hasValue(href) && - this.objectCache.hasByHref(href, entry.request.uuid) - ); + private hasExactMatchInObjectCache(href: string, entry: RequestEntry): boolean { + return hasValue(entry) && hasValue(entry.request) && isNotEmpty(entry.request.uuid) && + hasValue(href) && this.objectCache.hasByHref(href, entry.request.uuid); } /** @@ -158,10 +118,7 @@ export class RemoteDataBuildService { * @private */ private isCacheablePayload(entry: RequestEntry): boolean { - return ( - hasValue(entry.response.payloadLink) && - isNotEmpty(entry.response.payloadLink.href) - ); + return hasValue(entry.response.payloadLink) && isNotEmpty(entry.response.payloadLink.href); } /** @@ -181,40 +138,26 @@ export class RemoteDataBuildService { * @param object A plain object to be turned in to a {@link PaginatedList} * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved */ - private buildPaginatedList( - object: any, - ...linksToFollow: FollowLinkConfig[] - ): Observable { - const pageLink = linksToFollow.find( - (linkToFollow: FollowLinkConfig) => linkToFollow.name === 'page' - ); - const otherLinks = linksToFollow.filter( - (linkToFollow: FollowLinkConfig) => linkToFollow.name !== 'page' - ); + private buildPaginatedList(object: any, ...linksToFollow: FollowLinkConfig[]): Observable { + const pageLink = linksToFollow.find((linkToFollow: FollowLinkConfig) => linkToFollow.name === 'page'); + const otherLinks = linksToFollow.filter((linkToFollow: FollowLinkConfig) => linkToFollow.name !== 'page'); const paginatedList = Object.assign(new PaginatedList(), object); if (hasValue(pageLink)) { if (isEmpty(paginatedList.page)) { - const pageSelfLinks = paginatedList._links.page.map( - (link: HALLink) => link.href - ); - return this.objectCache.getList(pageSelfLinks).pipe( - map((page: any[]) => { - paginatedList.page = page - .map((obj: any) => this.plainObjectToInstance(obj)) - .map((obj: any) => - this.linkService.resolveLinks(obj, ...pageLink.linksToFollow) - ); - if (isNotEmpty(otherLinks)) { - return this.linkService.resolveLinks( - paginatedList, - ...otherLinks - ); - } - return paginatedList; - }) - ); + const pageSelfLinks = paginatedList._links.page.map((link: HALLink) => link.href); + return this.objectCache.getList(pageSelfLinks).pipe(map((page: any[]) => { + paginatedList.page = page + .map((obj: any) => this.plainObjectToInstance(obj)) + .map((obj: any) => + this.linkService.resolveLinks(obj, ...pageLink.linksToFollow) + ); + if (isNotEmpty(otherLinks)) { + return this.linkService.resolveLinks(paginatedList, ...otherLinks); + } + return paginatedList; + })); } else { // in case the elements of the paginated list were already filled in, because they're UnCacheableObjects paginatedList.page = paginatedList.page @@ -223,9 +166,7 @@ export class RemoteDataBuildService { this.linkService.resolveLinks(obj, ...pageLink.linksToFollow) ); if (isNotEmpty(otherLinks)) { - return observableOf( - this.linkService.resolveLinks(paginatedList, ...otherLinks) - ); + return observableOf(this.linkService.resolveLinks(paginatedList, ...otherLinks)); } } } @@ -238,22 +179,13 @@ export class RemoteDataBuildService { * @param requestUUID$ The UUID of the request we want to retrieve * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved */ - buildFromRequestUUID( - requestUUID$: string | Observable, - ...linksToFollow: FollowLinkConfig[] - ): Observable> { + buildFromRequestUUID(requestUUID$: string | Observable, ...linksToFollow: FollowLinkConfig[]): Observable> { if (typeof requestUUID$ === 'string') { requestUUID$ = observableOf(requestUUID$); } - const requestEntry$ = requestUUID$.pipe( - getRequestFromRequestUUID(this.requestService) - ); + const requestEntry$ = requestUUID$.pipe(getRequestFromRequestUUID(this.requestService)); - const payload$ = this.buildPayload( - requestEntry$, - undefined, - ...linksToFollow - ); + const payload$ = this.buildPayload(requestEntry$, undefined, ...linksToFollow); return this.toRemoteDataObservable(requestEntry$, payload$); } @@ -307,10 +239,7 @@ export class RemoteDataBuildService { * @param href$ self link of object we want to retrieve * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved */ - buildFromHref( - href$: string | Observable, - ...linksToFollow: FollowLinkConfig[] - ): Observable> { + buildFromHref(href$: string | Observable, ...linksToFollow: FollowLinkConfig[]): Observable> { if (typeof href$ === 'string') { href$ = observableOf(href$); } @@ -319,8 +248,7 @@ export class RemoteDataBuildService { const requestUUID$ = href$.pipe( switchMap((href: string) => - this.objectCache.getRequestUUIDBySelfLink(href) - ) + this.objectCache.getRequestUUIDBySelfLink(href)), ); const requestEntry$ = observableCombineLatest([ @@ -347,11 +275,7 @@ export class RemoteDataBuildService { distinctUntilKeyChanged('lastUpdated') ); - const payload$ = this.buildPayload( - requestEntry$, - href$, - ...linksToFollow - ); + const payload$ = this.buildPayload(requestEntry$, href$, ...linksToFollow); return this.toRemoteDataObservable(requestEntry$, payload$); } @@ -362,23 +286,19 @@ export class RemoteDataBuildService { * @param href$ Observable href of object we want to retrieve * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved */ - buildSingle( - href$: string | Observable, - ...linksToFollow: FollowLinkConfig[] - ): Observable> { + buildSingle(href$: string | Observable, ...linksToFollow: FollowLinkConfig[]): Observable> { return this.buildFromHref(href$, ...linksToFollow); } - toRemoteDataObservable( - requestEntry$: Observable, - payload$: Observable - ) { - return observableCombineLatest([requestEntry$, payload$]).pipe( - filter( - ([entry, payload]: [RequestEntry, T]) => - hasValue(entry) && - // filter out cases where the state is successful, but the payload isn't yet set - !(hasSucceeded(entry.state) && isUndefined(payload)) + toRemoteDataObservable(requestEntry$: Observable, payload$: Observable) { + return observableCombineLatest([ + requestEntry$, + payload$ + ]).pipe( + filter(([entry,payload]: [RequestEntry, T]) => + hasValue(entry) && + // filter out cases where the state is successful, but the payload isn't yet set + !(hasSucceeded(entry.state) && isUndefined(payload)) ), map(([entry, payload]: [RequestEntry, T]) => { let response = entry.response; @@ -408,14 +328,8 @@ export class RemoteDataBuildService { * @param href$ Observable href of objects we want to retrieve * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved */ - buildList( - href$: string | Observable, - ...linksToFollow: FollowLinkConfig[] - ): Observable>> { - return this.buildFromHref>( - href$, - followLink('page', { shouldEmbed: false }, ...linksToFollow) - ); + buildList(href$: string | Observable, ...linksToFollow: FollowLinkConfig[]): Observable>> { + return this.buildFromHref>(href$, followLink('page', { shouldEmbed: false }, ...linksToFollow)); } /** @@ -428,9 +342,8 @@ export class RemoteDataBuildService { * * @param input the array of RemoteData observables to start from */ - aggregate( - input: Observable>[] - ): Observable> { + aggregate(input: Observable>[]): Observable> { + if (isEmpty(input)) { return createSuccessfulRemoteDataObject$([], new Date().getTime()); } @@ -439,21 +352,15 @@ export class RemoteDataBuildService { map((arr) => { const timeCompleted = arr .map((d: RemoteData) => d.timeCompleted) - .reduce((max: number, current: number) => - current > max ? current : max - ); + .reduce((max: number, current: number) => current > max ? current : max); const msToLive = arr .map((d: RemoteData) => d.msToLive) - .reduce((min: number, current: number) => - current < min ? current : min - ); + .reduce((min: number, current: number) => current < min ? current : min); const lastUpdated = arr .map((d: RemoteData) => d.lastUpdated) - .reduce((max: number, current: number) => - current > max ? current : max - ); + .reduce((max: number, current: number) => current > max ? current : max); let state: RequestEntryState; if (arr.some((d: RemoteData) => d.isRequestPending)) { @@ -476,13 +383,11 @@ export class RemoteDataBuildService { if (hasValue(e)) { return `[${idx}]: ${e}`; } - }) - .filter((e: string) => hasValue(e)) + }).filter((e: string) => hasValue(e)) .join(', '); - const statusCodes = new Set( - arr.map((d: RemoteData) => d.statusCode) - ); + const statusCodes = new Set(arr + .map((d: RemoteData) => d.statusCode)); let statusCode: number; @@ -503,7 +408,6 @@ export class RemoteDataBuildService { payload, statusCode ); - }) - ); + })); } } diff --git a/src/app/core/registry/registry.service.spec.ts b/src/app/core/registry/registry.service.spec.ts index de545623462..a926c19d426 100644 --- a/src/app/core/registry/registry.service.spec.ts +++ b/src/app/core/registry/registry.service.spec.ts @@ -14,7 +14,7 @@ import { MetadataRegistryEditFieldAction, MetadataRegistryEditSchemaAction, MetadataRegistrySelectFieldAction, - MetadataRegistrySelectSchemaAction, + MetadataRegistrySelectSchemaAction } from '../../admin/admin-registries/metadata-registry/metadata-registry.actions'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { StoreMock } from '../../shared/testing/store.mock'; @@ -25,10 +25,7 @@ import { RegistryService } from './registry.service'; import { storeModuleConfig } from '../../app.reducer'; import { MetadataSchemaDataService } from '../data/metadata-schema-data.service'; import { MetadataFieldDataService } from '../data/metadata-field-data.service'; -import { - createNoContentRemoteDataObject$, - createSuccessfulRemoteDataObject$, -} from '../../shared/remote-data.utils'; +import { createNoContentRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createPaginatedList } from '../../shared/testing/utils.test'; import { RemoteData } from '../data/remote-data'; import { NoContent } from '../shared/NoContent.model'; @@ -36,7 +33,8 @@ import { FindListOptions } from '../data/find-list-options.model'; import { MetadataBitstreamDataService } from '../data/metadata-bitstream-data.service'; @Component({ template: '' }) -class DummyComponent {} +class DummyComponent { +} describe('RegistryService', () => { let registryService: RegistryService; @@ -52,110 +50,96 @@ describe('RegistryService', () => { function init() { options = Object.assign(new FindListOptions(), { currentPage: 1, - elementsPerPage: 20, + elementsPerPage: 20 }); mockSchemasList = [ Object.assign(new MetadataSchema(), { id: 1, _links: { - self: { - href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/1', - }, + self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/1' } }, prefix: 'dc', namespace: 'http://dublincore.org/documents/dcmi-terms/', - type: MetadataSchema.type, + type: MetadataSchema.type }), Object.assign(new MetadataSchema(), { id: 2, _links: { - self: { - href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/2', - }, + self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadataschemas/2' } }, prefix: 'mock', namespace: 'http://dspace.org/mockschema', - type: MetadataSchema.type, - }), + type: MetadataSchema.type + }) ]; mockFieldsList = [ - Object.assign(new MetadataField(), { - id: 1, - _links: { - self: { - href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/8', + Object.assign(new MetadataField(), + { + id: 1, + _links: { + self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/8' } }, - }, - element: 'contributor', - qualifier: 'advisor', - scopeNote: null, - schema: createSuccessfulRemoteDataObject$(mockSchemasList[0]), - type: MetadataField.type, - }), - Object.assign(new MetadataField(), { - id: 2, - _links: { - self: { - href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/9', + element: 'contributor', + qualifier: 'advisor', + scopeNote: null, + schema: createSuccessfulRemoteDataObject$(mockSchemasList[0]), + type: MetadataField.type + }), + Object.assign(new MetadataField(), + { + id: 2, + _links: { + self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/9' } }, - }, - element: 'contributor', - qualifier: 'author', - scopeNote: null, - schema: createSuccessfulRemoteDataObject$(mockSchemasList[0]), - type: MetadataField.type, - }), - Object.assign(new MetadataField(), { - id: 3, - _links: { - self: { - href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/10', + element: 'contributor', + qualifier: 'author', + scopeNote: null, + schema: createSuccessfulRemoteDataObject$(mockSchemasList[0]), + type: MetadataField.type + }), + Object.assign(new MetadataField(), + { + id: 3, + _links: { + self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/10' } }, - }, - element: 'contributor', - qualifier: 'editor', - scopeNote: 'test scope note', - schema: createSuccessfulRemoteDataObject$(mockSchemasList[1]), - type: MetadataField.type, - }), - Object.assign(new MetadataField(), { - id: 4, - _links: { - self: { - href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/11', + element: 'contributor', + qualifier: 'editor', + scopeNote: 'test scope note', + schema: createSuccessfulRemoteDataObject$(mockSchemasList[1]), + type: MetadataField.type + }), + Object.assign(new MetadataField(), + { + id: 4, + _links: { + self: { href: 'https://dspace7.4science.it/dspace-spring-rest/api/core/metadatafields/11' } }, - }, - element: 'contributor', - qualifier: 'illustrator', - scopeNote: null, - schema: createSuccessfulRemoteDataObject$(mockSchemasList[1]), - type: MetadataField.type, - }), + element: 'contributor', + qualifier: 'illustrator', + scopeNote: null, + schema: createSuccessfulRemoteDataObject$(mockSchemasList[1]), + type: MetadataField.type + }) ]; metadataSchemaService = jasmine.createSpyObj('metadataSchemaService', { - findAll: createSuccessfulRemoteDataObject$( - createPaginatedList(mockSchemasList) - ), + findAll: createSuccessfulRemoteDataObject$(createPaginatedList(mockSchemasList)), findById: createSuccessfulRemoteDataObject$(mockSchemasList[0]), - createOrUpdateMetadataSchema: createSuccessfulRemoteDataObject$( - mockSchemasList[0] - ), + createOrUpdateMetadataSchema: createSuccessfulRemoteDataObject$(mockSchemasList[0]), delete: createNoContentRemoteDataObject$(), - clearRequests: observableOf('href'), + clearRequests: observableOf('href') }); metadataFieldService = jasmine.createSpyObj('metadataFieldService', { - findAll: createSuccessfulRemoteDataObject$( - createPaginatedList(mockFieldsList) - ), + findAll: createSuccessfulRemoteDataObject$(createPaginatedList(mockFieldsList)), findById: createSuccessfulRemoteDataObject$(mockFieldsList[0]), create: createSuccessfulRemoteDataObject$(mockFieldsList[0]), put: createSuccessfulRemoteDataObject$(mockFieldsList[0]), delete: createNoContentRemoteDataObject$(), - clearRequests: observableOf('href'), + clearRequests: observableOf('href') }); metadataBitstreamDataService = jasmine.createSpyObj( 'metadataBitstreamDataService', @@ -170,26 +154,17 @@ describe('RegistryService', () => { beforeEach(() => { init(); TestBed.configureTestingModule({ - imports: [ - CommonModule, - StoreModule.forRoot({}, storeModuleConfig), - TranslateModule.forRoot(), + imports: [CommonModule, StoreModule.forRoot({}, storeModuleConfig), TranslateModule.forRoot()], + declarations: [ + DummyComponent ], - declarations: [DummyComponent], providers: [ { provide: Store, useClass: StoreMock }, - { - provide: NotificationsService, - useValue: new NotificationsServiceStub(), - }, + { provide: NotificationsService, useValue: new NotificationsServiceStub() }, { provide: MetadataSchemaDataService, useValue: metadataSchemaService }, { provide: MetadataFieldDataService, useValue: metadataFieldService }, - { - provide: MetadataBitstreamDataService, - useValue: metadataBitstreamDataService, - }, - RegistryService, - ], + RegistryService + ] }); registryService = TestBed.inject(RegistryService); mockStore = TestBed.inject(Store); @@ -214,18 +189,12 @@ describe('RegistryService', () => { let result; beforeEach(() => { - result = registryService.getMetadataSchemaByPrefix( - mockSchemasList[0].prefix - ); + result = registryService.getMetadataSchemaByPrefix(mockSchemasList[0].prefix); }); it('should call metadataSchemaService.findById with the correct ID', (done) => { result.subscribe(() => { - expect(metadataSchemaService.findById).toHaveBeenCalledWith( - `${mockSchemasList[0].id}`, - true, - true - ); + expect(metadataSchemaService.findById).toHaveBeenCalledWith(`${mockSchemasList[0].id}`, true, true); done(); }); }); @@ -242,9 +211,7 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryEditSchemaAction with the correct schema', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith( - new MetadataRegistryEditSchemaAction(mockSchemasList[0]) - ); + expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryEditSchemaAction(mockSchemasList[0])); }); }); @@ -254,9 +221,7 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryCancelSchemaAction', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith( - new MetadataRegistryCancelSchemaAction() - ); + expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryCancelSchemaAction()); }); }); @@ -266,9 +231,7 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistrySelectSchemaAction with the correct schema', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith( - new MetadataRegistrySelectSchemaAction(mockSchemasList[0]) - ); + expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistrySelectSchemaAction(mockSchemasList[0])); }); }); @@ -278,9 +241,7 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryDeselectSchemaAction with the correct schema', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith( - new MetadataRegistryDeselectSchemaAction(mockSchemasList[0]) - ); + expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryDeselectSchemaAction(mockSchemasList[0])); }); }); @@ -290,9 +251,7 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryDeselectAllSchemaAction', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith( - new MetadataRegistryDeselectAllSchemaAction() - ); + expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryDeselectAllSchemaAction()); }); }); @@ -302,9 +261,7 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryEditFieldAction with the correct Field', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith( - new MetadataRegistryEditFieldAction(mockFieldsList[0]) - ); + expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryEditFieldAction(mockFieldsList[0])); }); }); @@ -314,9 +271,7 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryCancelFieldAction', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith( - new MetadataRegistryCancelFieldAction() - ); + expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryCancelFieldAction()); }); }); @@ -326,9 +281,7 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistrySelectFieldAction with the correct Field', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith( - new MetadataRegistrySelectFieldAction(mockFieldsList[0]) - ); + expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistrySelectFieldAction(mockFieldsList[0])); }); }); @@ -338,9 +291,7 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryDeselectFieldAction with the correct Field', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith( - new MetadataRegistryDeselectFieldAction(mockFieldsList[0]) - ); + expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryDeselectFieldAction(mockFieldsList[0])); }); }); @@ -350,9 +301,7 @@ describe('RegistryService', () => { }); it('should dispatch a MetadataRegistryDeselectAllFieldAction', () => { - expect(mockStore.dispatch).toHaveBeenCalledWith( - new MetadataRegistryDeselectAllFieldAction() - ); + expect(mockStore.dispatch).toHaveBeenCalledWith(new MetadataRegistryDeselectAllFieldAction()); }); }); }); @@ -376,10 +325,7 @@ describe('RegistryService', () => { let result: Observable; beforeEach(() => { - result = registryService.createMetadataField( - mockFieldsList[0], - mockSchemasList[0] - ); + result = registryService.createMetadataField(mockFieldsList[0], mockSchemasList[0]); }); it('should return the created metadata field', (done) => { @@ -397,10 +343,7 @@ describe('RegistryService', () => { beforeEach(() => { metadataField = mockFieldsList[0]; metadataField.qualifier = ''; - result = registryService.createMetadataField( - metadataField, - mockSchemasList[0] - ); + result = registryService.createMetadataField(metadataField, mockSchemasList[0]); }); it('should return the created metadata field with a null qualifier', (done) => { diff --git a/src/app/core/registry/registry.service.ts b/src/app/core/registry/registry.service.ts index b91eb183d98..be7d171d0e6 100644 --- a/src/app/core/registry/registry.service.ts +++ b/src/app/core/registry/registry.service.ts @@ -2,11 +2,7 @@ import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; import { Injectable } from '@angular/core'; import { RemoteData } from '../data/remote-data'; import { PaginatedList } from '../data/paginated-list.model'; -import { - hasValue, - hasValueOperator, - isNotEmptyOperator, -} from '../../shared/empty.util'; +import { hasValue, hasValueOperator, isNotEmptyOperator } from '../../shared/empty.util'; import { getFirstSucceededRemoteDataPayload } from '../shared/operators'; import { createSelector, select, Store } from '@ngrx/store'; import { AppState } from '../../app.reducer'; @@ -21,7 +17,7 @@ import { MetadataRegistryEditFieldAction, MetadataRegistryEditSchemaAction, MetadataRegistrySelectFieldAction, - MetadataRegistrySelectSchemaAction, + MetadataRegistrySelectSchemaAction } from '../../admin/admin-registries/metadata-registry/metadata-registry.actions'; import { map, mergeMap, tap } from 'rxjs/operators'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -37,38 +33,25 @@ import { NoContent } from '../shared/NoContent.model'; import { FindListOptions } from '../data/find-list-options.model'; import { MetadataBitstream } from '../metadata/metadata-bitstream.model'; -const metadataRegistryStateSelector = (state: AppState) => - state.metadataRegistry; -const editMetadataSchemaSelector = createSelector( - metadataRegistryStateSelector, - (metadataState: MetadataRegistryState) => metadataState.editSchema -); -const selectedMetadataSchemasSelector = createSelector( - metadataRegistryStateSelector, - (metadataState: MetadataRegistryState) => metadataState.selectedSchemas -); -const editMetadataFieldSelector = createSelector( - metadataRegistryStateSelector, - (metadataState: MetadataRegistryState) => metadataState.editField -); -const selectedMetadataFieldsSelector = createSelector( - metadataRegistryStateSelector, - (metadataState: MetadataRegistryState) => metadataState.selectedFields -); +const metadataRegistryStateSelector = (state: AppState) => state.metadataRegistry; +const editMetadataSchemaSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editSchema); +const selectedMetadataSchemasSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.selectedSchemas); +const editMetadataFieldSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editField); +const selectedMetadataFieldsSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.selectedFields); /** * Service for registry related CRUD actions such as metadata schema, metadata field and bitstream format */ @Injectable() export class RegistryService { - constructor( - private store: Store, - private notificationsService: NotificationsService, - private translateService: TranslateService, - private metadataSchemaService: MetadataSchemaDataService, - private metadataFieldService: MetadataFieldDataService, - private metadataBitstreamDataService: MetadataBitstreamDataService - ) {} + constructor(private store: Store, + private notificationsService: NotificationsService, + private translateService: TranslateService, + private metadataSchemaService: MetadataSchemaDataService, + private metadataFieldService: MetadataFieldDataService, + private metadataBitstreamDataService: MetadataBitstreamDataService) { + + } /** * Retrieves all metadata schemas @@ -80,18 +63,8 @@ export class RegistryService { * @param linksToFollow List of {@link FollowLinkConfig} that indicate which * {@link HALLink}s should be automatically resolved */ - public getMetadataSchemas( - options: FindListOptions = {}, - useCachedVersionIfAvailable = true, - reRequestOnStale = true, - ...linksToFollow: FollowLinkConfig[] - ): Observable>> { - return this.metadataSchemaService.findAll( - options, - useCachedVersionIfAvailable, - reRequestOnStale, - ...linksToFollow - ); + public getMetadataSchemas(options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable>> { + return this.metadataSchemaService.findAll(options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); } /** @@ -104,32 +77,17 @@ export class RegistryService { * @param linksToFollow List of {@link FollowLinkConfig} that indicate which * {@link HALLink}s should be automatically resolved */ - public getMetadataSchemaByPrefix( - prefix: string, - useCachedVersionIfAvailable = true, - reRequestOnStale = true, - ...linksToFollow: FollowLinkConfig[] - ): Observable> { + public getMetadataSchemaByPrefix(prefix: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable> { // Temporary options to get ALL metadataschemas until there's a rest api endpoint for fetching a specific schema const options: FindListOptions = Object.assign(new FindListOptions(), { - elementsPerPage: 10000, + elementsPerPage: 10000 }); return this.getMetadataSchemas(options).pipe( getFirstSucceededRemoteDataPayload(), map((schemas: PaginatedList) => schemas.page), isNotEmptyOperator(), - map( - (schemas: MetadataSchema[]) => - schemas.filter((schema) => schema.prefix === prefix)[0] - ), - mergeMap((schema: MetadataSchema) => - this.metadataSchemaService.findById( - `${schema.id}`, - useCachedVersionIfAvailable, - reRequestOnStale, - ...linksToFollow - ) - ) + map((schemas: MetadataSchema[]) => schemas.filter((schema) => schema.prefix === prefix)[0]), + mergeMap((schema: MetadataSchema) => this.metadataSchemaService.findById(`${schema.id}`, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow)) ); } @@ -144,20 +102,8 @@ export class RegistryService { * @param linksToFollow List of {@link FollowLinkConfig} that indicate which * {@link HALLink}s should be automatically resolved */ - public getMetadataFieldsBySchema( - schema: MetadataSchema, - options: FindListOptions = {}, - useCachedVersionIfAvailable = true, - reRequestOnStale = true, - ...linksToFollow: FollowLinkConfig[] - ): Observable>> { - return this.metadataFieldService.findBySchema( - schema, - options, - useCachedVersionIfAvailable, - reRequestOnStale, - ...linksToFollow - ); + public getMetadataFieldsBySchema(schema: MetadataSchema, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable>> { + return this.metadataFieldService.findBySchema(schema, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); } /** @@ -297,17 +243,13 @@ export class RegistryService { * - On update, a PutRequest is used * @param schema The MetadataSchema to create or update */ - public createOrUpdateMetadataSchema( - schema: MetadataSchema - ): Observable { + public createOrUpdateMetadataSchema(schema: MetadataSchema): Observable { const isUpdate = hasValue(schema.id); return this.metadataSchemaService.createOrUpdateMetadataSchema(schema).pipe( getFirstSucceededRemoteDataPayload(), hasValueOperator(), tap(() => { - this.showNotifications(true, isUpdate, false, { - prefix: schema.prefix, - }); + this.showNotifications(true, isUpdate, false, { prefix: schema.prefix }); }) ); } @@ -333,24 +275,17 @@ export class RegistryService { * @param field The MetadataField to create * @param schema The MetadataSchema to create the field in */ - public createMetadataField( - field: MetadataField, - schema: MetadataSchema - ): Observable { + public createMetadataField(field: MetadataField, schema: MetadataSchema): Observable { if (!field.qualifier) { field.qualifier = null; } - return this.metadataFieldService - .create(field, new RequestParam('schemaId', schema.id)) - .pipe( - getFirstSucceededRemoteDataPayload(), - hasValueOperator(), - tap(() => { - this.showNotifications(true, false, true, { - field: field.toString(), - }); - }) - ); + return this.metadataFieldService.create(field, new RequestParam('schemaId', schema.id)).pipe( + getFirstSucceededRemoteDataPayload(), + hasValueOperator(), + tap(() => { + this.showNotifications(true, false, true, { field: field.toString() }); + }) + ); } /** @@ -386,23 +321,13 @@ export class RegistryService { this.metadataFieldService.clearRequests(); } - private showNotifications( - success: boolean, - edited: boolean, - isField: boolean, - options: any - ) { + private showNotifications(success: boolean, edited: boolean, isField: boolean, options: any) { const prefix = 'admin.registries.schema.notification'; const suffix = success ? 'success' : 'failure'; const editedString = edited ? 'edited' : 'created'; const messages = observableCombineLatest( - this.translateService.get( - success ? `${prefix}.${suffix}` : `${prefix}.${suffix}` - ), - this.translateService.get( - `${prefix}${isField ? '.field' : ''}.${editedString}`, - options - ) + this.translateService.get(success ? `${prefix}.${suffix}` : `${prefix}.${suffix}`), + this.translateService.get(`${prefix}${isField ? '.field' : ''}.${editedString}`, options) ); messages.subscribe(([head, content]) => { if (success) { @@ -427,23 +352,7 @@ export class RegistryService { * {@link HALLink}s should be automatically resolved * @returns an observable that emits a remote data object with a page of metadata fields that match the query */ - queryMetadataFields( - query: string, - options: FindListOptions = {}, - useCachedVersionIfAvailable = true, - reRequestOnStale = true, - ...linksToFollow: FollowLinkConfig[] - ): Observable>> { - return this.metadataFieldService.searchByFieldNameParams( - null, - null, - null, - query, - null, - options, - useCachedVersionIfAvailable, - reRequestOnStale, - ...linksToFollow - ); + queryMetadataFields(query: string, options: FindListOptions = {}, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig[]): Observable>> { + return this.metadataFieldService.searchByFieldNameParams(null, null, null, query, null, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); } } diff --git a/src/app/item-page/simple/item-page.component.spec.ts b/src/app/item-page/simple/item-page.component.spec.ts index 7db6cd7148a..15d3a29fad5 100644 --- a/src/app/item-page/simple/item-page.component.spec.ts +++ b/src/app/item-page/simple/item-page.component.spec.ts @@ -12,12 +12,12 @@ import { Item } from '../../core/shared/item.model'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { By } from '@angular/platform-browser'; import { createRelationshipsObservable } from './item-types/shared/item.component.spec'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { createFailedRemoteDataObject$, createPendingRemoteDataObject$, createSuccessfulRemoteDataObject, - createSuccessfulRemoteDataObject$, + createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { AuthService } from '../../core/auth/auth.service'; import { createPaginatedList } from '../../shared/testing/utils.test'; @@ -33,7 +33,7 @@ import { getMockTranslateService } from 'src/app/shared/mocks/translate.service. const mockItem: Item = Object.assign(new Item(), { bundles: createSuccessfulRemoteDataObject$(createPaginatedList([])), metadata: [], - relationships: createRelationshipsObservable(), + relationships: createRelationshipsObservable() }); const mockWithdrawnItem: Item = Object.assign(new Item(), { @@ -61,17 +61,17 @@ describe('ItemPageComponent', () => { /* eslint-enable no-empty, @typescript-eslint/no-empty-function */ }; const mockRoute = Object.assign(new ActivatedRouteStub(), { - data: observableOf({ dso: createSuccessfulRemoteDataObject(mockItem) }), + data: observableOf({ dso: createSuccessfulRemoteDataObject(mockItem) }) }); const mockMetadataBitstreamDataService = { - searchByHandleParams: () => of({}) // Returns a mock Observable + searchByHandleParams: () => observableOf({}) // Returns a mock Observable }; beforeEach(waitForAsync(() => { authService = jasmine.createSpyObj('authService', { isAuthenticated: observableOf(true), - setRedirectUrl: {}, + setRedirectUrl: {} }); translateService = getMockTranslateService(); @@ -80,15 +80,12 @@ describe('ItemPageComponent', () => { }); TestBed.configureTestingModule({ - imports: [ - TranslateModule.forRoot({ - loader: { - provide: TranslateLoader, - useClass: TranslateLoaderMock, - }, - }), - BrowserAnimationsModule, - ], + imports: [TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock + } + }), BrowserAnimationsModule], declarations: [ItemPageComponent, VarDirective], providers: [ { provide: ActivatedRoute, useValue: mockRoute }, @@ -106,12 +103,10 @@ describe('ItemPageComponent', () => { { provide: AuthorizationDataService, useValue: authorizationDataService }, ], - schemas: [NO_ERRORS_SCHEMA], - }) - .overrideComponent(ItemPageComponent, { - set: { changeDetection: ChangeDetectionStrategy.Default }, - }) - .compileComponents(); + schemas: [NO_ERRORS_SCHEMA] + }).overrideComponent(ItemPageComponent, { + set: { changeDetection: ChangeDetectionStrategy.Default } + }).compileComponents(); })); beforeEach(waitForAsync(() => { diff --git a/src/app/item-page/simple/item-page.component.ts b/src/app/item-page/simple/item-page.component.ts index d52ed7c410e..c42c2ccb821 100644 --- a/src/app/item-page/simple/item-page.component.ts +++ b/src/app/item-page/simple/item-page.component.ts @@ -31,7 +31,7 @@ import { Observable } from 'rxjs'; styleUrls: ['./item-page.component.scss'], templateUrl: './item-page.component.html', changeDetection: ChangeDetectionStrategy.OnPush, - animations: [fadeInOut], + animations: [fadeInOut] }) export class ItemPageComponent implements OnInit { /** @@ -107,7 +107,8 @@ export class ItemPageComponent implements OnInit { private authService: AuthService, private authorizationService: AuthorizationDataService, protected registryService: RegistryService - ) {} + ) { + } /** * Initialize instance variables @@ -169,8 +170,9 @@ export class ItemPageComponent implements OnInit { let isReplaced = ''; // load values from item - this.itemRD$ - .pipe(take(1), getAllSucceededRemoteDataPayload()) + this.itemRD$.pipe( + take(1), + getAllSucceededRemoteDataPayload()) .subscribe((item: Item) => { this.itemHandle = item.handle; isWithdrawn = item.isWithdrawn; @@ -184,10 +186,8 @@ export class ItemPageComponent implements OnInit { // for users navigate to the custom tombstone // for admin stay on the item page with tombstone flag - this.isAdmin$ = this.authorizationService.isAuthorized( - FeatureID.AdministratorOf - ); - this.isAdmin$.subscribe((isAdmin) => { + this.isAdmin$ = this.authorizationService.isAuthorized(FeatureID.AdministratorOf); + this.isAdmin$.subscribe(isAdmin => { // do not show tombstone for admin but show it for users if (!isAdmin) { if (isNotEmpty(isReplaced)) { diff --git a/src/app/item-page/simple/item-types/shared/item-relationships-utils.ts b/src/app/item-page/simple/item-types/shared/item-relationships-utils.ts index 33a97493358..b4c3da2cdc3 100644 --- a/src/app/item-page/simple/item-types/shared/item-relationships-utils.ts +++ b/src/app/item-page/simple/item-types/shared/item-relationships-utils.ts @@ -1,8 +1,4 @@ -import { - combineLatest as observableCombineLatest, - Observable, - zip as observableZip, -} from 'rxjs'; +import { combineLatest as observableCombineLatest, Observable, zip as observableZip } from 'rxjs'; import { distinctUntilChanged, map, mergeMap, switchMap } from 'rxjs/operators'; import { PaginatedList } from '../../../../core/data/paginated-list.model'; import { RemoteData } from '../../../../core/data/remote-data'; @@ -10,20 +6,14 @@ import { Relationship } from '../../../../core/shared/item-relationships/relatio import { Item } from '../../../../core/shared/item.model'; import { getFirstSucceededRemoteDataPayload, - getFirstSucceededRemoteData, + getFirstSucceededRemoteData } from '../../../../core/shared/operators'; import { hasValue } from '../../../../shared/empty.util'; import { InjectionToken } from '@angular/core'; -export const PAGINATED_RELATIONS_TO_ITEMS_OPERATOR = new InjectionToken< - ( - thisId: string - ) => ( - source: Observable>> - ) => Observable>> ->('paginatedRelationsToItems', { +export const PAGINATED_RELATIONS_TO_ITEMS_OPERATOR = new InjectionToken<(thisId: string) => (source: Observable>>) => Observable>>>('paginatedRelationsToItems', { providedIn: 'root', - factory: () => paginatedRelationsToItems, + factory: () => paginatedRelationsToItems }); /** @@ -33,51 +23,42 @@ export const PAGINATED_RELATIONS_TO_ITEMS_OPERATOR = new InjectionToken< * For example: "(o) => o.id" will compare the two arrays by comparing their content by id. * @param mapFn Function for mapping the arrays */ -export const compareArraysUsing = - (mapFn: (t: T) => any) => +export const compareArraysUsing = (mapFn: (t: T) => any) => (a: T[], b: T[]): boolean => { - if (!Array.isArray(a) || !Array.isArray(b)) { + if (!Array.isArray(a) || ! Array.isArray(b)) { return false; } const aIds = a.map(mapFn); const bIds = b.map(mapFn); - return ( - aIds.length === bIds.length && + return aIds.length === bIds.length && aIds.every((e) => bIds.includes(e)) && - bIds.every((e) => aIds.includes(e)) - ); + bIds.every((e) => aIds.includes(e)); }; /** * Operator for comparing arrays using the object's ids */ export const compareArraysUsingIds = () => - compareArraysUsing((t: T) => (hasValue(t) ? t.id : undefined)); + compareArraysUsing((t: T) => hasValue(t) ? t.id : undefined); /** * Operator for turning a list of relationships into a list of the relevant items * @param {string} thisId The item's id of which the relations belong to * @returns {(source: Observable) => Observable} */ -export const relationsToItems = - (thisId: string) => +export const relationsToItems = (thisId: string) => (source: Observable): Observable => source.pipe( mergeMap((rels: Relationship[]) => observableZip( - ...rels.map((rel: Relationship) => - observableCombineLatest(rel.leftItem, rel.rightItem) - ) + ...rels.map((rel: Relationship) => observableCombineLatest(rel.leftItem, rel.rightItem)) ) ), map((arr) => arr - .filter( - ([leftItem, rightItem]) => - leftItem.hasSucceeded && rightItem.hasSucceeded - ) + .filter(([leftItem, rightItem]) => leftItem.hasSucceeded && rightItem.hasSucceeded) .map(([leftItem, rightItem]) => { if (leftItem.payload.id === thisId) { return rightItem.payload; @@ -87,7 +68,7 @@ export const relationsToItems = }) .filter((item: Item) => hasValue(item)) ), - distinctUntilChanged(compareArraysUsingIds()) + distinctUntilChanged(compareArraysUsingIds()), ); /** @@ -96,11 +77,8 @@ export const relationsToItems = * @param {string} thisId The item's id of which the relations belong to * @returns {(source: Observable) => Observable} */ -export const paginatedRelationsToItems = - (thisId: string) => - ( - source: Observable>> - ): Observable>> => +export const paginatedRelationsToItems = (thisId: string) => + (source: Observable>>): Observable>> => source.pipe( getFirstSucceededRemoteData(), switchMap((relationshipsRD: RemoteData>) => { @@ -108,10 +86,9 @@ export const paginatedRelationsToItems = relationshipsRD.payload.page.map((rel: Relationship) => observableCombineLatest([ rel.leftItem.pipe(getFirstSucceededRemoteDataPayload()), - rel.rightItem.pipe(getFirstSucceededRemoteDataPayload()), - ]) - ) - ).pipe( + rel.rightItem.pipe(getFirstSucceededRemoteDataPayload())] + ) + )).pipe( map((arr) => arr .map(([leftItem, rightItem]) => { @@ -125,11 +102,7 @@ export const paginatedRelationsToItems = ), distinctUntilChanged(compareArraysUsingIds()), map((relatedItems: Item[]) => - Object.assign(relationshipsRD, { - payload: Object.assign(relationshipsRD.payload, { - page: relatedItems, - }), - }) + Object.assign(relationshipsRD, { payload: Object.assign(relationshipsRD.payload, { page: relatedItems } )}) ) ); }) diff --git a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html index 1b42e8c3257..ae2cde511d6 100644 --- a/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html +++ b/src/app/item-page/simple/item-types/untyped-item/untyped-item.component.html @@ -105,6 +105,5 @@ [iconName]="'fa-paperclip'" [separator]="'
        '"> -
    • From a720ac877402854ca19611cec5a5ad72dd2e0c18 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Wed, 27 Sep 2023 16:29:17 +0200 Subject: [PATCH 15/26] Refactoring and removed font awesome loading from node modules --- angular.json | 1 - src/app/item-page/item-page.module.ts | 14 ++++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/angular.json b/angular.json index 1afce4bb954..d828887b214 100644 --- a/angular.json +++ b/angular.json @@ -46,7 +46,6 @@ "styles": [ "src/styles/startup.scss", "src/aai/discojuice/discojuice.css", - "node_modules/font-awesome/css/font-awesome.css", "node_modules/bootstrap/dist/css/bootstrap.min.css", { "input": "src/styles/base-theme.scss", diff --git a/src/app/item-page/item-page.module.ts b/src/app/item-page/item-page.module.ts index 1c6174bca18..6e87e4594a9 100644 --- a/src/app/item-page/item-page.module.ts +++ b/src/app/item-page/item-page.module.ts @@ -82,7 +82,7 @@ import { const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator PublicationComponent, - UntypedItemComponent, + UntypedItemComponent ]; const DECLARATIONS = [ @@ -154,8 +154,13 @@ const DECLARATIONS = [ ChartsModule, NgbModule ], - declarations: [...DECLARATIONS], - exports: [...DECLARATIONS], + declarations: [ + ...DECLARATIONS, + + ], + exports: [ + ...DECLARATIONS + ] }) export class ItemPageModule { /** @@ -165,7 +170,8 @@ export class ItemPageModule { static withEntryComponents() { return { ngModule: ItemPageModule, - providers: ENTRY_COMPONENTS.map((component) => ({ provide: component })), + providers: ENTRY_COMPONENTS.map((component) => ({provide: component})) }; } + } From 23835f4987cd04fbb7d7f493c212247a5e7364d3 Mon Sep 17 00:00:00 2001 From: milanmajchrak Date: Thu, 28 Sep 2023 10:12:24 +0200 Subject: [PATCH 16/26] Updated preview file box look and feel --- .../file-description.component.html | 54 +++++++++---------- .../file-description.component.scss | 14 ++++- .../preview-section.component.html | 2 +- .../preview-section.component.scss | 11 ++-- .../item-page/simple/item-page.component.html | 2 +- 5 files changed, 48 insertions(+), 35 deletions(-) diff --git a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html index 0fb29830901..13e04fa8430 100644 --- a/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html +++ b/src/app/item-page/simple/field-components/preview-section/file-description/file-description.component.html @@ -1,4 +1,4 @@ -
      +
       File Preview
    • - {{ node.name }}{{ node.size }} + + {{ node.name }} + {{ node.size }}