Merge pull request #2761 from ybnd/fix-versioning-button

Fix caching issues for versioning
This commit is contained in:
Tim Donohue
2024-05-30 16:55:17 -05:00
committed by GitHub
22 changed files with 166 additions and 100 deletions

View File

@@ -5,10 +5,7 @@
*
* http://www.dspace.org/license/
*/
import {
Observable,
of as observableOf,
} from 'rxjs';
import { of as observableOf } from 'rxjs';
import { TestScheduler } from 'rxjs/testing';
import { getMockRemoteDataBuildService } from '../../../shared/mocks/remote-data-build.service.mock';
@@ -18,14 +15,14 @@ import { followLink } from '../../../shared/utils/follow-link-config.model';
import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../../cache/object-cache.service';
import { HALEndpointService } from '../../shared/hal-endpoint.service';
import { FindListOptions } from '../find-list-options.model';
import { RemoteData } from '../remote-data';
import { RequestService } from '../request.service';
import { RequestEntryState } from '../request-entry-state.model';
import { EMBED_SEPARATOR } from './base-data.service';
import { IdentifiableDataService } from './identifiable-data.service';
const endpoint = 'https://rest.api/core';
const base = 'https://rest.api/core';
const endpoint = 'test';
class TestService extends IdentifiableDataService<any> {
constructor(
@@ -34,11 +31,7 @@ class TestService extends IdentifiableDataService<any> {
protected objectCache: ObjectCacheService,
protected halService: HALEndpointService,
) {
super(undefined, requestService, rdbService, objectCache, halService);
}
public getBrowseEndpoint(options: FindListOptions = {}, linkPath: string = this.linkPath): Observable<string> {
return observableOf(endpoint);
super(endpoint, requestService, rdbService, objectCache, halService);
}
}
@@ -55,7 +48,7 @@ describe('IdentifiableDataService', () => {
function initTestService(): TestService {
requestService = getMockRequestService();
halService = new HALEndpointServiceStub('url') as any;
halService = new HALEndpointServiceStub(base) as any;
rdbService = getMockRemoteDataBuildService();
objectCache = {
@@ -147,4 +140,12 @@ describe('IdentifiableDataService', () => {
expect(result).toEqual(expected);
});
});
describe('invalidateById', () => {
it('should invalidate the correct resource by href', () => {
spyOn(service, 'invalidateByHref').and.returnValue(observableOf(true));
service.invalidateById('123');
expect(service.invalidateByHref).toHaveBeenCalledWith(`${base}/${endpoint}/123`);
});
});
});

View File

@@ -6,7 +6,11 @@
* http://www.dspace.org/license/
*/
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import {
map,
switchMap,
take,
} from 'rxjs/operators';
import { FollowLinkConfig } from '../../../shared/utils/follow-link-config.model';
import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service';
@@ -81,4 +85,19 @@ export class IdentifiableDataService<T extends CacheableObject> extends BaseData
return this.getEndpoint().pipe(
map((endpoint: string) => this.getIDHref(endpoint, resourceID, ...linksToFollow)));
}
/**
* Invalidate a cached resource by its identifier
* @param resourceID the identifier of the resource to invalidate
*/
invalidateById(resourceID: string): Observable<boolean> {
const ok$ = this.getIDHrefObs(resourceID).pipe(
take(1),
switchMap((href) => this.invalidateByHref(href)),
);
ok$.subscribe();
return ok$;
}
}

View File

@@ -69,6 +69,10 @@ describe('VersionHistoryDataService', () => {
},
},
});
const version1WithDraft = Object.assign(new Version(), {
...version1,
versionhistory: createSuccessfulRemoteDataObject$(versionHistoryDraft),
});
const versions = [version1, version2];
versionHistory.versions = createSuccessfulRemoteDataObject$(createPaginatedList(versions));
const item1 = Object.assign(new Item(), {
@@ -190,21 +194,18 @@ describe('VersionHistoryDataService', () => {
});
describe('hasDraftVersion$', () => {
beforeEach(waitForAsync(() => {
versionService.findByHref.and.returnValue(createSuccessfulRemoteDataObject$<Version>(version1));
}));
it('should return false if draftVersion is false', fakeAsync(() => {
versionService.getHistoryFromVersion.and.returnValue(of(versionHistory));
versionService.findByHref.and.returnValue(createSuccessfulRemoteDataObject$<Version>(version1));
service.hasDraftVersion$('href').subscribe((res) => {
expect(res).toBeFalse();
});
}));
it('should return true if draftVersion is true', fakeAsync(() => {
versionService.getHistoryFromVersion.and.returnValue(of(versionHistoryDraft));
versionService.findByHref.and.returnValue(createSuccessfulRemoteDataObject$<Version>(version1WithDraft));
service.hasDraftVersion$('href').subscribe((res) => {
expect(res).toBeTrue();
});
}));
});
});

View File

@@ -1,17 +1,22 @@
import { HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import {
combineLatest,
Observable,
of,
of as observableOf,
} from 'rxjs';
import {
filter,
find,
map,
switchMap,
take,
} from 'rxjs/operators';
import { hasValueOperator } from '../../shared/empty.util';
import {
hasValue,
hasValueOperator,
} from '../../shared/empty.util';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model';
import {
@@ -29,7 +34,6 @@ import {
getFirstSucceededRemoteDataPayload,
getRemoteDataPayload,
} from '../shared/operators';
import { sendRequest } from '../shared/request.operators';
import { Version } from '../shared/version.model';
import { VersionHistory } from '../shared/version-history.model';
import { IdentifiableDataService } from './base/identifiable-data.service';
@@ -38,7 +42,6 @@ import { PaginatedList } from './paginated-list.model';
import { RemoteData } from './remote-data';
import { PostRequest } from './request.models';
import { RequestService } from './request.service';
import { RestRequest } from './rest-request.model';
import { VersionDataService } from './version-data.service';
/**
@@ -100,19 +103,31 @@ export class VersionHistoryDataService extends IdentifiableDataService<VersionHi
* @param summary the summary of the new version
*/
createVersion(itemHref: string, summary: string): Observable<RemoteData<Version>> {
const requestId = this.requestService.generateRequestId();
const requestOptions: HttpOptions = Object.create({});
let requestHeaders = new HttpHeaders();
requestHeaders = requestHeaders.append('Content-Type', 'text/uri-list');
requestOptions.headers = requestHeaders;
return this.halService.getEndpoint(this.versionsEndpoint).pipe(
this.halService.getEndpoint(this.versionsEndpoint).pipe(
take(1),
map((endpointUrl: string) => (summary?.length > 0) ? `${endpointUrl}?summary=${summary}` : `${endpointUrl}`),
map((endpointURL: string) => new PostRequest(this.requestService.generateRequestId(), endpointURL, itemHref, requestOptions)),
sendRequest(this.requestService),
switchMap((restRequest: RestRequest) => this.rdbService.buildFromRequestUUID(restRequest.uuid)),
find((href: string) => hasValue(href)),
).subscribe((href) => {
const request = new PostRequest(requestId, href, itemHref, requestOptions);
if (hasValue(this.responseMsToLive)) {
request.responseMsToLive = this.responseMsToLive;
}
this.requestService.send(request);
});
return this.rdbService.buildFromRequestUUIDAndAwait<Version>(requestId, (versionRD) => combineLatest([
this.requestService.setStaleByHrefSubstring(versionRD.payload._links.self.href),
this.requestService.setStaleByHrefSubstring(versionRD.payload._links.versionhistory.href),
])).pipe(
getFirstCompletedRemoteData(),
) as Observable<RemoteData<Version>>;
);
}
/**
@@ -151,7 +166,7 @@ export class VersionHistoryDataService extends IdentifiableDataService<VersionHi
switchMap((res) => res.versionhistory),
getFirstSucceededRemoteDataPayload(),
switchMap((versionHistoryRD) => this.getLatestVersionFromHistory$(versionHistoryRD)),
) : of(null);
) : observableOf(null);
}
/**
@@ -162,8 +177,8 @@ export class VersionHistoryDataService extends IdentifiableDataService<VersionHi
isLatest$(version: Version): Observable<boolean> {
return version ? this.getLatestVersion$(version).pipe(
take(1),
switchMap((latestVersion) => of(version.version === latestVersion.version)),
) : of(null);
switchMap((latestVersion) => observableOf(version.version === latestVersion.version)),
) : observableOf(null);
}
/**
@@ -172,17 +187,22 @@ export class VersionHistoryDataService extends IdentifiableDataService<VersionHi
* @returns `true` if a workspace item exists, `false` otherwise, or `null` if a version history does not exist
*/
hasDraftVersion$(versionHref: string): Observable<boolean> {
return this.versionDataService.findByHref(versionHref, true, true, followLink('versionhistory')).pipe(
return this.versionDataService.findByHref(versionHref, false, true, followLink('versionhistory')).pipe(
getFirstCompletedRemoteData(),
switchMap((res) => {
if (res.hasSucceeded && !res.hasNoContent) {
return of(res).pipe(
getFirstSucceededRemoteDataPayload(),
switchMap((version) => this.versionDataService.getHistoryFromVersion(version)),
map((versionHistory) => versionHistory ? versionHistory.draftVersion : false),
switchMap((versionRD: RemoteData<Version>) => {
if (versionRD.hasSucceeded && !versionRD.hasNoContent) {
return versionRD.payload.versionhistory.pipe(
getFirstCompletedRemoteData(),
map((versionHistoryRD: RemoteData<VersionHistory>) => {
if (versionHistoryRD.hasSucceeded && !versionHistoryRD.hasNoContent) {
return versionHistoryRD.payload.draftVersion;
} else {
return false;
}
}),
);
} else {
return of(false);
return observableOf(false);
}
}),
);

View File

@@ -29,14 +29,12 @@ import { HALEndpointService } from '../shared/hal-endpoint.service';
import { NoContent } from '../shared/NoContent.model';
import { getFirstCompletedRemoteData } from '../shared/operators';
import { WorkflowItem } from './models/workflowitem.model';
import { WorkspaceItem } from './models/workspaceitem.model';
/**
* A service that provides methods to make REST requests with workflow items endpoint.
*/
@Injectable({ providedIn: 'root' })
export class WorkflowItemDataService extends IdentifiableDataService<WorkflowItem> implements SearchData<WorkflowItem>, DeleteData<WorkflowItem> {
protected linkPath = 'workflowitems';
protected searchByItemLinkPath = 'item';
protected responseMsToLive = 10 * 1000;
@@ -50,7 +48,7 @@ export class WorkflowItemDataService extends IdentifiableDataService<WorkflowIte
protected halService: HALEndpointService,
protected notificationsService: NotificationsService,
) {
super('workspaceitems', requestService, rdbService, objectCache, halService);
super('workflowitems', requestService, rdbService, objectCache, halService);
this.searchData = new SearchDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive);
this.deleteData = new DeleteDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, notificationsService, this.responseMsToLive, this.constructIdEndpoint);
@@ -113,7 +111,7 @@ export class WorkflowItemDataService extends IdentifiableDataService<WorkflowIte
* @param options The {@link FindListOptions} object
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public findByItem(uuid: string, useCachedVersionIfAvailable = false, reRequestOnStale = true, options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig<WorkspaceItem>[]): Observable<RemoteData<WorkspaceItem>> {
public findByItem(uuid: string, useCachedVersionIfAvailable = false, reRequestOnStale = true, options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig<WorkflowItem>[]): Observable<RemoteData<WorkflowItem>> {
const findListOptions = new FindListOptions();
findListOptions.searchParams = [new RequestParam('uuid', uuid)];
const href$ = this.searchData.getSearchByHref(this.searchByItemLinkPath, findListOptions, ...linksToFollow);
@@ -134,7 +132,7 @@ export class WorkflowItemDataService extends IdentifiableDataService<WorkflowIte
* @return {Observable<RemoteData<PaginatedList<T>>}
* Return an observable that emits response from the server
*/
public searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<WorkspaceItem>[]): Observable<RemoteData<PaginatedList<WorkspaceItem>>> {
public searchBy(searchMethod: string, options?: FindListOptions, useCachedVersionIfAvailable?: boolean, reRequestOnStale?: boolean, ...linksToFollow: FollowLinkConfig<WorkflowItem>[]): Observable<RemoteData<PaginatedList<WorkflowItem>>> {
return this.searchData.searchBy(searchMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
}

View File

@@ -7,7 +7,6 @@ import {
} from 'rxjs';
import {
map,
startWith,
switchMap,
tap,
} from 'rxjs/operators';
@@ -96,7 +95,6 @@ export class DsoVersioningModalService {
// button is disabled if hasDraftVersion = true, and enabled if hasDraftVersion = false or null
// (hasDraftVersion is null when a version history does not exist)
map((res) => Boolean(res)),
startWith(true),
);
}

View File

@@ -14,13 +14,11 @@ import {
TranslateLoader,
TranslateModule,
} from '@ngx-translate/core';
import {
of as observableOf,
of,
} from 'rxjs';
import { of as observableOf } from 'rxjs';
import { RequestService } from '../../../../core/data/request.service';
import { SearchService } from '../../../../core/shared/search/search.service';
import { WorkflowItemDataService } from '../../../../core/submission/workflowitem-data.service';
import { ClaimedTaskDataService } from '../../../../core/tasks/claimed-task-data.service';
import { ClaimedTask } from '../../../../core/tasks/models/claimed-task-object.model';
import { ProcessTaskResponse } from '../../../../core/tasks/models/process-task-response';
@@ -41,6 +39,7 @@ const searchService = getMockSearchService();
const requestService = getMockRequestService();
let mockPoolTaskDataService: PoolTaskDataService;
let mockWorkflowItemDataService: WorkflowItemDataService;
describe('ClaimedTaskActionsApproveComponent', () => {
const object = Object.assign(new ClaimedTask(), { id: 'claimed-task-1' });
@@ -50,6 +49,10 @@ describe('ClaimedTaskActionsApproveComponent', () => {
beforeEach(waitForAsync(() => {
mockPoolTaskDataService = new PoolTaskDataService(null, null, null, null);
mockWorkflowItemDataService = jasmine.createSpyObj('WorkflowItemDataService', {
'invalidateByHref': observableOf(false),
});
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot({
@@ -68,6 +71,7 @@ describe('ClaimedTaskActionsApproveComponent', () => {
{ provide: SearchService, useValue: searchService },
{ provide: RequestService, useValue: requestService },
{ provide: PoolTaskDataService, useValue: mockPoolTaskDataService },
{ provide: WorkflowItemDataService, useValue: mockWorkflowItemDataService },
],
schemas: [NO_ERRORS_SCHEMA],
}).overrideComponent(ClaimedTaskActionsApproveComponent, {
@@ -103,7 +107,7 @@ describe('ClaimedTaskActionsApproveComponent', () => {
beforeEach(() => {
spyOn(component.processCompleted, 'emit');
spyOn(component, 'startActionExecution').and.returnValue(of(null));
spyOn(component, 'startActionExecution').and.returnValue(observableOf(null));
expectedBody = {
[component.option]: 'true',

View File

@@ -21,6 +21,7 @@ import { RemoteData } from '../../../../core/data/remote-data';
import { RequestService } from '../../../../core/data/request.service';
import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
import { SearchService } from '../../../../core/shared/search/search.service';
import { WorkflowItemDataService } from '../../../../core/submission/workflowitem-data.service';
import { NotificationsService } from '../../../notifications/notifications.service';
import { ClaimedApprovedTaskSearchResult } from '../../../object-collection/shared/claimed-approved-task-search-result.model';
import { ClaimedTaskActionsAbstractComponent } from '../abstract/claimed-task-actions-abstract.component';
@@ -43,12 +44,15 @@ export class ClaimedTaskActionsApproveComponent extends ClaimedTaskActionsAbstra
*/
option = WORKFLOW_TASK_OPTION_APPROVE;
constructor(protected injector: Injector,
constructor(
protected injector: Injector,
protected router: Router,
protected notificationsService: NotificationsService,
protected translate: TranslateService,
protected searchService: SearchService,
protected requestService: RequestService) {
protected requestService: RequestService,
protected workflowItemDataService: WorkflowItemDataService,
) {
super(injector, router, notificationsService, translate, searchService, requestService);
}
@@ -63,4 +67,13 @@ export class ClaimedTaskActionsApproveComponent extends ClaimedTaskActionsAbstra
return reloadedObject;
}
public handleReloadableActionResponse(result: boolean, dso: DSpaceObject): void {
super.handleReloadableActionResponse(result, dso);
// Item page version table includes labels for workflow Items, determined
// based on the result of /workflowitems/search/item?uuid=...
// In order for this label to be in sync with the workflow state, we should
// invalidate WFIs as they are approved.
this.workflowItemDataService.invalidateByHref(this.object?._links.workflowitem?.href);
}
}

View File

@@ -82,6 +82,8 @@ describe('SubmissionObjectEffects test suite', () => {
let submissionServiceStub;
let submissionJsonPatchOperationsServiceStub;
let submissionObjectDataServiceStub;
let workspaceItemDataService;
const collectionId: string = mockSubmissionCollectionId;
const submissionId: string = mockSubmissionId;
const submissionDefinitionResponse: any = mockSubmissionDefinitionResponse;
@@ -98,6 +100,10 @@ describe('SubmissionObjectEffects test suite', () => {
submissionServiceStub.hasUnsavedModification.and.returnValue(observableOf(true));
workspaceItemDataService = jasmine.createSpyObj('WorkspaceItemDataService', {
invalidateById: observableOf(true),
});
TestBed.configureTestingModule({
imports: [
StoreModule.forRoot({}, storeModuleConfig),
@@ -122,6 +128,7 @@ describe('SubmissionObjectEffects test suite', () => {
{ provide: WorkflowItemDataService, useValue: {} },
{ provide: HALEndpointService, useValue: {} },
{ provide: SubmissionObjectDataService, useValue: submissionObjectDataServiceStub },
{ provide: WorkspaceitemDataService, useValue: workspaceItemDataService },
],
});

View File

@@ -37,6 +37,7 @@ import { WorkspaceitemSectionUploadObject } from '../../core/submission/models/w
import { WorkspaceitemSectionsObject } from '../../core/submission/models/workspaceitem-sections.model';
import { SubmissionJsonPatchOperationsService } from '../../core/submission/submission-json-patch-operations.service';
import { SubmissionObjectDataService } from '../../core/submission/submission-object-data.service';
import { WorkspaceitemDataService } from '../../core/submission/workspaceitem-data.service';
import {
isEmpty,
isNotEmpty,
@@ -287,6 +288,7 @@ export class SubmissionObjectEffects {
depositSubmissionSuccess$ = createEffect(() => this.actions$.pipe(
ofType(SubmissionObjectActionTypes.DEPOSIT_SUBMISSION_SUCCESS),
tap(() => this.notificationsService.success(null, this.translate.get('submission.sections.general.deposit_success_notice'))),
tap((action: DepositSubmissionSuccessAction) => this.workspaceItemDataService.invalidateById(action.payload.submissionId)),
tap(() => this.submissionService.redirectToMyDSpace())), { dispatch: false });
/**
@@ -355,14 +357,17 @@ export class SubmissionObjectEffects {
ofType(SubmissionObjectActionTypes.DISCARD_SUBMISSION_ERROR),
tap(() => this.notificationsService.error(null, this.translate.get('submission.sections.general.discard_error_notice')))), { dispatch: false });
constructor(private actions$: Actions,
constructor(
private actions$: Actions,
private notificationsService: NotificationsService,
private operationsService: SubmissionJsonPatchOperationsService,
private sectionService: SectionsService,
private store$: Store<any>,
private submissionService: SubmissionService,
private submissionObjectService: SubmissionObjectDataService,
private translate: TranslateService) {
private translate: TranslateService,
private workspaceItemDataService: WorkspaceitemDataService,
) {
}
/**

View File

@@ -3522,7 +3522,7 @@
// "item.page.version.create": "Create new version",
"item.page.version.create": "নতুন সংস্করণ তৈরি করুন",
// "item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.page.version.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.page.version.hasDraft": "একটি নতুন সংস্করণ তৈরি করা যাচ্ছে না কারণ ভার্সন হিস্ট্রিতে একটি জমা ইনপ্রগ্রেসস অবস্থাই রয়েছে",
// "item.preview.dc.identifier.uri": "Identifier:",
@@ -3651,7 +3651,7 @@
// "item.version.history.table.action.deleteVersion": "Delete version",
"item.version.history.table.action.deleteVersion": "মুছে ফেলুন সংস্করণ",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.history.table.action.hasDraft": "একটি নতুন সংস্করণ তৈরি করা যাচ্ছে না কারণ ভার্সন হিস্ট্রিতে একটি জমা ইনপ্রগ্রেসস অবস্থাই রয়েছে",
@@ -3692,7 +3692,7 @@
// "item.version.create.notification.failure" : "New version has not been created",
"item.version.create.notification.failure": "নতুন সংস্করণ তৈরি করা হয়নি",
// "item.version.create.notification.inProgress" : "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.create.notification.inProgress" : "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.create.notification.inProgress": "একটি নতুন সংস্করণ তৈরি করা যাবে না কারণ ভার্সন হিস্ট্রিতে একটি জমা ইনপ্রগ্রেসস অবস্থাই রয়েছে",

View File

@@ -3779,7 +3779,7 @@
// "item.page.version.create": "Create new version",
"item.page.version.create": "Crear una nova versió",
// "item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.page.version.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.page.version.hasDraft": "No es pot crear una nova versió perquè a l'historial de versions hi ha un enviament en curs",
// "item.page.claim.button": "Claim",
@@ -3938,7 +3938,7 @@
// "item.version.history.table.action.deleteVersion": "Delete version",
"item.version.history.table.action.deleteVersion": "Esborrar versió",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.history.table.action.hasDraft": "No és possible crear una nova versió ja que existeix a l'historial de versions un enviament pendent",
@@ -3985,7 +3985,7 @@
// "item.version.create.notification.failure" : "New version has not been created",
"item.version.create.notification.failure": "No s'ha creat una nova versió",
// "item.version.create.notification.inProgress" : "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.create.notification.inProgress" : "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.create.notification.inProgress": "No és possible crear una nova versió ja que existeix a l'historial de versions un enviament pendent",

View File

@@ -2782,7 +2782,7 @@
"item.page.reinstate": "Request reinstatement",
"item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
"item.page.version.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.page.claim.button": "Claim",
@@ -2912,7 +2912,7 @@
"item.version.history.table.action.deleteVersion": "Delete version",
"item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
"item.version.history.table.action.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.notice": "This is not the latest version of this item. The latest version can be found <a href='{{destination}}'>here</a>.",
@@ -2976,7 +2976,7 @@
"item.version.create.notification.failure": "New version has not been created",
"item.version.create.notification.inProgress": "A new version cannot be created because there is an inprogress submission in the version history",
"item.version.create.notification.inProgress": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.delete.modal.header": "Delete version",

View File

@@ -4078,7 +4078,7 @@
// "item.page.version.create": "Create new version",
"item.page.version.create": "Crear una nueva version",
// "item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.page.version.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.page.version.hasDraft": "No se puede crear una nueva versión porque en el historial de versiones hay un envío en curso",
// "item.page.claim.button": "Claim",
@@ -4237,7 +4237,7 @@
// "item.version.history.table.action.deleteVersion": "Delete version",
"item.version.history.table.action.deleteVersion": "Borrar versión",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.history.table.action.hasDraft": "No es posible crear una nueva versión puesto que existe en el historial de versiones un envío pendiente",
// "item.version.notice": "This is not the latest version of this item. The latest version can be found <a href='{{destination}}'>here</a>.",
@@ -4282,7 +4282,7 @@
// "item.version.create.notification.failure": "New version has not been created",
"item.version.create.notification.failure": "No se ha creado una nueva versión",
// "item.version.create.notification.inProgress": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.create.notification.inProgress": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.create.notification.inProgress": "No es posible crear una nueva versión puesto que existe en el historial de versiones un envío pendiente",
// "item.version.delete.modal.header": "Delete version",

View File

@@ -3474,7 +3474,7 @@
// "item.page.version.create": "Create new version",
"item.page.version.create": "Créer une nouvelle version",
// "item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.page.version.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.page.version.hasDraft": "Une nouvelle version ne peut être créée car il y a une soumission en cours dans l'historique des versions",
// "item.preview.dc.identifier.uri": "Identifier:",
@@ -3600,7 +3600,7 @@
// "item.version.history.table.action.deleteVersion": "Delete version",
"item.version.history.table.action.deleteVersion": "Supprimer la version",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.history.table.action.hasDraft": "Une nouvelle version ne peut pas être créée parce qu'il y a une soumission en cours dans l'historique des versions.",
// "item.version.notice": "This is not the latest version of this item. The latest version can be found <a href='{{destination}}'>here</a>.",
@@ -3639,7 +3639,7 @@
// "item.version.create.notification.failure": "New version has not been created",
"item.version.create.notification.failure": "La nouvelle version n'a pas été créée",
// "item.version.create.notification.inProgress": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.create.notification.inProgress": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.create.notification.inProgress": "Une nouvelle version ne peut pas être créée parce qu'il y a une soumission en cours dans l'historique des versions.",
// "item.version.delete.modal.header": "Delete version",

View File

@@ -3509,7 +3509,7 @@
// "item.page.version.create": "Create new version",
"item.page.version.create": "Cruthaich dreach ùr",
// "item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.page.version.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.page.version.hasDraft": "Cha ghabh dreach ùr a chruthachadh oir tha cur-a-steach a' tachairt ann an eachdraidh nan dreachan",
// "item.preview.dc.identifier.uri": "Identifier:",
@@ -3638,7 +3638,7 @@
// "item.version.history.table.action.deleteVersion": "Delete version",
"item.version.history.table.action.deleteVersion": "Dubh às dreach",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.history.table.action.hasDraft": "Cha ghabh dreach ùr a chruthachadh oir tha cur-a-steach a' tachairt ann an eachdraidh nan dreachan",
@@ -3679,7 +3679,7 @@
// "item.version.create.notification.failure" : "New version has not been created",
"item.version.create.notification.failure": "Cha deach dreach ùr a chruthachadh",
// "item.version.create.notification.inProgress" : "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.create.notification.inProgress" : "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.create.notification.inProgress": "Cha ghabh dreach ùr a chruthachadh oir tha cur-a-steach a' tachairt ann an eachdraidh nan dreachan",

View File

@@ -4378,9 +4378,9 @@
// TODO New key - Add a translation
"item.page.version.create": "Create new version",
// "item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.page.version.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
// TODO New key - Add a translation
"item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
"item.page.version.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
// "item.page.claim.button": "Claim",
// TODO New key - Add a translation
@@ -4565,9 +4565,9 @@
// TODO New key - Add a translation
"item.version.history.table.action.deleteVersion": "Delete version",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
// TODO New key - Add a translation
"item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
"item.version.history.table.action.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
// "item.version.notice": "This is not the latest version of this item. The latest version can be found <a href='{{destination}}'>here</a>.",
@@ -4626,9 +4626,9 @@
// TODO New key - Add a translation
"item.version.create.notification.failure": "New version has not been created",
// "item.version.create.notification.inProgress" : "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.create.notification.inProgress" : "A new version cannot be created because there is an in-progress submission in the version history",
// TODO New key - Add a translation
"item.version.create.notification.inProgress": "A new version cannot be created because there is an inprogress submission in the version history",
"item.version.create.notification.inProgress": "A new version cannot be created because there is an in-progress submission in the version history",
// "item.version.delete.modal.header": "Delete version",

View File

@@ -3679,7 +3679,7 @@
// "item.page.version.create": "Create new version",
"item.page.version.create": "Crea una nuova versione",
// "item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.page.version.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.page.version.hasDraft": "Impossibile creare una nuova versione perché è presente un'submission in corso nella cronologia delle versioni",
// "item.page.claim.button": "Claim",
@@ -3838,7 +3838,7 @@
// "item.version.history.table.action.deleteVersion": "Delete version",
"item.version.history.table.action.deleteVersion": "Elimina versione",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.history.table.action.hasDraft": "Non è possibile creare una nuova versione perchè c'è già una submission in progress nella cronologia delle versioni",
@@ -3885,7 +3885,7 @@
// "item.version.create.notification.failure": "New version has not been created",
"item.version.create.notification.failure": "Non è stata creata una nuova versione",
// "item.version.create.notification.inProgress": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.create.notification.inProgress": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.create.notification.inProgress": "Non è possibile creare una nuova versione perchè c'è già una submission in progress nella cronologia delle versioni",

View File

@@ -3726,7 +3726,7 @@
// "item.page.version.create": "Create new version",
"item.page.version.create": "Жаңа нұсқасын жасау",
// "item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.page.version.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.page.version.hasDraft": "Жаңа нұсқаны жасау мүмкін емес, өйткені нұсқа тарихында аяқталмаған жіберу бар",
// "item.page.claim.button": "Claim",
@@ -3886,7 +3886,7 @@
// "item.version.history.table.action.deleteVersion": "Delete version",
"item.version.history.table.action.deleteVersion": "Нұсқаны өшіру",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.history.table.action.hasDraft": "Жаңа нұсқаны жасау мүмкін емес, өйткені нұсқа тарихында аяқталмаған бағынымдар бар",
@@ -3933,7 +3933,7 @@
// "item.version.create.notification.failure" : "New version has not been created",
"item.version.create.notification.failure": "Жаңа нұсқа жасалмады",
// "item.version.create.notification.inProgress" : "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.create.notification.inProgress" : "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.create.notification.inProgress": "Жаңа нұсқаны жасау мүмкін емес, өйткені нұсқа тарихында аяқталмаған жіберу бар",

View File

@@ -4072,7 +4072,7 @@
// "item.page.version.create": "Create new version",
"item.page.version.create": "Criar nova versão",
// "item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.page.version.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.page.version.hasDraft": "Não é possível criar uma nova versão porque há uma submissão em andamento no histórico de versões",
// "item.page.claim.button": "Claim",
@@ -4231,7 +4231,7 @@
// "item.version.history.table.action.deleteVersion": "Delete version",
"item.version.history.table.action.deleteVersion": "Apagar versão",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.history.table.action.hasDraft": "Não é possível criar uma nova versão porque há uma submissão em andamento no histórico de versões",
// "item.version.notice": "This is not the latest version of this item. The latest version can be found <a href='{{destination}}'>here</a>.",
@@ -4276,7 +4276,7 @@
// "item.version.create.notification.failure": "New version has not been created",
"item.version.create.notification.failure": "A nova versão não foi criada",
// "item.version.create.notification.inProgress": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.create.notification.inProgress": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.create.notification.inProgress": "Não é possível criar uma nova versão porque há uma submissão em andamento no histórico de versões",
// "item.version.delete.modal.header": "Delete version",

View File

@@ -4109,7 +4109,7 @@
// "item.page.version.create": "Create new version",
"item.page.version.create": "Criar nova versão",
// "item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.page.version.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.page.version.hasDraft": "Um nova versão não pode ser criada porque já se encontra uma submisão em curso no histórico de versões.",
// "item.page.claim.button": "Claim",
@@ -4274,7 +4274,7 @@
// "item.version.history.table.action.deleteVersion": "Delete version",
"item.version.history.table.action.deleteVersion": "Remover versão",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.history.table.action.hasDraft": "Uma nova versão não pode ser criada porque se encontra um depósito em curso no histórico de versões",
// "item.version.notice": "This is not the latest version of this item. The latest version can be found <a href='{{destination}}'>here</a>.",
@@ -4319,7 +4319,7 @@
// "item.version.create.notification.failure": "New version has not been created",
"item.version.create.notification.failure": "Nova versão não foi criada",
// "item.version.create.notification.inProgress": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.create.notification.inProgress": "A new version cannot be created because there is an in-progress submission in the version history",
"item.version.create.notification.inProgress": "Uma nova versão não pode ser criada porque se encontra um depósito em curso no histórico de versões",
// "item.version.delete.modal.header": "Delete version",

View File

@@ -3555,7 +3555,7 @@
// "item.page.version.create": "Create new version",
"item.page.version.create": "Skapa ny version",
// "item.page.version.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.page.version.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
"item.page.version.hasDraft": "Ny version kan inte skapas pga pågående uppladdning i versionshistoriken",
// "item.preview.dc.identifier.uri": "Identifier:",
@@ -3685,9 +3685,9 @@
// "item.version.history.table.action.deleteVersion": "Delete version",
"item.version.history.table.action.deleteVersion": "Radera version",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.history.table.action.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
// TODO New key - Add a translation
"item.version.history.table.action.hasDraft": "A new version cannot be created because there is an inprogress submission in the version history",
"item.version.history.table.action.hasDraft": "A new version cannot be created because there is an in-progress submission in the version history",
// "item.version.notice": "This is not the latest version of this item. The latest version can be found <a href='{{destination}}'>here</a>.",
@@ -3727,9 +3727,9 @@
// "item.version.create.notification.failure" : "New version has not been created",
"item.version.create.notification.failure": "Ny version har inte skapats",
// "item.version.create.notification.inProgress" : "A new version cannot be created because there is an inprogress submission in the version history",
// "item.version.create.notification.inProgress" : "A new version cannot be created because there is an in-progress submission in the version history",
// TODO New key - Add a translation
"item.version.create.notification.inProgress": "A new version cannot be created because there is an inprogress submission in the version history",
"item.version.create.notification.inProgress": "A new version cannot be created because there is an in-progress submission in the version history",
// "item.version.delete.modal.header": "Delete version",