diff --git a/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.html b/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.html
index 0f79fa6a1dd..b59fddc846e 100644
--- a/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.html
+++ b/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.html
@@ -43,7 +43,7 @@
- {{ field.label }}
+ {{ field.label | translate }}
@@ -86,7 +86,7 @@
5" [disabled]="field.id === 'jurisdiction' && defaultJurisdiction !== undefined && defaultJurisdiction !== 'none'">
- {{ option.label }}
+ {{ option.label | translate }}
{{ 'submission.sections.ccLicense.option.select' | translate }}
@@ -97,7 +97,7 @@
- {{ option.label }}
+ {{ option.label | translate }}
@@ -108,10 +108,10 @@
class="d-flex flex-row m-1">
- {{ option.label }}
+ {{ option.label | translate }}
diff --git a/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.scss b/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.scss
index 142cd82822a..eef804bac93 100644
--- a/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.scss
+++ b/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.scss
@@ -3,7 +3,12 @@
}
.ccLicense-select {
- width: fit-content;
+ width: 400px;
+ max-width: 100%;
+
+ ngb-dropdown, .input-group, input.form-control {
+ width: 100%;
+ }
}
.scrollable-menu {
diff --git a/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.spec.ts b/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.spec.ts
index e59cf69ca48..268f08aaf4e 100644
--- a/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.spec.ts
+++ b/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.spec.ts
@@ -1,7 +1,7 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { SubmissionSectionCcLicensesComponent } from './submission-section-cc-licenses.component';
import { SUBMISSION_CC_LICENSE } from '../../../core/submission/models/submission-cc-licence.resource-type';
-import { of as observableOf } from 'rxjs';
+import { of as observableOf, Subject } from 'rxjs';
import { SubmissionCcLicenseDataService } from '../../../core/submission/submission-cc-license-data.service';
import { DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser';
@@ -139,9 +139,11 @@ describe('SubmissionSectionCcLicensesComponent', () => {
getCcLicenseLink: observableOf('test cc license link'),
});
+ let sectionState$: Subject;
+
const sectionService = {
getSectionState: () => {
- return observableOf({});
+ return sectionState$;
},
setSectionStatus: () => undefined,
updateSectionData: (submissionId, sectionId, updatedData) => {
@@ -186,6 +188,7 @@ describe('SubmissionSectionCcLicensesComponent', () => {
}));
beforeEach(() => {
+ sectionState$ = new Subject();
fixture = TestBed.createComponent(SubmissionSectionCcLicensesComponent);
component = fixture.componentInstance;
de = fixture.debugElement;
@@ -281,4 +284,168 @@ describe('SubmissionSectionCcLicensesComponent', () => {
});
});
});
+
+ describe('when a license uri is stored', () => {
+
+ const enumOption = (id: string) => ({ id, label: id, description: id });
+ const _links = { self: { href: 'test link' } };
+ const cc30: SubmissionCcLicence = {
+ id: 'cc30',
+ type: SUBMISSION_CC_LICENSE,
+ name: 'Creative Commons License (3.0)',
+ fields: [
+ { id: 'commercial', label: 'commercial', description: '', enums: [enumOption('y'), enumOption('n')] },
+ { id: 'derivatives', label: 'derivatives', description: '', enums: [enumOption('y'), enumOption('sa'), enumOption('n')] },
+ { id: 'jurisdiction', label: 'jurisdiction', description: '', enums: [enumOption(''), enumOption('us')] },
+ ],
+ _links,
+ };
+ const cc40: SubmissionCcLicence = {
+ id: 'cc40',
+ type: SUBMISSION_CC_LICENSE,
+ name: 'Creative Commons License (4.0)',
+ fields: [
+ { id: 'commercial', label: 'commercial', description: '', enums: [enumOption('y'), enumOption('n')] },
+ { id: 'derivatives', label: 'derivatives', description: '', enums: [enumOption('y'), enumOption('sa'), enumOption('n')] },
+ ],
+ _links,
+ };
+ const cc0: SubmissionCcLicence = { id: 'cc0', type: SUBMISSION_CC_LICENSE, name: 'CC0 1.0 Universal', fields: [], _links };
+ const mark: SubmissionCcLicence = { id: 'mark', type: SUBMISSION_CC_LICENSE, name: 'Public Domain Mark 1.0 Universal', fields: [], _links };
+ const sampling: SubmissionCcLicence = {
+ id: 'sampling',
+ type: SUBMISSION_CC_LICENSE,
+ name: 'Creative Commons Sampling License (1.0)',
+ fields: [
+ { id: 'sampling', label: 'sampling', description: '', enums: [enumOption('sampling'), enumOption('samplingplus'), enumOption('ncsamplingplus')] },
+ ],
+ _links,
+ };
+
+ const restore = (uri: string) => {
+ component.submissionCcLicenses = [cc30, cc40, cc0, mark, sampling];
+ component.sectionData.data = { uri };
+ (component as any).restoreSelectionFromStoredUri();
+ };
+
+ it('should restore a CC 4.0 license with its options', () => {
+ restore('https://creativecommons.org/licenses/by-nc-sa/4.0/');
+ expect(component.data.ccLicense.id).toEqual('cc40');
+ expect(component.data.ccLicense.fields.commercial.id).toEqual('n');
+ expect(component.data.ccLicense.fields.derivatives.id).toEqual('sa');
+ expect(component.data.uri).toEqual('https://creativecommons.org/licenses/by-nc-sa/4.0/');
+ });
+
+ it('should restore a CC 3.0 license with its jurisdiction', () => {
+ restore('https://creativecommons.org/licenses/by-nd/3.0/us/');
+ expect(component.data.ccLicense.id).toEqual('cc30');
+ expect(component.data.ccLicense.fields.commercial.id).toEqual('y');
+ expect(component.data.ccLicense.fields.derivatives.id).toEqual('n');
+ expect(component.data.ccLicense.fields.jurisdiction.id).toEqual('us');
+ });
+
+ it('should restore a Sampling license with its option', () => {
+ restore('https://creativecommons.org/licenses/nc-sampling+/1.0/');
+ expect(component.data.ccLicense.id).toEqual('sampling');
+ expect(component.data.ccLicense.fields.sampling.id).toEqual('ncsamplingplus');
+ });
+
+ it('should distinguish public domain licenses with the same version', () => {
+ restore('https://creativecommons.org/publicdomain/mark/1.0/');
+ expect(component.data.ccLicense.id).toEqual('mark');
+ restore('https://creativecommons.org/publicdomain/zero/1.0/');
+ expect(component.data.ccLicense.id).toEqual('cc0');
+ });
+
+ it('should leave an unknown uri untouched', () => {
+ restore('https://example.org/my-license');
+ expect(component.data.ccLicense).toBeUndefined();
+ expect(component.accepted).toBeTrue();
+ });
+
+ it('should not override an existing selection', () => {
+ component.submissionCcLicenses = [cc30, cc40, cc0, mark];
+ component.sectionData.data = { uri: 'https://creativecommons.org/licenses/by/4.0/', ccLicense: { id: 'cc0', fields: {} } };
+ (component as any).restoreSelectionFromStoredUri();
+ expect(component.data.ccLicense.id).toEqual('cc0');
+ });
+ });
+
+ describe('when the section state changes', () => {
+ const uri = 'https://creativecommons.org/licenses/by/4.0/';
+
+ beforeEach(() => {
+ operationsBuilder.add.calls.reset();
+ operationsBuilder.remove.calls.reset();
+ });
+
+ it('should queue a remove when the stored license is no longer accepted', () => {
+ component.sectionData.data = { uri };
+ sectionState$.next({ data: { uri, accepted: false } });
+ expect(operationsBuilder.remove).toHaveBeenCalledTimes(1);
+ });
+
+ it('should queue the stored license again when it is unticked and ticked again before saving', () => {
+ component.sectionData.data = { uri };
+ sectionState$.next({ data: { uri, accepted: false } });
+ sectionState$.next({ data: { uri, accepted: true } });
+ expect(operationsBuilder.remove).toHaveBeenCalledTimes(1);
+ expect(operationsBuilder.add).toHaveBeenCalledTimes(1);
+ });
+
+ describe('when the stored license is selected', () => {
+ const cc0Uri = 'https://creativecommons.org/publicdomain/zero/1.0/';
+ const cc0License: SubmissionCcLicence = {
+ id: 'cc0', type: SUBMISSION_CC_LICENSE, name: 'CC0 1.0 Universal', fields: [], _links: submissionCcLicenses[0]._links,
+ };
+
+ beforeEach(() => {
+ component.submissionCcLicenses = [cc0License];
+ submissionCcLicenseUrlDataService.getCcLicenseLink.calls.reset();
+ });
+
+ it('should queue the stored uri right away when it is ticked again before saving', () => {
+ component.sectionData.data = { uri: cc0Uri, ccLicense: { id: 'cc0', fields: {} } };
+ sectionState$.next({ data: { uri: cc0Uri, ccLicense: { id: 'cc0', fields: {} }, accepted: false } });
+ sectionState$.next({ data: { uri: cc0Uri, ccLicense: { id: 'cc0', fields: {} }, accepted: true } });
+ expect(operationsBuilder.add).toHaveBeenCalledOnceWith(jasmine.anything(), cc0Uri, false, true);
+ expect(submissionCcLicenseUrlDataService.getCcLicenseLink).not.toHaveBeenCalled();
+ });
+
+ it('should look up the link when the selection differs from the stored uri', () => {
+ component.sectionData.data = { uri, ccLicense: { id: 'cc0', fields: {} } };
+ sectionState$.next({ data: { uri, ccLicense: { id: 'cc0', fields: {} }, accepted: false } });
+ sectionState$.next({ data: { uri, ccLicense: { id: 'cc0', fields: {} }, accepted: true } });
+ expect(operationsBuilder.add).toHaveBeenCalledOnceWith(jasmine.anything(), 'test cc license link', false, true);
+ });
+ });
+
+ it('should not queue a duplicate add for a license the server already stores', () => {
+ component.sectionData.data = { uri };
+ sectionState$.next({ data: { uri, accepted: false } });
+ // Section data from the server, without an accepted state, ends the pending remove
+ sectionState$.next({ data: { uri } });
+ sectionState$.next({ data: { uri, accepted: true } });
+ expect(operationsBuilder.add).not.toHaveBeenCalled();
+ });
+
+ it('should not queue a remove for a save response of an already removed license', () => {
+ component.sectionData.data = { uri, accepted: false };
+ // The REST API returns the cleared section data without an accepted state
+ sectionState$.next({ data: { uri: null, rights: null, file: null } });
+ expect(operationsBuilder.remove).not.toHaveBeenCalled();
+ expect(component.accepted).toBeFalse();
+ });
+
+ it('should queue a single remove when another license is selected', () => {
+ // Like the store, only apply the update once it is emitted by the section state
+ let updatedData;
+ spyOn(sectionService, 'updateSectionData').and.callFake((submissionId, sectionId, data) => updatedData = data);
+ component.submissionCcLicenses = submissionCcLicenses;
+ component.sectionData.data = { uri };
+ component.selectCcLicense(submissionCcLicenses[0]);
+ sectionState$.next({ data: updatedData });
+ expect(operationsBuilder.remove).toHaveBeenCalledTimes(1);
+ });
+ });
});
diff --git a/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.ts b/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.ts
index b999db5d339..7fecf2f16f0 100644
--- a/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.ts
+++ b/src/app/submission/sections/cc-license/submission-section-cc-licenses.component.ts
@@ -94,6 +94,12 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
*/
private ccLicenseLinkTrigger$ = new Subject();
+ /**
+ * Whether a remove of the stored uri is queued but not yet saved, so accepting the same license again
+ * has to queue an add instead of being skipped as unchanged.
+ */
+ private uriRemoveQueued = false;
+
/**
* The Creative Commons link saved in the workspace item.
*/
@@ -167,14 +173,16 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
return;
}
this.selectedCcLicense = ccLicense;
- this.setAccepted(false);
+ // A single update, as separate updates would each be compared against stale section data
this.updateSectionData({
ccLicense: {
id: ccLicense.id,
fields: {},
},
uri: undefined,
+ accepted: false,
});
+ this.updateSectionStatus();
// Trigger the debounced license link update
this.ccLicenseLinkTrigger$.next();
}
@@ -238,13 +246,10 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
* Get the link to the Creative Commons license corresponding with the selected options.
*/
getCcLicenseLink$(): Observable {
-
- if (!!this.storedCcLicenseLink) {
- return observableOf(this.storedCcLicenseLink);
- }
if (!this.getSelectedCcLicense() || this.getSelectedCcLicense().fields.some(
(field) => !this.getSelectedOption(this.getSelectedCcLicense(), field))) {
- return undefined;
+ // Fall back to the stored link when the selection could not be (fully) restored from it
+ return this.storedCcLicenseLink ? observableOf(this.storedCcLicenseLink) : undefined;
}
const selectedCcLicense = this.getSelectedCcLicense();
return this.submissionCcLicenseUrlDataService.getCcLicenseLink(
@@ -309,29 +314,49 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
}),
map((sectionState) => sectionState.data as WorkspaceitemSectionCcLicenseObject),
).subscribe((data) => {
- const wasAccepted = this.data.accepted;
const wasUri = this.data.uri;
+ if (!hasValue(data.accepted)) {
+ // Section data from the REST API, so any queued patch has been saved
+ this.uriRemoveQueued = false;
+ }
- // Only process if acceptance state actually changed
- if (wasAccepted !== data.accepted && data.accepted !== undefined) {
+ // The REST API never returns the accepted state, so only changes made in this section (which always
+ // set it) should queue a patch. Otherwise a save response would queue a remove of an already removed uri.
+ if (hasValue(data.accepted) && this.data.accepted !== data.accepted) {
const path = this.pathCombiner.getPath('uri');
- if (data.accepted && !wasAccepted) {
+ if (data.accepted && this.uriRemoveQueued && wasUri && this.isSelectionForUri(wasUri)) {
+ // The stored license is accepted again before its remove was saved. Queue it right away, as an add
+ // from the asynchronous link lookup below could miss a save that is already on its way.
+ this.operationsBuilder.add(path, wasUri, false, true);
+ this.uriRemoveQueued = false;
+ } else if (data.accepted) {
// Only add URI if we're switching from not accepted to accepted
const licenseLink$ = this.getCcLicenseLink$();
if (licenseLink$) {
licenseLink$.pipe(
take(1),
- filter(link => !!link && link !== wasUri) // Only proceed if link exists and is different
+ // Only proceed if link exists and is different, or the stored one is about to be removed
+ filter(link => !!link && (this.uriRemoveQueued || link !== wasUri))
).subscribe((link) => {
this.operationsBuilder.add(path, link.toString(), false, true);
+ this.uriRemoveQueued = false;
});
}
- } else if (!data.accepted && wasAccepted && !!this.data.uri) {
- // Only remove URI if we're switching from accepted to not accepted
+ } else if (this.data.uri) {
this.operationsBuilder.remove(path);
+ this.uriRemoveQueued = true;
}
}
- this.sectionData.data = data;
+ const previousCcLicense = this.data?.ccLicense;
+ this.sectionData.data = {
+ ...data,
+ // The REST API only returns the stored uri, so keep the (restored) selection when it is missing
+ ccLicense: data.ccLicense ?? previousCcLicense,
+ };
+ // The selection is updated asynchronously, so recompute the link once it has landed in the store
+ if (JSON.stringify(previousCcLicense) !== JSON.stringify(this.data.ccLicense)) {
+ this.ccLicenseLinkTrigger$.next();
+ }
}),
this.configService.findByPropertyName('cc.license.jurisdiction').pipe(
getFirstCompletedRemoteData(),
@@ -387,9 +412,120 @@ export class SubmissionSectionCcLicensesComponent extends SectionModelComponent
(licenses) => {
this.submissionCcLicenses = [...this.submissionCcLicenses, ...licenses];
this.isLoading = false;
+ this.restoreSelectionFromStoredUri();
this.ref.detectChanges();
},
),
);
}
+
+ /**
+ * Rebuild the license selection (license + field answers) from the stored license uri.
+ * The REST API only returns the uri of a saved license, so without this the previously chosen
+ * license and options can't be shown or changed after the submission has been saved and reopened.
+ * Does not touch the uri or accepted state, as the stored license remains valid.
+ */
+ private restoreSelectionFromStoredUri(): void {
+ if (hasValue(this.data?.ccLicense) || !this.storedCcLicenseLink) {
+ return;
+ }
+ const selection = this.getSelectionForUri(this.storedCcLicenseLink);
+ if (!selection) {
+ // Unknown uri, or the license might be on a page that hasn't been loaded yet
+ return;
+ }
+ this.selectedCcLicense = selection.license;
+ this.updateSectionData({
+ ccLicense: {
+ id: selection.license.id,
+ fields: selection.fields,
+ },
+ });
+ }
+
+ /**
+ * Whether the currently selected license and options are the ones the given license uri was issued for.
+ * @param uri the license uri
+ */
+ private isSelectionForUri(uri: string): boolean {
+ const selection = this.getSelectionForUri(uri);
+ const selectedCcLicense = this.getSelectedCcLicense();
+ if (!selection || !selectedCcLicense || selectedCcLicense.id !== selection.license.id) {
+ return false;
+ }
+ return (selection.license.fields ?? []).every((field) => {
+ const expected = selection.fields[field.id];
+ const actual = this.getSelectedOption(selectedCcLicense, field);
+ return !!expected && !!actual && expected.id === actual.id;
+ });
+ }
+
+ /**
+ * Get the license and field answers that a given license uri was issued for.
+ * Returns null when the uri is not a known Creative Commons license or the license isn't loaded.
+ * @param uri the license uri
+ */
+ private getSelectionForUri(uri: string): { license: SubmissionCcLicence, fields: { [fieldId: string]: Option } } {
+ const parsed = this.parseCcLicenseUri(uri);
+ if (!parsed) {
+ return null;
+ }
+ const license = this.submissionCcLicenses.find((ccLicense) => parsed.matches(ccLicense.name ?? ''));
+ if (!license) {
+ return null;
+ }
+
+ const fields: { [fieldId: string]: Option } = {};
+ (license.fields ?? []).forEach((field) => {
+ let optionId: string;
+ switch (field.id) {
+ case 'commercial':
+ optionId = parsed.unit.includes('nc') ? 'n' : 'y';
+ break;
+ case 'derivatives':
+ optionId = parsed.unit.includes('nd') ? 'n' : parsed.unit.includes('sa') ? 'sa' : 'y';
+ break;
+ case 'jurisdiction':
+ optionId = parsed.jurisdiction ?? '';
+ break;
+ case 'sampling':
+ // e.g. 'nc-sampling+' -> 'ncsamplingplus'
+ optionId = parsed.unit.replace('-', '').replace('+', 'plus');
+ break;
+ }
+ const option = field.enums?.find((o) => o.id === optionId);
+ if (option) {
+ fields[field.id] = option;
+ }
+ });
+ return { license, fields };
+ }
+
+ /**
+ * Parse a creativecommons.org license uri into its unit (e.g. 'by-nc-nd', 'sampling+', 'zero'), version and
+ * optional jurisdiction, together with a matcher for the name of the corresponding license.
+ * Returns null for uris that don't match a known Creative Commons pattern.
+ * @param uri the stored license uri
+ */
+ private parseCcLicenseUri(uri: string): { unit: string, jurisdiction?: string, matches: (name: string) => boolean } {
+ const standard = /creativecommons\.org\/licenses\/([a-z+-]+)\/(\d+\.\d+)(?:\/([a-z_-]+))?/i.exec(uri);
+ if (standard) {
+ const version = standard[2];
+ return {
+ unit: standard[1].toLowerCase(),
+ jurisdiction: standard[3]?.toLowerCase(),
+ matches: (name) => name.includes(`(${version})`),
+ };
+ }
+ const publicDomain = /creativecommons\.org\/publicdomain\/(zero|mark|certification)\//i.exec(uri);
+ if (publicDomain) {
+ const unit = publicDomain[1].toLowerCase();
+ const namePart = { zero: 'cc0', mark: 'mark', certification: 'certification' }[unit];
+ return {
+ unit,
+ matches: (name) => name.toLowerCase().includes(namePart),
+ };
+ }
+ return null;
+ }
}
diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5
index b9b7081b238..83e51685f5b 100644
--- a/src/assets/i18n/cs.json5
+++ b/src/assets/i18n/cs.json5
@@ -6948,6 +6948,81 @@
// "submission.sections.ccLicense.confirmation": "I grant the license above",
"submission.sections.ccLicense.confirmation": "Uděluji výše uvedenou licenci",
+ // "cc-license.commercial.label": "Allow commercial uses of your work?",
+ "cc-license.commercial.label": "Povolit komerční užití vašeho díla?",
+
+ // "cc-license.commercial.hint": "Choose whether others may use your work for commercial purposes.",
+ "cc-license.commercial.hint": "Zvolte, zda mohou ostatní užívat vaše dílo pro komerční účely.",
+
+ // "cc-license.commercial.option.yes.label": "Yes",
+ "cc-license.commercial.option.yes.label": "Ano",
+
+ // "cc-license.commercial.option.yes.hint": "Visitors may copy, distribute, display and perform your Submission for any purpose, including commercial purposes.",
+ "cc-license.commercial.option.yes.hint": "Návštěvníci mohou váš příspěvek kopírovat, šířit, vystavovat a předvádět za jakýmkoli účelem, včetně komerčního.",
+
+ // "cc-license.commercial.option.no.label": "No",
+ "cc-license.commercial.option.no.label": "Ne",
+
+ // "cc-license.commercial.option.no.hint": "Visitors may copy, distribute, display and perform your Submission, but only for non-commercial purposes.",
+ "cc-license.commercial.option.no.hint": "Návštěvníci mohou váš příspěvek kopírovat, šířit, vystavovat a předvádět, ale pouze pro nekomerční účely.",
+
+ // "cc-license.derivatives.label": "Allow modifications of your work?",
+ "cc-license.derivatives.label": "Povolit úpravy vašeho díla?",
+
+ // "cc-license.derivatives.hint": "Choose whether others may create derivative works based on your Submission.",
+ "cc-license.derivatives.hint": "Zvolte, zda mohou ostatní vytvářet odvozená díla na základě vašeho příspěvku.",
+
+ // "cc-license.derivatives.option.yes.label": "Yes",
+ "cc-license.derivatives.option.yes.label": "Ano",
+
+ // "cc-license.derivatives.option.yes.hint": "Visitors may copy, distribute, display, perform and modify your Submission in any way.",
+ "cc-license.derivatives.option.yes.hint": "Návštěvníci mohou váš příspěvek kopírovat, šířit, vystavovat, předvádět a jakkoli upravovat.",
+
+ // "cc-license.derivatives.option.sharealike.label": "ShareAlike",
+ "cc-license.derivatives.option.sharealike.label": "Ano, se zachováním licence (ShareAlike)",
+
+ // "cc-license.derivatives.option.sharealike.hint": "Visitors are permitted to copy, display, perform and modify your Submission, as long as they distribute the modified version on similar use terms.",
+ "cc-license.derivatives.option.sharealike.hint": "Návštěvníci mohou váš příspěvek kopírovat, vystavovat, předvádět a upravovat, pokud upravenou verzi šíří za stejných licenčních podmínek.",
+
+ // "cc-license.derivatives.option.no.label": "No",
+ "cc-license.derivatives.option.no.label": "Ne",
+
+ // "cc-license.derivatives.option.no.hint": "Visitors are only permitted to copy and distribute unaltered versions of your Submission.",
+ "cc-license.derivatives.option.no.hint": "Návštěvníci mohou váš příspěvek pouze kopírovat a šířit v nezměněné podobě.",
+
+ // "cc-license.jurisdiction.label": "Jurisdiction",
+ "cc-license.jurisdiction.label": "Jurisdikce",
+
+ // "cc-license.jurisdiction.hint": "Select the legal jurisdiction for your Creative Commons license, or leave as the default international license.",
+ "cc-license.jurisdiction.hint": "Vyberte právní jurisdikci licence Creative Commons, nebo ponechte výchozí mezinárodní licenci.",
+
+ // "cc-license.jurisdiction.option.unported.label": "Generic (Unported)",
+ "cc-license.jurisdiction.option.unported.label": "Obecná (mezinárodní)",
+
+ // "cc-license.sampling.label": "Which Sampling license would you like to use?",
+ "cc-license.sampling.label": "Kterou licenci Sampling chcete použít?",
+
+ // "cc-license.sampling.hint": "Choose which kind of sampling, remixing or mash-up of your work you allow.",
+ "cc-license.sampling.hint": "Zvolte, jaký druh samplování, remixování nebo mash-upu vašeho díla povolujete.",
+
+ // "cc-license.sampling.option.sampling.label": "Sampling",
+ "cc-license.sampling.option.sampling.label": "Sampling",
+
+ // "cc-license.sampling.option.sampling.hint": "Visitors may sample, remix or transform parts of your work for any purpose other than advertising, but may not copy or distribute the entire work.",
+ "cc-license.sampling.option.sampling.hint": "Návštěvníci mohou části vašeho díla samplovat, remixovat nebo upravovat za jakýmkoli účelem kromě reklamy, ale nesmí kopírovat ani šířit celé dílo.",
+
+ // "cc-license.sampling.option.samplingplus.label": "Sampling Plus",
+ "cc-license.sampling.option.samplingplus.label": "Sampling Plus",
+
+ // "cc-license.sampling.option.samplingplus.hint": "Visitors may sample, remix or transform parts of your work for any purpose other than advertising, and may also copy and distribute the entire work for non-commercial purposes.",
+ "cc-license.sampling.option.samplingplus.hint": "Návštěvníci mohou části vašeho díla samplovat, remixovat nebo upravovat za jakýmkoli účelem kromě reklamy a celé dílo mohou kopírovat a šířit pro nekomerční účely.",
+
+ // "cc-license.sampling.option.ncsamplingplus.label": "NonCommercial Sampling Plus",
+ "cc-license.sampling.option.ncsamplingplus.label": "Nekomerční Sampling Plus",
+
+ // "cc-license.sampling.option.ncsamplingplus.hint": "Visitors may sample, remix or transform parts of your work, and copy and distribute the entire work, but only for non-commercial purposes.",
+ "cc-license.sampling.option.ncsamplingplus.hint": "Návštěvníci mohou části vašeho díla samplovat, remixovat nebo upravovat a celé dílo kopírovat a šířit, ale pouze pro nekomerční účely.",
+
// "submission.sections.general.add-more": "Add more",
"submission.sections.general.add-more": "Přidat další",
diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5
index e24bf4378ca..a38f69f43c2 100644
--- a/src/assets/i18n/en.json5
+++ b/src/assets/i18n/en.json5
@@ -6437,4 +6437,42 @@
"clarin-license-agreement-page.download-error": "An error occurred while downloading the file. Please try again later.",
"footer.link.university": "University Library",
+
+ "cc-license.commercial.label": "Allow commercial uses of your work?",
+ "cc-license.commercial.hint": "Choose whether others may use your work for commercial purposes.",
+
+ "cc-license.commercial.option.yes.label": "Yes",
+ "cc-license.commercial.option.yes.hint": "Visitors may copy, distribute, display and perform your Submission for any purpose, including commercial purposes.",
+
+ "cc-license.commercial.option.no.label": "No",
+ "cc-license.commercial.option.no.hint": "Visitors may copy, distribute, display and perform your Submission, but only for non-commercial purposes.",
+
+ "cc-license.derivatives.label": "Allow modifications of your work?",
+ "cc-license.derivatives.hint": "Choose whether others may create derivative works based on your Submission.",
+
+ "cc-license.derivatives.option.yes.label": "Yes",
+ "cc-license.derivatives.option.yes.hint": "Visitors may copy, distribute, display, perform and modify your Submission in any way.",
+
+ "cc-license.derivatives.option.sharealike.label": "ShareAlike",
+ "cc-license.derivatives.option.sharealike.hint": "Visitors are permitted to copy, display, perform and modify your Submission, as long as they distribute the modified version on similar use terms.",
+
+ "cc-license.derivatives.option.no.label": "No",
+ "cc-license.derivatives.option.no.hint": "Visitors are only permitted to copy and distribute unaltered versions of your Submission.",
+
+ "cc-license.jurisdiction.label": "Jurisdiction",
+ "cc-license.jurisdiction.hint": "Select the legal jurisdiction for your Creative Commons license, or leave as the default international license.",
+
+ "cc-license.jurisdiction.option.unported.label": "Generic (Unported)",
+
+ "cc-license.sampling.label": "Which Sampling license would you like to use?",
+ "cc-license.sampling.hint": "Choose which kind of sampling, remixing or mash-up of your work you allow.",
+
+ "cc-license.sampling.option.sampling.label": "Sampling",
+ "cc-license.sampling.option.sampling.hint": "Visitors may sample, remix or transform parts of your work for any purpose other than advertising, but may not copy or distribute the entire work.",
+
+ "cc-license.sampling.option.samplingplus.label": "Sampling Plus",
+ "cc-license.sampling.option.samplingplus.hint": "Visitors may sample, remix or transform parts of your work for any purpose other than advertising, and may also copy and distribute the entire work for non-commercial purposes.",
+
+ "cc-license.sampling.option.ncsamplingplus.label": "NonCommercial Sampling Plus",
+ "cc-license.sampling.option.ncsamplingplus.hint": "Visitors may sample, remix or transform parts of your work, and copy and distribute the entire work, but only for non-commercial purposes.",
}