Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ufal/fe-22-54-download-preview-item #362

Merged
merged 28 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4c89209
create new component and add model file and service file
HuynhKhoa1601 Jul 12, 2023
65290d8
build the user interface and calling the api from backend
HuynhKhoa1601 Jul 13, 2023
e794918
add logic for handling data from BE and refactor the UI
HuynhKhoa1601 Jul 14, 2023
e3df2d3
fix the lint error and fix the collapse/hide behaviour
HuynhKhoa1601 Jul 17, 2023
060bf51
add UI for download buttons and fix UI for the ZIP Preview
HuynhKhoa1601 Jul 18, 2023
a537c05
getting data from backend and make the download feature
HuynhKhoa1601 Jul 19, 2023
bafb92b
handle with the dynamic input
HuynhKhoa1601 Jul 21, 2023
af88da9
fix the collapese/hide behaviour and handle more cases
HuynhKhoa1601 Jul 24, 2023
52a07b2
add more conditions for checking permission to preview and download f…
HuynhKhoa1601 Jul 26, 2023
9ddbb6e
fix lint error
HuynhKhoa1601 Jul 26, 2023
395db4e
fix failed test
HuynhKhoa1601 Jul 27, 2023
a868331
Lock/download preview (#311)
milanmajchrak Sep 27, 2023
d12d397
Merge branch 'ufal/fe-22-54-download-preview-item' of github.com:data…
milanmajchrak Sep 27, 2023
dfde4a8
Resolved conflicts
milanmajchrak Sep 27, 2023
9c9149f
Resolved conflicts
milanmajchrak Sep 27, 2023
94b62af
Revert unnecessary changes
milanmajchrak Sep 27, 2023
a720ac8
Refactoring and removed font awesome loading from node modules
milanmajchrak Sep 27, 2023
23835f4
Updated preview file box look and feel
milanmajchrak Sep 28, 2023
1fc1509
Fixed file preview icons
milanmajchrak Sep 28, 2023
32190b5
Fixed html preview scrolling
milanmajchrak Sep 28, 2023
70f0120
Show scrollbar in txt preview
milanmajchrak Sep 29, 2023
6109d40
Some refactoring
milanmajchrak Oct 2, 2023
f964a4c
Refactoring and the dspace BE is loaded from configuration property.
milanmajchrak Oct 3, 2023
48017e8
Added messages
milanmajchrak Oct 3, 2023
bb18eb9
Fixed tests
milanmajchrak Oct 4, 2023
af3c35e
Added download buttons and fixed downloading
milanmajchrak Oct 4, 2023
b8081c2
Added messages
milanmajchrak Oct 4, 2023
54863ec
Added image to the assetstore instead of url from lindat
milanmajchrak Oct 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/app/core/core.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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';
Expand Down Expand Up @@ -298,6 +300,7 @@ const PROVIDERS = [
SiteRegisterGuard,
MetadataSchemaDataService,
MetadataFieldDataService,
MetadataBitstreamDataService,
TokenResponseParsingService,
ReloadGuard,
EndUserAgreementCurrentUserGuard,
Expand Down Expand Up @@ -341,6 +344,7 @@ export const models =
ResourcePolicy,
MetadataSchema,
MetadataField,
MetadataBitstream,
License,
WorkflowItem,
WorkspaceItem,
Expand Down
76 changes: 76 additions & 0 deletions src/app/core/data/metadata-bitstream-data.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { Injectable } from '@angular/core';
import { hasValue } from '../../shared/empty.util';
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 { NotificationsService } from '../../shared/notifications/notifications.service';
import { ObjectCacheService } from '../cache/object-cache.service';
import { METADATA_BITSTREAM } from '../metadata/metadata-bitstream.resource-type';
import { MetadataBitstream } from '../metadata/metadata-bitstream.model';
import { HttpClient } from '@angular/common/http';
import { Store } from '@ngrx/store';
import { ChangeAnalyzer } from './change-analyzer';
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 IdentifiableDataService<MetadataBitstream> implements SearchData<MetadataBitstream> {
protected store: Store<CoreState>;
protected http: HttpClient;
protected comparator: ChangeAnalyzer<MetadataBitstream>;
protected linkPath = 'metadatabitstreams';
protected searchByHandleLinkPath = 'byHandle';
private searchData: SearchData<MetadataBitstream>;

constructor(
protected requestService: RequestService,
protected rdbService: RemoteDataBuildService,
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
protected notificationsService: NotificationsService
) {
super(linkName, requestService, rdbService, objectCache, halService, undefined);
this.searchData = new SearchDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive);
}

/**
* 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<any>[]): Observable<RemoteData<any>> {
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);
}

searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<MetadataBitstream>[]): Observable<RemoteData<PaginatedList<MetadataBitstream>>> {
return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
}
}
12 changes: 12 additions & 0 deletions src/app/core/metadata/file-info.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { autoserialize, autoserializeAs } from 'cerialize';

/**
* This class is used to store the information about a file or a directory
*/
export class FileInfo {
@autoserialize name: string;
@autoserialize content: any;
@autoserialize size: string;
@autoserialize isDirectory: boolean;
@autoserializeAs('sub') sub: { [key: string]: FileInfo };
}
97 changes: 97 additions & 0 deletions src/app/core/metadata/metadata-bitstream.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import {
autoserialize,
autoserializeAs,
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';
import { FileInfo } from './file-info.model';

/**
* 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<ListableObject>)[] {
return [this.constructor as GenericConstructor<ListableObject>];
}
}
export { FileInfo };

9 changes: 9 additions & 0 deletions src/app/core/metadata/metadata-bitstream.resource-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
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');
14 changes: 13 additions & 1 deletion src/app/core/registry/registry.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -30,6 +30,7 @@ import { createPaginatedList } from '../../shared/testing/utils.test';
import { RemoteData } from '../data/remote-data';
import { NoContent } from '../shared/NoContent.model';
import { FindListOptions } from '../data/find-list-options.model';
import { MetadataBitstreamDataService } from '../data/metadata-bitstream-data.service';

@Component({ template: '' })
class DummyComponent {
Expand All @@ -40,6 +41,7 @@ describe('RegistryService', () => {
let mockStore;
let metadataSchemaService: MetadataSchemaDataService;
let metadataFieldService: MetadataFieldDataService;
let metadataBitstreamDataService: MetadataBitstreamDataService;

let options: FindListOptions;
let mockSchemasList: MetadataSchema[];
Expand Down Expand Up @@ -139,6 +141,14 @@ describe('RegistryService', () => {
delete: createNoContentRemoteDataObject$(),
clearRequests: observableOf('href')
});
metadataBitstreamDataService = jasmine.createSpyObj(
'metadataBitstreamDataService',
{
searchByHandleParams: of({
/* Your Mock Data */
}),
}
);
}

beforeEach(() => {
Expand All @@ -153,6 +163,8 @@ describe('RegistryService', () => {
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
{ provide: MetadataSchemaDataService, useValue: metadataSchemaService },
{ provide: MetadataFieldDataService, useValue: metadataFieldService },
{ provide: MetadataFieldDataService, useValue: metadataFieldService },
{ provide: MetadataBitstreamDataService, useValue: metadataBitstreamDataService },
RegistryService
]
});
Expand Down
22 changes: 20 additions & 2 deletions src/app/core/registry/registry.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ 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);
Expand All @@ -42,12 +44,12 @@ const selectedMetadataFieldsSelector = createSelector(metadataRegistryStateSelec
*/
@Injectable()
export class RegistryService {

constructor(private store: Store<AppState>,
private notificationsService: NotificationsService,
private translateService: TranslateService,
private metadataSchemaService: MetadataSchemaDataService,
private metadataFieldService: MetadataFieldDataService) {
private metadataFieldService: MetadataFieldDataService,
private metadataBitstreamDataService: MetadataBitstreamDataService) {

}

Expand Down Expand Up @@ -104,6 +106,22 @@ 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<MetadataBitstream>[]): Observable<RemoteData<any>> {
return this.metadataBitstreamDataService.searchByHandleParams(handle, fileGrpType, options,
useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
}

public editMetadataSchema(schema: MetadataSchema) {
this.store.dispatch(new MetadataRegistryEditSchemaAction(schema));
}
Expand Down
1 change: 0 additions & 1 deletion src/app/core/shared/clarin/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@ export const DOWNLOAD_TOKEN_EXPIRED_EXCEPTION = 'DownloadTokenExpiredException';
export const HTTP_STATUS_UNAUTHORIZED = 401;
export const USER_WITHOUT_EMAIL_EXCEPTION = 'UserWithoutEmailException';
export const MISSING_HEADERS_FROM_IDP_EXCEPTION = 'MissingHeadersFromIpd';

Loading
Loading