From 2bc1217dff9448d8f99836c39cda66179bedc40c Mon Sep 17 00:00:00 2001 From: myrza1 Date: Thu, 19 Aug 2021 13:16:54 +0600 Subject: [PATCH 0001/2129] Create Kazakh Translation Create Kazakh Translation --- src/assets/i18n/kz.json5 | 6743 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 6743 insertions(+) create mode 100644 src/assets/i18n/kz.json5 diff --git a/src/assets/i18n/kz.json5 b/src/assets/i18n/kz.json5 new file mode 100644 index 00000000000..e18e846d176 --- /dev/null +++ b/src/assets/i18n/kz.json5 @@ -0,0 +1,6743 @@ +{ + + // "401.help": "You're not authorized to access this page. You can use the button below to get back to the home page.", + // TODO New key - Add a translation + "401.help": "You're not authorized to access this page. You can use the button below to get back to the home page.", + + // "401.link.home-page": "Take me to the home page", + "401.link.home-page": "Басты бетке өту", + + // "401.unauthorized": "unauthorized", + // TODO New key - Add a translation + "401.unauthorized": "unauthorized", + + + + // "403.help": "You don't have permission to access this page. You can use the button below to get back to the home page.", + // TODO New key - Add a translation + "403.help": "You don't have permission to access this page. You can use the button below to get back to the home page.", + + // "403.link.home-page": "Take me to the home page", + // TODO New key - Add a translation + "403.link.home-page": "Take me to the home page", + + // "403.forbidden": "forbidden", + // TODO New key - Add a translation + "403.forbidden": "forbidden", + + + + // "404.help": "We can't find the page you're looking for. The page may have been moved or deleted. You can use the button below to get back to the home page. ", + // TODO New key - Add a translation + "404.help": "We can't find the page you're looking for. The page may have been moved or deleted. You can use the button below to get back to the home page. ", + + // "404.link.home-page": "Take me to the home page", + // TODO New key - Add a translation + "404.link.home-page": "Take me to the home page", + + // "404.page-not-found": "page not found", + // TODO New key - Add a translation + "404.page-not-found": "page not found", + + // "admin.curation-tasks.breadcrumbs": "System curation tasks", + // TODO New key - Add a translation + "admin.curation-tasks.breadcrumbs": "System curation tasks", + + // "admin.curation-tasks.title": "System curation tasks", + // TODO New key - Add a translation + "admin.curation-tasks.title": "System curation tasks", + + // "admin.curation-tasks.header": "System curation tasks", + // TODO New key - Add a translation + "admin.curation-tasks.header": "System curation tasks", + + // "admin.registries.bitstream-formats.breadcrumbs": "Format registry", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.breadcrumbs": "Format registry", + + // "admin.registries.bitstream-formats.create.breadcrumbs": "Bitstream format", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.create.breadcrumbs": "Bitstream format", + + // "admin.registries.bitstream-formats.create.failure.content": "An error occurred while creating the new bitstream format.", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.create.failure.content": "An error occurred while creating the new bitstream format.", + + // "admin.registries.bitstream-formats.create.failure.head": "Failure", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.create.failure.head": "Failure", + + // "admin.registries.bitstream-formats.create.head": "Create Bitstream format", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.create.head": "Create Bitstream format", + + // "admin.registries.bitstream-formats.create.new": "Add a new bitstream format", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.create.new": "Add a new bitstream format", + + // "admin.registries.bitstream-formats.create.success.content": "The new bitstream format was successfully created.", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.create.success.content": "The new bitstream format was successfully created.", + + // "admin.registries.bitstream-formats.create.success.head": "Success", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.create.success.head": "Success", + + // "admin.registries.bitstream-formats.delete.failure.amount": "Failed to remove {{ amount }} format(s)", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.delete.failure.amount": "Failed to remove {{ amount }} format(s)", + + // "admin.registries.bitstream-formats.delete.failure.head": "Failure", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.delete.failure.head": "Failure", + + // "admin.registries.bitstream-formats.delete.success.amount": "Successfully removed {{ amount }} format(s)", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.delete.success.amount": "Successfully removed {{ amount }} format(s)", + + // "admin.registries.bitstream-formats.delete.success.head": "Success", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.delete.success.head": "Success", + + // "admin.registries.bitstream-formats.description": "This list of bitstream formats provides information about known formats and their support level.", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.description": "This list of bitstream formats provides information about known formats and their support level.", + + // "admin.registries.bitstream-formats.edit.breadcrumbs": "Bitstream format", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.breadcrumbs": "Bitstream format", + + // "admin.registries.bitstream-formats.edit.description.hint": "", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.description.hint": "", + + // "admin.registries.bitstream-formats.edit.description.label": "Description", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.description.label": "Description", + + // "admin.registries.bitstream-formats.edit.extensions.hint": "Extensions are file extensions that are used to automatically identify the format of uploaded files. You can enter several extensions for each format.", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.extensions.hint": "Extensions are file extensions that are used to automatically identify the format of uploaded files. You can enter several extensions for each format.", + + // "admin.registries.bitstream-formats.edit.extensions.label": "File extensions", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.extensions.label": "File extensions", + + // "admin.registries.bitstream-formats.edit.extensions.placeholder": "Enter a file extension without the dot", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.extensions.placeholder": "Enter a file extension without the dot", + + // "admin.registries.bitstream-formats.edit.failure.content": "An error occurred while editing the bitstream format.", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.failure.content": "An error occurred while editing the bitstream format.", + + // "admin.registries.bitstream-formats.edit.failure.head": "Failure", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.failure.head": "Failure", + + // "admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}", + + // "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.", + + // "admin.registries.bitstream-formats.edit.internal.label": "Internal", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.internal.label": "Internal", + + // "admin.registries.bitstream-formats.edit.mimetype.hint": "The MIME type associated with this format, does not have to be unique.", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.mimetype.hint": "The MIME type associated with this format, does not have to be unique.", + + // "admin.registries.bitstream-formats.edit.mimetype.label": "MIME Type", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.mimetype.label": "MIME Type", + + // "admin.registries.bitstream-formats.edit.shortDescription.hint": "A unique name for this format, (e.g. Microsoft Word XP or Microsoft Word 2000)", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.shortDescription.hint": "A unique name for this format, (e.g. Microsoft Word XP or Microsoft Word 2000)", + + // "admin.registries.bitstream-formats.edit.shortDescription.label": "Name", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.shortDescription.label": "Name", + + // "admin.registries.bitstream-formats.edit.success.content": "The bitstream format was successfully edited.", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.success.content": "The bitstream format was successfully edited.", + + // "admin.registries.bitstream-formats.edit.success.head": "Success", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.success.head": "Success", + + // "admin.registries.bitstream-formats.edit.supportLevel.hint": "The level of support your institution pledges for this format.", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.supportLevel.hint": "The level of support your institution pledges for this format.", + + // "admin.registries.bitstream-formats.edit.supportLevel.label": "Support level", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.supportLevel.label": "Support level", + + // "admin.registries.bitstream-formats.head": "Bitstream Format Registry", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.head": "Bitstream Format Registry", + + // "admin.registries.bitstream-formats.no-items": "No bitstream formats to show.", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.no-items": "No bitstream formats to show.", + + // "admin.registries.bitstream-formats.table.delete": "Delete selected", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.table.delete": "Delete selected", + + // "admin.registries.bitstream-formats.table.deselect-all": "Deselect all", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.table.deselect-all": "Deselect all", + + // "admin.registries.bitstream-formats.table.internal": "internal", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.table.internal": "internal", + + // "admin.registries.bitstream-formats.table.mimetype": "MIME Type", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.table.mimetype": "MIME Type", + + // "admin.registries.bitstream-formats.table.name": "Name", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.table.name": "Name", + + // "admin.registries.bitstream-formats.table.return": "Return", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.table.return": "Return", + + // "admin.registries.bitstream-formats.table.supportLevel.KNOWN": "Known", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.table.supportLevel.KNOWN": "Known", + + // "admin.registries.bitstream-formats.table.supportLevel.SUPPORTED": "Supported", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.table.supportLevel.SUPPORTED": "Supported", + + // "admin.registries.bitstream-formats.table.supportLevel.UNKNOWN": "Unknown", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.table.supportLevel.UNKNOWN": "Unknown", + + // "admin.registries.bitstream-formats.table.supportLevel.head": "Support Level", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.table.supportLevel.head": "Support Level", + + // "admin.registries.bitstream-formats.title": "DSpace Angular :: Bitstream Format Registry", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.title": "DSpace Angular :: Bitstream Format Registry", + + + + // "admin.registries.metadata.breadcrumbs": "Metadata registry", + // TODO New key - Add a translation + "admin.registries.metadata.breadcrumbs": "Metadata registry", + + // "admin.registries.metadata.description": "The metadata registry maintains a list of all metadata fields available in the repository. These fields may be divided amongst multiple schemas. However, DSpace requires the qualified Dublin Core schema.", + // TODO New key - Add a translation + "admin.registries.metadata.description": "The metadata registry maintains a list of all metadata fields available in the repository. These fields may be divided amongst multiple schemas. However, DSpace requires the qualified Dublin Core schema.", + + // "admin.registries.metadata.form.create": "Create metadata schema", + // TODO New key - Add a translation + "admin.registries.metadata.form.create": "Create metadata schema", + + // "admin.registries.metadata.form.edit": "Edit metadata schema", + // TODO New key - Add a translation + "admin.registries.metadata.form.edit": "Edit metadata schema", + + // "admin.registries.metadata.form.name": "Name", + // TODO New key - Add a translation + "admin.registries.metadata.form.name": "Name", + + // "admin.registries.metadata.form.namespace": "Namespace", + // TODO New key - Add a translation + "admin.registries.metadata.form.namespace": "Namespace", + + // "admin.registries.metadata.head": "Metadata Registry", + // TODO New key - Add a translation + "admin.registries.metadata.head": "Metadata Registry", + + // "admin.registries.metadata.schemas.no-items": "No metadata schemas to show.", + // TODO New key - Add a translation + "admin.registries.metadata.schemas.no-items": "No metadata schemas to show.", + + // "admin.registries.metadata.schemas.table.delete": "Delete selected", + // TODO New key - Add a translation + "admin.registries.metadata.schemas.table.delete": "Delete selected", + + // "admin.registries.metadata.schemas.table.id": "ID", + // TODO New key - Add a translation + "admin.registries.metadata.schemas.table.id": "ID", + + // "admin.registries.metadata.schemas.table.name": "Name", + // TODO New key - Add a translation + "admin.registries.metadata.schemas.table.name": "Name", + + // "admin.registries.metadata.schemas.table.namespace": "Namespace", + // TODO New key - Add a translation + "admin.registries.metadata.schemas.table.namespace": "Namespace", + + // "admin.registries.metadata.title": "DSpace Angular :: Metadata Registry", + // TODO New key - Add a translation + "admin.registries.metadata.title": "DSpace Angular :: Metadata Registry", + + + + // "admin.registries.schema.breadcrumbs": "Metadata schema", + // TODO New key - Add a translation + "admin.registries.schema.breadcrumbs": "Metadata schema", + + // "admin.registries.schema.description": "This is the metadata schema for \"{{namespace}}\".", + // TODO New key - Add a translation + "admin.registries.schema.description": "This is the metadata schema for \"{{namespace}}\".", + + // "admin.registries.schema.fields.head": "Schema metadata fields", + // TODO New key - Add a translation + "admin.registries.schema.fields.head": "Schema metadata fields", + + // "admin.registries.schema.fields.no-items": "No metadata fields to show.", + // TODO New key - Add a translation + "admin.registries.schema.fields.no-items": "No metadata fields to show.", + + // "admin.registries.schema.fields.table.delete": "Delete selected", + // TODO New key - Add a translation + "admin.registries.schema.fields.table.delete": "Delete selected", + + // "admin.registries.schema.fields.table.field": "Field", + // TODO New key - Add a translation + "admin.registries.schema.fields.table.field": "Field", + + // "admin.registries.schema.fields.table.scopenote": "Scope Note", + // TODO New key - Add a translation + "admin.registries.schema.fields.table.scopenote": "Scope Note", + + // "admin.registries.schema.form.create": "Create metadata field", + // TODO New key - Add a translation + "admin.registries.schema.form.create": "Create metadata field", + + // "admin.registries.schema.form.edit": "Edit metadata field", + // TODO New key - Add a translation + "admin.registries.schema.form.edit": "Edit metadata field", + + // "admin.registries.schema.form.element": "Element", + // TODO New key - Add a translation + "admin.registries.schema.form.element": "Element", + + // "admin.registries.schema.form.qualifier": "Qualifier", + // TODO New key - Add a translation + "admin.registries.schema.form.qualifier": "Qualifier", + + // "admin.registries.schema.form.scopenote": "Scope Note", + // TODO New key - Add a translation + "admin.registries.schema.form.scopenote": "Scope Note", + + // "admin.registries.schema.head": "Metadata Schema", + // TODO New key - Add a translation + "admin.registries.schema.head": "Metadata Schema", + + // "admin.registries.schema.notification.created": "Successfully created metadata schema \"{{prefix}}\"", + // TODO New key - Add a translation + "admin.registries.schema.notification.created": "Successfully created metadata schema \"{{prefix}}\"", + + // "admin.registries.schema.notification.deleted.failure": "Failed to delete {{amount}} metadata schemas", + // TODO New key - Add a translation + "admin.registries.schema.notification.deleted.failure": "Failed to delete {{amount}} metadata schemas", + + // "admin.registries.schema.notification.deleted.success": "Successfully deleted {{amount}} metadata schemas", + // TODO New key - Add a translation + "admin.registries.schema.notification.deleted.success": "Successfully deleted {{amount}} metadata schemas", + + // "admin.registries.schema.notification.edited": "Successfully edited metadata schema \"{{prefix}}\"", + // TODO New key - Add a translation + "admin.registries.schema.notification.edited": "Successfully edited metadata schema \"{{prefix}}\"", + + // "admin.registries.schema.notification.failure": "Error", + // TODO New key - Add a translation + "admin.registries.schema.notification.failure": "Error", + + // "admin.registries.schema.notification.field.created": "Successfully created metadata field \"{{field}}\"", + // TODO New key - Add a translation + "admin.registries.schema.notification.field.created": "Successfully created metadata field \"{{field}}\"", + + // "admin.registries.schema.notification.field.deleted.failure": "Failed to delete {{amount}} metadata fields", + // TODO New key - Add a translation + "admin.registries.schema.notification.field.deleted.failure": "Failed to delete {{amount}} metadata fields", + + // "admin.registries.schema.notification.field.deleted.success": "Successfully deleted {{amount}} metadata fields", + // TODO New key - Add a translation + "admin.registries.schema.notification.field.deleted.success": "Successfully deleted {{amount}} metadata fields", + + // "admin.registries.schema.notification.field.edited": "Successfully edited metadata field \"{{field}}\"", + // TODO New key - Add a translation + "admin.registries.schema.notification.field.edited": "Successfully edited metadata field \"{{field}}\"", + + // "admin.registries.schema.notification.success": "Success", + // TODO New key - Add a translation + "admin.registries.schema.notification.success": "Success", + + // "admin.registries.schema.return": "Return", + // TODO New key - Add a translation + "admin.registries.schema.return": "Return", + + // "admin.registries.schema.title": "DSpace Angular :: Metadata Schema Registry", + // TODO New key - Add a translation + "admin.registries.schema.title": "DSpace Angular :: Metadata Schema Registry", + + + + // "admin.access-control.epeople.actions.delete": "Delete EPerson", + // TODO New key - Add a translation + "admin.access-control.epeople.actions.delete": "Delete EPerson", + + // "admin.access-control.epeople.actions.impersonate": "Impersonate EPerson", + // TODO New key - Add a translation + "admin.access-control.epeople.actions.impersonate": "Impersonate EPerson", + + // "admin.access-control.epeople.actions.reset": "Reset password", + // TODO New key - Add a translation + "admin.access-control.epeople.actions.reset": "Reset password", + + // "admin.access-control.epeople.actions.stop-impersonating": "Stop impersonating EPerson", + // TODO New key - Add a translation + "admin.access-control.epeople.actions.stop-impersonating": "Stop impersonating EPerson", + + // "admin.access-control.epeople.title": "DSpace Angular :: EPeople", + // TODO New key - Add a translation + "admin.access-control.epeople.title": "DSpace Angular :: EPeople", + + // "admin.access-control.epeople.head": "EPeople", + // TODO New key - Add a translation + "admin.access-control.epeople.head": "EPeople", + + // "admin.access-control.epeople.search.head": "Search", + "admin.access-control.epeople.search.head": "Іздеу", + + // "admin.access-control.epeople.button.see-all": "Browse All", + // TODO New key - Add a translation + "admin.access-control.epeople.button.see-all": "Browse All", + + // "admin.access-control.epeople.search.scope.metadata": "Metadata", + // TODO New key - Add a translation + "admin.access-control.epeople.search.scope.metadata": "Metadata", + + // "admin.access-control.epeople.search.scope.email": "E-mail (exact)", + // TODO New key - Add a translation + "admin.access-control.epeople.search.scope.email": "E-mail (exact)", + + // "admin.access-control.epeople.search.button": "Search", + // TODO New key - Add a translation + "admin.access-control.epeople.search.button": "Search", + + // "admin.access-control.epeople.button.add": "Add EPerson", + // TODO New key - Add a translation + "admin.access-control.epeople.button.add": "Add EPerson", + + // "admin.access-control.epeople.table.id": "ID", + // TODO New key - Add a translation + "admin.access-control.epeople.table.id": "ID", + + // "admin.access-control.epeople.table.name": "Name", + // TODO New key - Add a translation + "admin.access-control.epeople.table.name": "Name", + + // "admin.access-control.epeople.table.email": "E-mail (exact)", + // TODO New key - Add a translation + "admin.access-control.epeople.table.email": "E-mail (exact)", + + // "admin.access-control.epeople.table.edit": "Edit", + // TODO New key - Add a translation + "admin.access-control.epeople.table.edit": "Edit", + + // "admin.access-control.epeople.table.edit.buttons.edit": "Edit \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.epeople.table.edit.buttons.edit": "Edit \"{{name}}\"", + + // "admin.access-control.epeople.table.edit.buttons.remove": "Delete \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.epeople.table.edit.buttons.remove": "Delete \"{{name}}\"", + + // "admin.access-control.epeople.no-items": "No EPeople to show.", + // TODO New key - Add a translation + "admin.access-control.epeople.no-items": "No EPeople to show.", + + // "admin.access-control.epeople.form.create": "Create EPerson", + // TODO New key - Add a translation + "admin.access-control.epeople.form.create": "Create EPerson", + + // "admin.access-control.epeople.form.edit": "Edit EPerson", + // TODO New key - Add a translation + "admin.access-control.epeople.form.edit": "Edit EPerson", + + // "admin.access-control.epeople.form.firstName": "First name", + // TODO New key - Add a translation + "admin.access-control.epeople.form.firstName": "First name", + + // "admin.access-control.epeople.form.lastName": "Last name", + // TODO New key - Add a translation + "admin.access-control.epeople.form.lastName": "Last name", + + // "admin.access-control.epeople.form.email": "E-mail", + // TODO New key - Add a translation + "admin.access-control.epeople.form.email": "E-mail", + + // "admin.access-control.epeople.form.emailHint": "Must be valid e-mail address", + // TODO New key - Add a translation + "admin.access-control.epeople.form.emailHint": "Must be valid e-mail address", + + // "admin.access-control.epeople.form.canLogIn": "Can log in", + // TODO New key - Add a translation + "admin.access-control.epeople.form.canLogIn": "Can log in", + + // "admin.access-control.epeople.form.requireCertificate": "Requires certificate", + // TODO New key - Add a translation + "admin.access-control.epeople.form.requireCertificate": "Requires certificate", + + // "admin.access-control.epeople.form.notification.created.success": "Successfully created EPerson \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.epeople.form.notification.created.success": "Successfully created EPerson \"{{name}}\"", + + // "admin.access-control.epeople.form.notification.created.failure": "Failed to create EPerson \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.epeople.form.notification.created.failure": "Failed to create EPerson \"{{name}}\"", + + // "admin.access-control.epeople.form.notification.created.failure.emailInUse": "Failed to create EPerson \"{{name}}\", email \"{{email}}\" already in use.", + // TODO New key - Add a translation + "admin.access-control.epeople.form.notification.created.failure.emailInUse": "Failed to create EPerson \"{{name}}\", email \"{{email}}\" already in use.", + + // "admin.access-control.epeople.form.notification.edited.failure.emailInUse": "Failed to edit EPerson \"{{name}}\", email \"{{email}}\" already in use.", + // TODO New key - Add a translation + "admin.access-control.epeople.form.notification.edited.failure.emailInUse": "Failed to edit EPerson \"{{name}}\", email \"{{email}}\" already in use.", + + // "admin.access-control.epeople.form.notification.edited.success": "Successfully edited EPerson \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.epeople.form.notification.edited.success": "Successfully edited EPerson \"{{name}}\"", + + // "admin.access-control.epeople.form.notification.edited.failure": "Failed to edit EPerson \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.epeople.form.notification.edited.failure": "Failed to edit EPerson \"{{name}}\"", + + // "admin.access-control.epeople.form.notification.deleted.success": "Successfully deleted EPerson \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.epeople.form.notification.deleted.success": "Successfully deleted EPerson \"{{name}}\"", + + // "admin.access-control.epeople.form.notification.deleted.failure": "Failed to delete EPerson \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.epeople.form.notification.deleted.failure": "Failed to delete EPerson \"{{name}}\"", + + // "admin.access-control.epeople.form.groupsEPersonIsMemberOf": "Member of these groups:", + // TODO New key - Add a translation + "admin.access-control.epeople.form.groupsEPersonIsMemberOf": "Member of these groups:", + + // "admin.access-control.epeople.form.table.id": "ID", + // TODO New key - Add a translation + "admin.access-control.epeople.form.table.id": "ID", + + // "admin.access-control.epeople.form.table.name": "Name", + // TODO New key - Add a translation + "admin.access-control.epeople.form.table.name": "Name", + + // "admin.access-control.epeople.form.memberOfNoGroups": "This EPerson is not a member of any groups", + // TODO New key - Add a translation + "admin.access-control.epeople.form.memberOfNoGroups": "This EPerson is not a member of any groups", + + // "admin.access-control.epeople.form.goToGroups": "Add to groups", + // TODO New key - Add a translation + "admin.access-control.epeople.form.goToGroups": "Add to groups", + + // "admin.access-control.epeople.notification.deleted.failure": "Failed to delete EPerson: \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.epeople.notification.deleted.failure": "Failed to delete EPerson: \"{{name}}\"", + + // "admin.access-control.epeople.notification.deleted.success": "Successfully deleted EPerson: \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.epeople.notification.deleted.success": "Successfully deleted EPerson: \"{{name}}\"", + + + + // "admin.access-control.groups.title": "DSpace Angular :: Groups", + // TODO New key - Add a translation + "admin.access-control.groups.title": "DSpace Angular :: Groups", + + // "admin.access-control.groups.title.singleGroup": "DSpace Angular :: Edit Group", + // TODO New key - Add a translation + "admin.access-control.groups.title.singleGroup": "DSpace Angular :: Edit Group", + + // "admin.access-control.groups.title.addGroup": "DSpace Angular :: New Group", + // TODO New key - Add a translation + "admin.access-control.groups.title.addGroup": "DSpace Angular :: New Group", + + // "admin.access-control.groups.head": "Groups", + // TODO New key - Add a translation + "admin.access-control.groups.head": "Groups", + + // "admin.access-control.groups.button.add": "Add group", + // TODO New key - Add a translation + "admin.access-control.groups.button.add": "Add group", + + // "admin.access-control.groups.search.head": "Search groups", + // TODO New key - Add a translation + "admin.access-control.groups.search.head": "Search groups", + + // "admin.access-control.groups.button.see-all": "Browse all", + // TODO New key - Add a translation + "admin.access-control.groups.button.see-all": "Browse all", + + // "admin.access-control.groups.search.button": "Search", + // TODO New key - Add a translation + "admin.access-control.groups.search.button": "Search", + + // "admin.access-control.groups.table.id": "ID", + // TODO New key - Add a translation + "admin.access-control.groups.table.id": "ID", + + // "admin.access-control.groups.table.name": "Name", + // TODO New key - Add a translation + "admin.access-control.groups.table.name": "Name", + + // "admin.access-control.groups.table.members": "Members", + // TODO New key - Add a translation + "admin.access-control.groups.table.members": "Members", + + // "admin.access-control.groups.table.edit": "Edit", + // TODO New key - Add a translation + "admin.access-control.groups.table.edit": "Edit", + + // "admin.access-control.groups.table.edit.buttons.edit": "Edit \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.table.edit.buttons.edit": "Edit \"{{name}}\"", + + // "admin.access-control.groups.table.edit.buttons.remove": "Delete \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.table.edit.buttons.remove": "Delete \"{{name}}\"", + + // "admin.access-control.groups.no-items": "No groups found with this in their name or this as UUID", + // TODO New key - Add a translation + "admin.access-control.groups.no-items": "No groups found with this in their name or this as UUID", + + // "admin.access-control.groups.notification.deleted.success": "Successfully deleted group \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.notification.deleted.success": "Successfully deleted group \"{{name}}\"", + + // "admin.access-control.groups.notification.deleted.failure.title": "Failed to delete group \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.notification.deleted.failure.title": "Failed to delete group \"{{name}}\"", + + // "admin.access-control.groups.notification.deleted.failure.content": "Cause: \"{{cause}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.notification.deleted.failure.content": "Cause: \"{{cause}}\"", + + + + // "admin.access-control.groups.form.alert.permanent": "This group is permanent, so it can't be edited or deleted. You can still add and remove group members using this page.", + // TODO New key - Add a translation + "admin.access-control.groups.form.alert.permanent": "This group is permanent, so it can't be edited or deleted. You can still add and remove group members using this page.", + + // "admin.access-control.groups.form.alert.workflowGroup": "This group can’t be modified or deleted because it corresponds to a role in the submission and workflow process in the \"{{name}}\" {{comcol}}. You can delete it from the \"assign roles\" tab on the edit {{comcol}} page. You can still add and remove group members using this page.", + // TODO New key - Add a translation + "admin.access-control.groups.form.alert.workflowGroup": "This group can’t be modified or deleted because it corresponds to a role in the submission and workflow process in the \"{{name}}\" {{comcol}}. You can delete it from the \"assign roles\" tab on the edit {{comcol}} page. You can still add and remove group members using this page.", + + // "admin.access-control.groups.form.head.create": "Create group", + // TODO New key - Add a translation + "admin.access-control.groups.form.head.create": "Create group", + + // "admin.access-control.groups.form.head.edit": "Edit group", + // TODO New key - Add a translation + "admin.access-control.groups.form.head.edit": "Edit group", + + // "admin.access-control.groups.form.groupName": "Group name", + // TODO New key - Add a translation + "admin.access-control.groups.form.groupName": "Group name", + + // "admin.access-control.groups.form.groupDescription": "Description", + // TODO New key - Add a translation + "admin.access-control.groups.form.groupDescription": "Description", + + // "admin.access-control.groups.form.notification.created.success": "Successfully created Group \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.notification.created.success": "Successfully created Group \"{{name}}\"", + + // "admin.access-control.groups.form.notification.created.failure": "Failed to create Group \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.notification.created.failure": "Failed to create Group \"{{name}}\"", + + // "admin.access-control.groups.form.notification.created.failure.groupNameInUse": "Failed to create Group with name: \"{{name}}\", make sure the name is not already in use.", + // TODO New key - Add a translation + "admin.access-control.groups.form.notification.created.failure.groupNameInUse": "Failed to create Group with name: \"{{name}}\", make sure the name is not already in use.", + + // "admin.access-control.groups.form.notification.edited.failure": "Failed to edit Group \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.notification.edited.failure": "Failed to edit Group \"{{name}}\"", + + // "admin.access-control.groups.form.notification.edited.failure.groupNameInUse": "Name \"{{name}}\" already in use!", + // TODO New key - Add a translation + "admin.access-control.groups.form.notification.edited.failure.groupNameInUse": "Name \"{{name}}\" already in use!", + + // "admin.access-control.groups.form.notification.edited.success": "Successfully edited Group \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.notification.edited.success": "Successfully edited Group \"{{name}}\"", + + // "admin.access-control.groups.form.actions.delete": "Delete Group", + // TODO New key - Add a translation + "admin.access-control.groups.form.actions.delete": "Delete Group", + + // "admin.access-control.groups.form.delete-group.modal.header": "Delete Group \"{{ dsoName }}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.delete-group.modal.header": "Delete Group \"{{ dsoName }}\"", + + // "admin.access-control.groups.form.delete-group.modal.info": "Are you sure you want to delete Group \"{{ dsoName }}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.delete-group.modal.info": "Are you sure you want to delete Group \"{{ dsoName }}\"", + + // "admin.access-control.groups.form.delete-group.modal.cancel": "Cancel", + // TODO New key - Add a translation + "admin.access-control.groups.form.delete-group.modal.cancel": "Cancel", + + // "admin.access-control.groups.form.delete-group.modal.confirm": "Delete", + // TODO New key - Add a translation + "admin.access-control.groups.form.delete-group.modal.confirm": "Delete", + + // "admin.access-control.groups.form.notification.deleted.success": "Successfully deleted group \"{{ name }}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.notification.deleted.success": "Successfully deleted group \"{{ name }}\"", + + // "admin.access-control.groups.form.notification.deleted.failure.title": "Failed to delete group \"{{ name }}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.notification.deleted.failure.title": "Failed to delete group \"{{ name }}\"", + + // "admin.access-control.groups.form.notification.deleted.failure.content": "Cause: \"{{ cause }}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.notification.deleted.failure.content": "Cause: \"{{ cause }}\"", + + // "admin.access-control.groups.form.members-list.head": "EPeople", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.head": "EPeople", + + // "admin.access-control.groups.form.members-list.search.head": "Add EPeople", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.search.head": "Add EPeople", + + // "admin.access-control.groups.form.members-list.button.see-all": "Browse All", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.button.see-all": "Browse All", + + // "admin.access-control.groups.form.members-list.headMembers": "Current Members", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.headMembers": "Current Members", + + // "admin.access-control.groups.form.members-list.search.scope.metadata": "Metadata", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.search.scope.metadata": "Metadata", + + // "admin.access-control.groups.form.members-list.search.scope.email": "E-mail (exact)", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.search.scope.email": "E-mail (exact)", + + // "admin.access-control.groups.form.members-list.search.button": "Search", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.search.button": "Search", + + // "admin.access-control.groups.form.members-list.table.id": "ID", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.table.id": "ID", + + // "admin.access-control.groups.form.members-list.table.name": "Name", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.table.name": "Name", + + // "admin.access-control.groups.form.members-list.table.edit": "Remove / Add", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.table.edit": "Remove / Add", + + // "admin.access-control.groups.form.members-list.table.edit.buttons.remove": "Remove member with name \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.table.edit.buttons.remove": "Remove member with name \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.notification.success.addMember": "Successfully added member: \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.notification.success.addMember": "Successfully added member: \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.notification.failure.addMember": "Failed to add member: \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.notification.failure.addMember": "Failed to add member: \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.notification.success.deleteMember": "Successfully deleted member: \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.notification.success.deleteMember": "Successfully deleted member: \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.notification.failure.deleteMember": "Failed to delete member: \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.notification.failure.deleteMember": "Failed to delete member: \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.table.edit.buttons.add": "Add member with name \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.table.edit.buttons.add": "Add member with name \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", + + // "admin.access-control.groups.form.members-list.no-members-yet": "No members in group yet, search and add.", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.no-members-yet": "No members in group yet, search and add.", + + // "admin.access-control.groups.form.members-list.no-items": "No EPeople found in that search", + // TODO New key - Add a translation + "admin.access-control.groups.form.members-list.no-items": "No EPeople found in that search", + + // "admin.access-control.groups.form.subgroups-list.notification.failure": "Something went wrong: \"{{cause}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.notification.failure": "Something went wrong: \"{{cause}}\"", + + // "admin.access-control.groups.form.subgroups-list.head": "Groups", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.head": "Groups", + + // "admin.access-control.groups.form.subgroups-list.search.head": "Add Subgroup", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.search.head": "Add Subgroup", + + // "admin.access-control.groups.form.subgroups-list.button.see-all": "Browse All", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.button.see-all": "Browse All", + + // "admin.access-control.groups.form.subgroups-list.headSubgroups": "Current Subgroups", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.headSubgroups": "Current Subgroups", + + // "admin.access-control.groups.form.subgroups-list.search.button": "Search", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.search.button": "Search", + + // "admin.access-control.groups.form.subgroups-list.table.id": "ID", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.table.id": "ID", + + // "admin.access-control.groups.form.subgroups-list.table.name": "Name", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.table.name": "Name", + + // "admin.access-control.groups.form.subgroups-list.table.edit": "Remove / Add", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.table.edit": "Remove / Add", + + // "admin.access-control.groups.form.subgroups-list.table.edit.buttons.remove": "Remove subgroup with name \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.table.edit.buttons.remove": "Remove subgroup with name \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.table.edit.buttons.add": "Add subgroup with name \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.table.edit.buttons.add": "Add subgroup with name \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.table.edit.currentGroup": "Current group", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.table.edit.currentGroup": "Current group", + + // "admin.access-control.groups.form.subgroups-list.notification.success.addSubgroup": "Successfully added subgroup: \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.notification.success.addSubgroup": "Successfully added subgroup: \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.notification.failure.addSubgroup": "Failed to add subgroup: \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.notification.failure.addSubgroup": "Failed to add subgroup: \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.notification.success.deleteSubgroup": "Successfully deleted subgroup: \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.notification.success.deleteSubgroup": "Successfully deleted subgroup: \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.notification.failure.deleteSubgroup": "Failed to delete subgroup: \"{{name}}\"", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.notification.failure.deleteSubgroup": "Failed to delete subgroup: \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", + + // "admin.access-control.groups.form.subgroups-list.notification.failure.subgroupToAddIsActiveGroup": "This is the current group, can't be added.", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.notification.failure.subgroupToAddIsActiveGroup": "This is the current group, can't be added.", + + // "admin.access-control.groups.form.subgroups-list.no-items": "No groups found with this in their name or this as UUID", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.no-items": "No groups found with this in their name or this as UUID", + + // "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "No subgroups in group yet.", + // TODO New key - Add a translation + "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "No subgroups in group yet.", + + // "admin.access-control.groups.form.return": "Return to groups", + // TODO New key - Add a translation + "admin.access-control.groups.form.return": "Return to groups", + + + + // "admin.search.breadcrumbs": "Administrative Search", + // TODO New key - Add a translation + "admin.search.breadcrumbs": "Administrative Search", + + // "admin.search.collection.edit": "Edit", + // TODO New key - Add a translation + "admin.search.collection.edit": "Edit", + + // "admin.search.community.edit": "Edit", + // TODO New key - Add a translation + "admin.search.community.edit": "Edit", + + // "admin.search.item.delete": "Delete", + // TODO New key - Add a translation + "admin.search.item.delete": "Delete", + + // "admin.search.item.edit": "Edit", + // TODO New key - Add a translation + "admin.search.item.edit": "Edit", + + // "admin.search.item.make-private": "Make Private", + // TODO New key - Add a translation + "admin.search.item.make-private": "Make Private", + + // "admin.search.item.make-public": "Make Public", + // TODO New key - Add a translation + "admin.search.item.make-public": "Make Public", + + // "admin.search.item.move": "Move", + // TODO New key - Add a translation + "admin.search.item.move": "Move", + + // "admin.search.item.reinstate": "Reinstate", + // TODO New key - Add a translation + "admin.search.item.reinstate": "Reinstate", + + // "admin.search.item.withdraw": "Withdraw", + // TODO New key - Add a translation + "admin.search.item.withdraw": "Withdraw", + + // "admin.search.title": "Administrative Search", + // TODO New key - Add a translation + "admin.search.title": "Administrative Search", + + // "administrativeView.search.results.head": "Administrative Search", + // TODO New key - Add a translation + "administrativeView.search.results.head": "Administrative Search", + + + + + // "admin.workflow.breadcrumbs": "Administer Workflow", + // TODO New key - Add a translation + "admin.workflow.breadcrumbs": "Administer Workflow", + + // "admin.workflow.title": "Administer Workflow", + // TODO New key - Add a translation + "admin.workflow.title": "Administer Workflow", + + // "admin.workflow.item.workflow": "Workflow", + // TODO New key - Add a translation + "admin.workflow.item.workflow": "Workflow", + + // "admin.workflow.item.delete": "Delete", + // TODO New key - Add a translation + "admin.workflow.item.delete": "Delete", + + // "admin.workflow.item.send-back": "Send back", + // TODO New key - Add a translation + "admin.workflow.item.send-back": "Send back", + + + + // "admin.metadata-import.breadcrumbs": "Import Metadata", + // TODO New key - Add a translation + "admin.metadata-import.breadcrumbs": "Import Metadata", + + // "admin.metadata-import.title": "Import Metadata", + // TODO New key - Add a translation + "admin.metadata-import.title": "Import Metadata", + + // "admin.metadata-import.page.header": "Import Metadata", + // TODO New key - Add a translation + "admin.metadata-import.page.header": "Import Metadata", + + // "admin.metadata-import.page.help": "You can drop or browse CSV files that contain batch metadata operations on files here", + // TODO New key - Add a translation + "admin.metadata-import.page.help": "You can drop or browse CSV files that contain batch metadata operations on files here", + + // "admin.metadata-import.page.dropMsg": "Drop a metadata CSV to import", + // TODO New key - Add a translation + "admin.metadata-import.page.dropMsg": "Drop a metadata CSV to import", + + // "admin.metadata-import.page.dropMsgReplace": "Drop to replace the metadata CSV to import", + // TODO New key - Add a translation + "admin.metadata-import.page.dropMsgReplace": "Drop to replace the metadata CSV to import", + + // "admin.metadata-import.page.button.return": "Return", + // TODO New key - Add a translation + "admin.metadata-import.page.button.return": "Return", + + // "admin.metadata-import.page.button.proceed": "Proceed", + // TODO New key - Add a translation + "admin.metadata-import.page.button.proceed": "Proceed", + + // "admin.metadata-import.page.error.addFile": "Select file first!", + // TODO New key - Add a translation + "admin.metadata-import.page.error.addFile": "Select file first!", + + + + + // "auth.errors.invalid-user": "Invalid email address or password.", + // TODO New key - Add a translation + "auth.errors.invalid-user": "Invalid email address or password.", + + // "auth.messages.expired": "Your session has expired. Please log in again.", + // TODO New key - Add a translation + "auth.messages.expired": "Your session has expired. Please log in again.", + + + + // "bitstream.edit.bitstream": "Bitstream: ", + // TODO New key - Add a translation + "bitstream.edit.bitstream": "Bitstream: ", + + // "bitstream.edit.form.description.hint": "Optionally, provide a brief description of the file, for example \"Main article\" or \"Experiment data readings\".", + // TODO New key - Add a translation + "bitstream.edit.form.description.hint": "Optionally, provide a brief description of the file, for example \"Main article\" or \"Experiment data readings\".", + + // "bitstream.edit.form.description.label": "Description", + // TODO New key - Add a translation + "bitstream.edit.form.description.label": "Description", + + // "bitstream.edit.form.embargo.hint": "The first day from which access is allowed. This date cannot be modified on this form. To set an embargo date for a bitstream, go to the Item Status tab, click Authorizations..., create or edit the bitstream's READ policy, and set the Start Date as desired.", + // TODO New key - Add a translation + "bitstream.edit.form.embargo.hint": "The first day from which access is allowed. This date cannot be modified on this form. To set an embargo date for a bitstream, go to the Item Status tab, click Authorizations..., create or edit the bitstream's READ policy, and set the Start Date as desired.", + + // "bitstream.edit.form.embargo.label": "Embargo until specific date", + // TODO New key - Add a translation + "bitstream.edit.form.embargo.label": "Embargo until specific date", + + // "bitstream.edit.form.fileName.hint": "Change the filename for the bitstream. Note that this will change the display bitstream URL, but old links will still resolve as long as the sequence ID does not change.", + // TODO New key - Add a translation + "bitstream.edit.form.fileName.hint": "Change the filename for the bitstream. Note that this will change the display bitstream URL, but old links will still resolve as long as the sequence ID does not change.", + + // "bitstream.edit.form.fileName.label": "Filename", + // TODO New key - Add a translation + "bitstream.edit.form.fileName.label": "Filename", + + // "bitstream.edit.form.newFormat.label": "Describe new format", + // TODO New key - Add a translation + "bitstream.edit.form.newFormat.label": "Describe new format", + + // "bitstream.edit.form.newFormat.hint": "The application you used to create the file, and the version number (for example, \"ACMESoft SuperApp version 1.5\").", + // TODO New key - Add a translation + "bitstream.edit.form.newFormat.hint": "The application you used to create the file, and the version number (for example, \"ACMESoft SuperApp version 1.5\").", + + // "bitstream.edit.form.primaryBitstream.label": "Primary bitstream", + // TODO New key - Add a translation + "bitstream.edit.form.primaryBitstream.label": "Primary bitstream", + + // "bitstream.edit.form.selectedFormat.hint": "If the format is not in the above list, select \"format not in list\" above and describe it under \"Describe new format\".", + // TODO New key - Add a translation + "bitstream.edit.form.selectedFormat.hint": "If the format is not in the above list, select \"format not in list\" above and describe it under \"Describe new format\".", + + // "bitstream.edit.form.selectedFormat.label": "Selected Format", + // TODO New key - Add a translation + "bitstream.edit.form.selectedFormat.label": "Selected Format", + + // "bitstream.edit.form.selectedFormat.unknown": "Format not in list", + // TODO New key - Add a translation + "bitstream.edit.form.selectedFormat.unknown": "Format not in list", + + // "bitstream.edit.notifications.error.format.title": "An error occurred saving the bitstream's format", + // TODO New key - Add a translation + "bitstream.edit.notifications.error.format.title": "An error occurred saving the bitstream's format", + + // "bitstream.edit.notifications.saved.content": "Your changes to this bitstream were saved.", + // TODO New key - Add a translation + "bitstream.edit.notifications.saved.content": "Your changes to this bitstream were saved.", + + // "bitstream.edit.notifications.saved.title": "Bitstream saved", + // TODO New key - Add a translation + "bitstream.edit.notifications.saved.title": "Bitstream saved", + + // "bitstream.edit.title": "Edit bitstream", + // TODO New key - Add a translation + "bitstream.edit.title": "Edit bitstream", + + + + // "browse.comcol.by.author": "By Author", + // TODO New key - Add a translation + "browse.comcol.by.author": "By Author", + + // "browse.comcol.by.dateissued": "By Issue Date", + // TODO New key - Add a translation + "browse.comcol.by.dateissued": "By Issue Date", + + // "browse.comcol.by.subject": "By Subject", + // TODO New key - Add a translation + "browse.comcol.by.subject": "By Subject", + + // "browse.comcol.by.title": "By Title", + // TODO New key - Add a translation + "browse.comcol.by.title": "By Title", + + // "browse.comcol.head": "Browse", + // TODO New key - Add a translation + "browse.comcol.head": "Browse", + + // "browse.empty": "No items to show.", + // TODO New key - Add a translation + "browse.empty": "No items to show.", + + // "browse.metadata.author": "Author", + // TODO New key - Add a translation + "browse.metadata.author": "Author", + + // "browse.metadata.dateissued": "Issue Date", + // TODO New key - Add a translation + "browse.metadata.dateissued": "Issue Date", + + // "browse.metadata.subject": "Subject", + // TODO New key - Add a translation + "browse.metadata.subject": "Subject", + + // "browse.metadata.title": "Title", + // TODO New key - Add a translation + "browse.metadata.title": "Title", + + // "browse.metadata.author.breadcrumbs": "Browse by Author", + // TODO New key - Add a translation + "browse.metadata.author.breadcrumbs": "Browse by Author", + + // "browse.metadata.dateissued.breadcrumbs": "Browse by Date", + // TODO New key - Add a translation + "browse.metadata.dateissued.breadcrumbs": "Browse by Date", + + // "browse.metadata.subject.breadcrumbs": "Browse by Subject", + // TODO New key - Add a translation + "browse.metadata.subject.breadcrumbs": "Browse by Subject", + + // "browse.metadata.title.breadcrumbs": "Browse by Title", + // TODO New key - Add a translation + "browse.metadata.title.breadcrumbs": "Browse by Title", + + // "browse.startsWith.choose_start": "(Choose start)", + // TODO New key - Add a translation + "browse.startsWith.choose_start": "(Choose start)", + + // "browse.startsWith.choose_year": "(Choose year)", + // TODO New key - Add a translation + "browse.startsWith.choose_year": "(Choose year)", + + // "browse.startsWith.jump": "Jump to a point in the index:", + // TODO New key - Add a translation + "browse.startsWith.jump": "Jump to a point in the index:", + + // "browse.startsWith.months.april": "April", + // TODO New key - Add a translation + "browse.startsWith.months.april": "April", + + // "browse.startsWith.months.august": "August", + // TODO New key - Add a translation + "browse.startsWith.months.august": "August", + + // "browse.startsWith.months.december": "December", + // TODO New key - Add a translation + "browse.startsWith.months.december": "December", + + // "browse.startsWith.months.february": "February", + // TODO New key - Add a translation + "browse.startsWith.months.february": "February", + + // "browse.startsWith.months.january": "January", + // TODO New key - Add a translation + "browse.startsWith.months.january": "January", + + // "browse.startsWith.months.july": "July", + // TODO New key - Add a translation + "browse.startsWith.months.july": "July", + + // "browse.startsWith.months.june": "June", + // TODO New key - Add a translation + "browse.startsWith.months.june": "June", + + // "browse.startsWith.months.march": "March", + // TODO New key - Add a translation + "browse.startsWith.months.march": "March", + + // "browse.startsWith.months.may": "May", + // TODO New key - Add a translation + "browse.startsWith.months.may": "May", + + // "browse.startsWith.months.none": "(Choose month)", + // TODO New key - Add a translation + "browse.startsWith.months.none": "(Choose month)", + + // "browse.startsWith.months.november": "November", + // TODO New key - Add a translation + "browse.startsWith.months.november": "November", + + // "browse.startsWith.months.october": "October", + // TODO New key - Add a translation + "browse.startsWith.months.october": "October", + + // "browse.startsWith.months.september": "September", + // TODO New key - Add a translation + "browse.startsWith.months.september": "September", + + // "browse.startsWith.submit": "Go", + // TODO New key - Add a translation + "browse.startsWith.submit": "Go", + + // "browse.startsWith.type_date": "Or type in a date (year-month):", + // TODO New key - Add a translation + "browse.startsWith.type_date": "Or type in a date (year-month):", + + // "browse.startsWith.type_text": "Or enter first few letters:", + // TODO New key - Add a translation + "browse.startsWith.type_text": "Or enter first few letters:", + + // "browse.title": "Browsing {{ collection }} by {{ field }} {{ value }}", + // TODO New key - Add a translation + "browse.title": "Browsing {{ collection }} by {{ field }} {{ value }}", + + + // "chips.remove": "Remove chip", + // TODO New key - Add a translation + "chips.remove": "Remove chip", + + + + // "collection.create.head": "Create a Collection", + // TODO New key - Add a translation + "collection.create.head": "Create a Collection", + + // "collection.create.notifications.success": "Successfully created the Collection", + // TODO New key - Add a translation + "collection.create.notifications.success": "Successfully created the Collection", + + // "collection.create.sub-head": "Create a Collection for Community {{ parent }}", + // TODO New key - Add a translation + "collection.create.sub-head": "Create a Collection for Community {{ parent }}", + + // "collection.curate.header": "Curate Collection: {{collection}}", + // TODO New key - Add a translation + "collection.curate.header": "Curate Collection: {{collection}}", + + // "collection.delete.cancel": "Cancel", + // TODO New key - Add a translation + "collection.delete.cancel": "Cancel", + + // "collection.delete.confirm": "Confirm", + // TODO New key - Add a translation + "collection.delete.confirm": "Confirm", + + // "collection.delete.head": "Delete Collection", + // TODO New key - Add a translation + "collection.delete.head": "Delete Collection", + + // "collection.delete.notification.fail": "Collection could not be deleted", + // TODO New key - Add a translation + "collection.delete.notification.fail": "Collection could not be deleted", + + // "collection.delete.notification.success": "Successfully deleted collection", + // TODO New key - Add a translation + "collection.delete.notification.success": "Successfully deleted collection", + + // "collection.delete.text": "Are you sure you want to delete collection \"{{ dso }}\"", + // TODO New key - Add a translation + "collection.delete.text": "Are you sure you want to delete collection \"{{ dso }}\"", + + + + // "collection.edit.delete": "Delete this collection", + // TODO New key - Add a translation + "collection.edit.delete": "Delete this collection", + + // "collection.edit.head": "Edit Collection", + // TODO New key - Add a translation + "collection.edit.head": "Edit Collection", + + // "collection.edit.breadcrumbs": "Edit Collection", + // TODO New key - Add a translation + "collection.edit.breadcrumbs": "Edit Collection", + + + + // "collection.edit.tabs.mapper.head": "Item Mapper", + // TODO New key - Add a translation + "collection.edit.tabs.mapper.head": "Item Mapper", + + // "collection.edit.tabs.item-mapper.title": "Collection Edit - Item Mapper", + // TODO New key - Add a translation + "collection.edit.tabs.item-mapper.title": "Collection Edit - Item Mapper", + + // "collection.edit.item-mapper.cancel": "Cancel", + // TODO New key - Add a translation + "collection.edit.item-mapper.cancel": "Cancel", + + // "collection.edit.item-mapper.collection": "Collection: \"{{name}}\"", + // TODO New key - Add a translation + "collection.edit.item-mapper.collection": "Collection: \"{{name}}\"", + + // "collection.edit.item-mapper.confirm": "Map selected items", + // TODO New key - Add a translation + "collection.edit.item-mapper.confirm": "Map selected items", + + // "collection.edit.item-mapper.description": "This is the item mapper tool that allows collection administrators to map items from other collections into this collection. You can search for items from other collections and map them, or browse the list of currently mapped items.", + // TODO New key - Add a translation + "collection.edit.item-mapper.description": "This is the item mapper tool that allows collection administrators to map items from other collections into this collection. You can search for items from other collections and map them, or browse the list of currently mapped items.", + + // "collection.edit.item-mapper.head": "Item Mapper - Map Items from Other Collections", + // TODO New key - Add a translation + "collection.edit.item-mapper.head": "Item Mapper - Map Items from Other Collections", + + // "collection.edit.item-mapper.no-search": "Please enter a query to search", + // TODO New key - Add a translation + "collection.edit.item-mapper.no-search": "Please enter a query to search", + + // "collection.edit.item-mapper.notifications.map.error.content": "Errors occurred for mapping of {{amount}} items.", + // TODO New key - Add a translation + "collection.edit.item-mapper.notifications.map.error.content": "Errors occurred for mapping of {{amount}} items.", + + // "collection.edit.item-mapper.notifications.map.error.head": "Mapping errors", + // TODO New key - Add a translation + "collection.edit.item-mapper.notifications.map.error.head": "Mapping errors", + + // "collection.edit.item-mapper.notifications.map.success.content": "Successfully mapped {{amount}} items.", + // TODO New key - Add a translation + "collection.edit.item-mapper.notifications.map.success.content": "Successfully mapped {{amount}} items.", + + // "collection.edit.item-mapper.notifications.map.success.head": "Mapping completed", + // TODO New key - Add a translation + "collection.edit.item-mapper.notifications.map.success.head": "Mapping completed", + + // "collection.edit.item-mapper.notifications.unmap.error.content": "Errors occurred for removing the mappings of {{amount}} items.", + // TODO New key - Add a translation + "collection.edit.item-mapper.notifications.unmap.error.content": "Errors occurred for removing the mappings of {{amount}} items.", + + // "collection.edit.item-mapper.notifications.unmap.error.head": "Remove mapping errors", + // TODO New key - Add a translation + "collection.edit.item-mapper.notifications.unmap.error.head": "Remove mapping errors", + + // "collection.edit.item-mapper.notifications.unmap.success.content": "Successfully removed the mappings of {{amount}} items.", + // TODO New key - Add a translation + "collection.edit.item-mapper.notifications.unmap.success.content": "Successfully removed the mappings of {{amount}} items.", + + // "collection.edit.item-mapper.notifications.unmap.success.head": "Remove mapping completed", + // TODO New key - Add a translation + "collection.edit.item-mapper.notifications.unmap.success.head": "Remove mapping completed", + + // "collection.edit.item-mapper.remove": "Remove selected item mappings", + // TODO New key - Add a translation + "collection.edit.item-mapper.remove": "Remove selected item mappings", + + // "collection.edit.item-mapper.tabs.browse": "Browse mapped items", + // TODO New key - Add a translation + "collection.edit.item-mapper.tabs.browse": "Browse mapped items", + + // "collection.edit.item-mapper.tabs.map": "Map new items", + // TODO New key - Add a translation + "collection.edit.item-mapper.tabs.map": "Map new items", + + + + // "collection.edit.logo.label": "Collection logo", + // TODO New key - Add a translation + "collection.edit.logo.label": "Collection logo", + + // "collection.edit.logo.notifications.add.error": "Uploading Collection logo failed. Please verify the content before retrying.", + // TODO New key - Add a translation + "collection.edit.logo.notifications.add.error": "Uploading Collection logo failed. Please verify the content before retrying.", + + // "collection.edit.logo.notifications.add.success": "Upload Collection logo successful.", + // TODO New key - Add a translation + "collection.edit.logo.notifications.add.success": "Upload Collection logo successful.", + + // "collection.edit.logo.notifications.delete.success.title": "Logo deleted", + // TODO New key - Add a translation + "collection.edit.logo.notifications.delete.success.title": "Logo deleted", + + // "collection.edit.logo.notifications.delete.success.content": "Successfully deleted the collection's logo", + // TODO New key - Add a translation + "collection.edit.logo.notifications.delete.success.content": "Successfully deleted the collection's logo", + + // "collection.edit.logo.notifications.delete.error.title": "Error deleting logo", + // TODO New key - Add a translation + "collection.edit.logo.notifications.delete.error.title": "Error deleting logo", + + // "collection.edit.logo.upload": "Drop a Collection Logo to upload", + // TODO New key - Add a translation + "collection.edit.logo.upload": "Drop a Collection Logo to upload", + + + + // "collection.edit.notifications.success": "Successfully edited the Collection", + // TODO New key - Add a translation + "collection.edit.notifications.success": "Successfully edited the Collection", + + // "collection.edit.return": "Return", + // TODO New key - Add a translation + "collection.edit.return": "Return", + + + + // "collection.edit.tabs.curate.head": "Curate", + // TODO New key - Add a translation + "collection.edit.tabs.curate.head": "Curate", + + // "collection.edit.tabs.curate.title": "Collection Edit - Curate", + // TODO New key - Add a translation + "collection.edit.tabs.curate.title": "Collection Edit - Curate", + + // "collection.edit.tabs.authorizations.head": "Authorizations", + // TODO New key - Add a translation + "collection.edit.tabs.authorizations.head": "Authorizations", + + // "collection.edit.tabs.authorizations.title": "Collection Edit - Authorizations", + // TODO New key - Add a translation + "collection.edit.tabs.authorizations.title": "Collection Edit - Authorizations", + + // "collection.edit.tabs.metadata.head": "Edit Metadata", + // TODO New key - Add a translation + "collection.edit.tabs.metadata.head": "Edit Metadata", + + // "collection.edit.tabs.metadata.title": "Collection Edit - Metadata", + // TODO New key - Add a translation + "collection.edit.tabs.metadata.title": "Collection Edit - Metadata", + + // "collection.edit.tabs.roles.head": "Assign Roles", + // TODO New key - Add a translation + "collection.edit.tabs.roles.head": "Assign Roles", + + // "collection.edit.tabs.roles.title": "Collection Edit - Roles", + // TODO New key - Add a translation + "collection.edit.tabs.roles.title": "Collection Edit - Roles", + + // "collection.edit.tabs.source.external": "This collection harvests its content from an external source", + // TODO New key - Add a translation + "collection.edit.tabs.source.external": "This collection harvests its content from an external source", + + // "collection.edit.tabs.source.form.errors.oaiSource.required": "You must provide a set id of the target collection.", + // TODO New key - Add a translation + "collection.edit.tabs.source.form.errors.oaiSource.required": "You must provide a set id of the target collection.", + + // "collection.edit.tabs.source.form.harvestType": "Content being harvested", + // TODO New key - Add a translation + "collection.edit.tabs.source.form.harvestType": "Content being harvested", + + // "collection.edit.tabs.source.form.head": "Configure an external source", + // TODO New key - Add a translation + "collection.edit.tabs.source.form.head": "Configure an external source", + + // "collection.edit.tabs.source.form.metadataConfigId": "Metadata Format", + // TODO New key - Add a translation + "collection.edit.tabs.source.form.metadataConfigId": "Metadata Format", + + // "collection.edit.tabs.source.form.oaiSetId": "OAI specific set id", + // TODO New key - Add a translation + "collection.edit.tabs.source.form.oaiSetId": "OAI specific set id", + + // "collection.edit.tabs.source.form.oaiSource": "OAI Provider", + // TODO New key - Add a translation + "collection.edit.tabs.source.form.oaiSource": "OAI Provider", + + // "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_BITSTREAMS": "Harvest metadata and bitstreams (requires ORE support)", + // TODO New key - Add a translation + "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_BITSTREAMS": "Harvest metadata and bitstreams (requires ORE support)", + + // "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_REF": "Harvest metadata and references to bitstreams (requires ORE support)", + // TODO New key - Add a translation + "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_REF": "Harvest metadata and references to bitstreams (requires ORE support)", + + // "collection.edit.tabs.source.form.options.harvestType.METADATA_ONLY": "Harvest metadata only", + // TODO New key - Add a translation + "collection.edit.tabs.source.form.options.harvestType.METADATA_ONLY": "Harvest metadata only", + + // "collection.edit.tabs.source.head": "Content Source", + // TODO New key - Add a translation + "collection.edit.tabs.source.head": "Content Source", + + // "collection.edit.tabs.source.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + // TODO New key - Add a translation + "collection.edit.tabs.source.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + + // "collection.edit.tabs.source.notifications.discarded.title": "Changed discarded", + // TODO New key - Add a translation + "collection.edit.tabs.source.notifications.discarded.title": "Changed discarded", + + // "collection.edit.tabs.source.notifications.invalid.content": "Your changes were not saved. Please make sure all fields are valid before you save.", + // TODO New key - Add a translation + "collection.edit.tabs.source.notifications.invalid.content": "Your changes were not saved. Please make sure all fields are valid before you save.", + + // "collection.edit.tabs.source.notifications.invalid.title": "Metadata invalid", + // TODO New key - Add a translation + "collection.edit.tabs.source.notifications.invalid.title": "Metadata invalid", + + // "collection.edit.tabs.source.notifications.saved.content": "Your changes to this collection's content source were saved.", + // TODO New key - Add a translation + "collection.edit.tabs.source.notifications.saved.content": "Your changes to this collection's content source were saved.", + + // "collection.edit.tabs.source.notifications.saved.title": "Content Source saved", + // TODO New key - Add a translation + "collection.edit.tabs.source.notifications.saved.title": "Content Source saved", + + // "collection.edit.tabs.source.title": "Collection Edit - Content Source", + // TODO New key - Add a translation + "collection.edit.tabs.source.title": "Collection Edit - Content Source", + + + + // "collection.edit.template.add-button": "Add", + // TODO New key - Add a translation + "collection.edit.template.add-button": "Add", + + // "collection.edit.template.breadcrumbs": "Item template", + // TODO New key - Add a translation + "collection.edit.template.breadcrumbs": "Item template", + + // "collection.edit.template.cancel": "Cancel", + // TODO New key - Add a translation + "collection.edit.template.cancel": "Cancel", + + // "collection.edit.template.delete-button": "Delete", + // TODO New key - Add a translation + "collection.edit.template.delete-button": "Delete", + + // "collection.edit.template.edit-button": "Edit", + // TODO New key - Add a translation + "collection.edit.template.edit-button": "Edit", + + // "collection.edit.template.head": "Edit Template Item for Collection \"{{ collection }}\"", + // TODO New key - Add a translation + "collection.edit.template.head": "Edit Template Item for Collection \"{{ collection }}\"", + + // "collection.edit.template.label": "Template item", + // TODO New key - Add a translation + "collection.edit.template.label": "Template item", + + // "collection.edit.template.notifications.delete.error": "Failed to delete the item template", + // TODO New key - Add a translation + "collection.edit.template.notifications.delete.error": "Failed to delete the item template", + + // "collection.edit.template.notifications.delete.success": "Successfully deleted the item template", + // TODO New key - Add a translation + "collection.edit.template.notifications.delete.success": "Successfully deleted the item template", + + // "collection.edit.template.title": "Edit Template Item", + // TODO New key - Add a translation + "collection.edit.template.title": "Edit Template Item", + + + + // "collection.form.abstract": "Short Description", + // TODO New key - Add a translation + "collection.form.abstract": "Short Description", + + // "collection.form.description": "Introductory text (HTML)", + // TODO New key - Add a translation + "collection.form.description": "Introductory text (HTML)", + + // "collection.form.errors.title.required": "Please enter a collection name", + // TODO New key - Add a translation + "collection.form.errors.title.required": "Please enter a collection name", + + // "collection.form.license": "License", + // TODO New key - Add a translation + "collection.form.license": "License", + + // "collection.form.provenance": "Provenance", + // TODO New key - Add a translation + "collection.form.provenance": "Provenance", + + // "collection.form.rights": "Copyright text (HTML)", + // TODO New key - Add a translation + "collection.form.rights": "Copyright text (HTML)", + + // "collection.form.tableofcontents": "News (HTML)", + // TODO New key - Add a translation + "collection.form.tableofcontents": "News (HTML)", + + // "collection.form.title": "Name", + // TODO New key - Add a translation + "collection.form.title": "Name", + + + + // "collection.listelement.badge": "Collection", + // TODO New key - Add a translation + "collection.listelement.badge": "Collection", + + + + // "collection.page.browse.recent.head": "Recent Submissions", + // TODO New key - Add a translation + "collection.page.browse.recent.head": "Recent Submissions", + + // "collection.page.browse.recent.empty": "No items to show", + // TODO New key - Add a translation + "collection.page.browse.recent.empty": "No items to show", + + // "collection.page.edit": "Edit this collection", + // TODO New key - Add a translation + "collection.page.edit": "Edit this collection", + + // "collection.page.handle": "Permanent URI for this collection", + // TODO New key - Add a translation + "collection.page.handle": "Permanent URI for this collection", + + // "collection.page.license": "License", + // TODO New key - Add a translation + "collection.page.license": "License", + + // "collection.page.news": "News", + "collection.page.news": "Жаңалықтар", + + + + // "collection.select.confirm": "Confirm selected", + // TODO New key - Add a translation + "collection.select.confirm": "Confirm selected", + + // "collection.select.empty": "No collections to show", + // TODO New key - Add a translation + "collection.select.empty": "No collections to show", + + // "collection.select.table.title": "Title", + // TODO New key - Add a translation + "collection.select.table.title": "Title", + + + + // "collection.source.update.notifications.error.content": "The provided settings have been tested and didn't work.", + // TODO New key - Add a translation + "collection.source.update.notifications.error.content": "The provided settings have been tested and didn't work.", + + // "collection.source.update.notifications.error.title": "Server Error", + // TODO New key - Add a translation + "collection.source.update.notifications.error.title": "Server Error", + + + + // "communityList.tabTitle": "DSpace - Community List", + // TODO New key - Add a translation + "communityList.tabTitle": "DSpace - Community List", + + // "communityList.title": "List of Communities", + // TODO New key - Add a translation + "communityList.title": "List of Communities", + + // "communityList.showMore": "Show More", + // TODO New key - Add a translation + "communityList.showMore": "Show More", + + + + // "community.create.head": "Create a Community", + // TODO New key - Add a translation + "community.create.head": "Create a Community", + + // "community.create.notifications.success": "Successfully created the Community", + // TODO New key - Add a translation + "community.create.notifications.success": "Successfully created the Community", + + // "community.create.sub-head": "Create a Sub-Community for Community {{ parent }}", + // TODO New key - Add a translation + "community.create.sub-head": "Create a Sub-Community for Community {{ parent }}", + + // "community.curate.header": "Curate Community: {{community}}", + // TODO New key - Add a translation + "community.curate.header": "Curate Community: {{community}}", + + // "community.delete.cancel": "Cancel", + // TODO New key - Add a translation + "community.delete.cancel": "Cancel", + + // "community.delete.confirm": "Confirm", + // TODO New key - Add a translation + "community.delete.confirm": "Confirm", + + // "community.delete.head": "Delete Community", + // TODO New key - Add a translation + "community.delete.head": "Delete Community", + + // "community.delete.notification.fail": "Community could not be deleted", + // TODO New key - Add a translation + "community.delete.notification.fail": "Community could not be deleted", + + // "community.delete.notification.success": "Successfully deleted community", + // TODO New key - Add a translation + "community.delete.notification.success": "Successfully deleted community", + + // "community.delete.text": "Are you sure you want to delete community \"{{ dso }}\"", + // TODO New key - Add a translation + "community.delete.text": "Are you sure you want to delete community \"{{ dso }}\"", + + // "community.edit.delete": "Delete this community", + // TODO New key - Add a translation + "community.edit.delete": "Delete this community", + + // "community.edit.head": "Edit Community", + // TODO New key - Add a translation + "community.edit.head": "Edit Community", + + // "community.edit.breadcrumbs": "Edit Community", + // TODO New key - Add a translation + "community.edit.breadcrumbs": "Edit Community", + + + // "community.edit.logo.label": "Community logo", + // TODO New key - Add a translation + "community.edit.logo.label": "Community logo", + + // "community.edit.logo.notifications.add.error": "Uploading Community logo failed. Please verify the content before retrying.", + // TODO New key - Add a translation + "community.edit.logo.notifications.add.error": "Uploading Community logo failed. Please verify the content before retrying.", + + // "community.edit.logo.notifications.add.success": "Upload Community logo successful.", + // TODO New key - Add a translation + "community.edit.logo.notifications.add.success": "Upload Community logo successful.", + + // "community.edit.logo.notifications.delete.success.title": "Logo deleted", + // TODO New key - Add a translation + "community.edit.logo.notifications.delete.success.title": "Logo deleted", + + // "community.edit.logo.notifications.delete.success.content": "Successfully deleted the community's logo", + // TODO New key - Add a translation + "community.edit.logo.notifications.delete.success.content": "Successfully deleted the community's logo", + + // "community.edit.logo.notifications.delete.error.title": "Error deleting logo", + // TODO New key - Add a translation + "community.edit.logo.notifications.delete.error.title": "Error deleting logo", + + // "community.edit.logo.upload": "Drop a Community Logo to upload", + // TODO New key - Add a translation + "community.edit.logo.upload": "Drop a Community Logo to upload", + + + + // "community.edit.notifications.success": "Successfully edited the Community", + // TODO New key - Add a translation + "community.edit.notifications.success": "Successfully edited the Community", + + // "community.edit.notifications.unauthorized": "You do not have privileges to make this change", + // TODO New key - Add a translation + "community.edit.notifications.unauthorized": "You do not have privileges to make this change", + + // "community.edit.notifications.error": "An error occured while editing the Community", + // TODO New key - Add a translation + "community.edit.notifications.error": "An error occured while editing the Community", + + // "community.edit.return": "Return", + // TODO New key - Add a translation + "community.edit.return": "Return", + + + + // "community.edit.tabs.curate.head": "Curate", + // TODO New key - Add a translation + "community.edit.tabs.curate.head": "Curate", + + // "community.edit.tabs.curate.title": "Community Edit - Curate", + // TODO New key - Add a translation + "community.edit.tabs.curate.title": "Community Edit - Curate", + + // "community.edit.tabs.metadata.head": "Edit Metadata", + // TODO New key - Add a translation + "community.edit.tabs.metadata.head": "Edit Metadata", + + // "community.edit.tabs.metadata.title": "Community Edit - Metadata", + // TODO New key - Add a translation + "community.edit.tabs.metadata.title": "Community Edit - Metadata", + + // "community.edit.tabs.roles.head": "Assign Roles", + // TODO New key - Add a translation + "community.edit.tabs.roles.head": "Assign Roles", + + // "community.edit.tabs.roles.title": "Community Edit - Roles", + // TODO New key - Add a translation + "community.edit.tabs.roles.title": "Community Edit - Roles", + + // "community.edit.tabs.authorizations.head": "Authorizations", + // TODO New key - Add a translation + "community.edit.tabs.authorizations.head": "Authorizations", + + // "community.edit.tabs.authorizations.title": "Community Edit - Authorizations", + // TODO New key - Add a translation + "community.edit.tabs.authorizations.title": "Community Edit - Authorizations", + + + + // "community.listelement.badge": "Community", + // TODO New key - Add a translation + "community.listelement.badge": "Community", + + + + // "comcol-role.edit.no-group": "None", + // TODO New key - Add a translation + "comcol-role.edit.no-group": "None", + + // "comcol-role.edit.create": "Create", + // TODO New key - Add a translation + "comcol-role.edit.create": "Create", + + // "comcol-role.edit.restrict": "Restrict", + // TODO New key - Add a translation + "comcol-role.edit.restrict": "Restrict", + + // "comcol-role.edit.delete": "Delete", + // TODO New key - Add a translation + "comcol-role.edit.delete": "Delete", + + + // "comcol-role.edit.community-admin.name": "Administrators", + // TODO New key - Add a translation + "comcol-role.edit.community-admin.name": "Administrators", + + // "comcol-role.edit.collection-admin.name": "Administrators", + // TODO New key - Add a translation + "comcol-role.edit.collection-admin.name": "Administrators", + + + // "comcol-role.edit.community-admin.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", + // TODO New key - Add a translation + "comcol-role.edit.community-admin.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", + + // "comcol-role.edit.collection-admin.description": "Collection administrators decide who can submit items to the collection, edit item metadata (after submission), and add (map) existing items from other collections to this collection (subject to authorization for that collection).", + // TODO New key - Add a translation + "comcol-role.edit.collection-admin.description": "Collection administrators decide who can submit items to the collection, edit item metadata (after submission), and add (map) existing items from other collections to this collection (subject to authorization for that collection).", + + + // "comcol-role.edit.submitters.name": "Submitters", + // TODO New key - Add a translation + "comcol-role.edit.submitters.name": "Submitters", + + // "comcol-role.edit.submitters.description": "The E-People and Groups that have permission to submit new items to this collection.", + // TODO New key - Add a translation + "comcol-role.edit.submitters.description": "The E-People and Groups that have permission to submit new items to this collection.", + + + // "comcol-role.edit.item_read.name": "Default item read access", + // TODO New key - Add a translation + "comcol-role.edit.item_read.name": "Default item read access", + + // "comcol-role.edit.item_read.description": "E-People and Groups that can read new items submitted to this collection. Changes to this role are not retroactive. Existing items in the system will still be viewable by those who had read access at the time of their addition.", + // TODO New key - Add a translation + "comcol-role.edit.item_read.description": "E-People and Groups that can read new items submitted to this collection. Changes to this role are not retroactive. Existing items in the system will still be viewable by those who had read access at the time of their addition.", + + // "comcol-role.edit.item_read.anonymous-group": "Default read for incoming items is currently set to Anonymous.", + // TODO New key - Add a translation + "comcol-role.edit.item_read.anonymous-group": "Default read for incoming items is currently set to Anonymous.", + + + // "comcol-role.edit.bitstream_read.name": "Default bitstream read access", + // TODO New key - Add a translation + "comcol-role.edit.bitstream_read.name": "Default bitstream read access", + + // "comcol-role.edit.bitstream_read.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", + // TODO New key - Add a translation + "comcol-role.edit.bitstream_read.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", + + // "comcol-role.edit.bitstream_read.anonymous-group": "Default read for incoming bitstreams is currently set to Anonymous.", + // TODO New key - Add a translation + "comcol-role.edit.bitstream_read.anonymous-group": "Default read for incoming bitstreams is currently set to Anonymous.", + + + // "comcol-role.edit.editor.name": "Editors", + // TODO New key - Add a translation + "comcol-role.edit.editor.name": "Editors", + + // "comcol-role.edit.editor.description": "Editors are able to edit the metadata of incoming submissions, and then accept or reject them.", + // TODO New key - Add a translation + "comcol-role.edit.editor.description": "Editors are able to edit the metadata of incoming submissions, and then accept or reject them.", + + + // "comcol-role.edit.finaleditor.name": "Final editors", + // TODO New key - Add a translation + "comcol-role.edit.finaleditor.name": "Final editors", + + // "comcol-role.edit.finaleditor.description": "Final editors are able to edit the metadata of incoming submissions, but will not be able to reject them.", + // TODO New key - Add a translation + "comcol-role.edit.finaleditor.description": "Final editors are able to edit the metadata of incoming submissions, but will not be able to reject them.", + + + // "comcol-role.edit.reviewer.name": "Reviewers", + // TODO New key - Add a translation + "comcol-role.edit.reviewer.name": "Reviewers", + + // "comcol-role.edit.reviewer.description": "Reviewers are able to accept or reject incoming submissions. However, they are not able to edit the submission's metadata.", + // TODO New key - Add a translation + "comcol-role.edit.reviewer.description": "Reviewers are able to accept or reject incoming submissions. However, they are not able to edit the submission's metadata.", + + + + // "community.form.abstract": "Short Description", + // TODO New key - Add a translation + "community.form.abstract": "Short Description", + + // "community.form.description": "Introductory text (HTML)", + // TODO New key - Add a translation + "community.form.description": "Introductory text (HTML)", + + // "community.form.errors.title.required": "Please enter a community name", + // TODO New key - Add a translation + "community.form.errors.title.required": "Please enter a community name", + + // "community.form.rights": "Copyright text (HTML)", + // TODO New key - Add a translation + "community.form.rights": "Copyright text (HTML)", + + // "community.form.tableofcontents": "News (HTML)", + // TODO New key - Add a translation + "community.form.tableofcontents": "News (HTML)", + + // "community.form.title": "Name", + // TODO New key - Add a translation + "community.form.title": "Name", + + // "community.page.edit": "Edit this community", + // TODO New key - Add a translation + "community.page.edit": "Edit this community", + + // "community.page.handle": "Permanent URI for this community", + // TODO New key - Add a translation + "community.page.handle": "Permanent URI for this community", + + // "community.page.license": "License", + // TODO New key - Add a translation + "community.page.license": "License", + + // "community.page.news": "News", + // TODO New key - Add a translation + "community.page.news": "News", + + // "community.all-lists.head": "Subcommunities and Collections", + // TODO New key - Add a translation + "community.all-lists.head": "Subcommunities and Collections", + + // "community.sub-collection-list.head": "Collections of this Community", + // TODO New key - Add a translation + "community.sub-collection-list.head": "Collections of this Community", + + // "community.sub-community-list.head": "Communities of this Community", + // TODO New key - Add a translation + "community.sub-community-list.head": "Communities of this Community", + + + + // "cookies.consent.accept-all": "Accept all", + // TODO New key - Add a translation + "cookies.consent.accept-all": "Accept all", + + // "cookies.consent.accept-selected": "Accept selected", + // TODO New key - Add a translation + "cookies.consent.accept-selected": "Accept selected", + + // "cookies.consent.app.opt-out.description": "This app is loaded by default (but you can opt out)", + // TODO New key - Add a translation + "cookies.consent.app.opt-out.description": "This app is loaded by default (but you can opt out)", + + // "cookies.consent.app.opt-out.title": "(opt-out)", + // TODO New key - Add a translation + "cookies.consent.app.opt-out.title": "(opt-out)", + + // "cookies.consent.app.purpose": "purpose", + // TODO New key - Add a translation + "cookies.consent.app.purpose": "purpose", + + // "cookies.consent.app.required.description": "This application is always required", + // TODO New key - Add a translation + "cookies.consent.app.required.description": "This application is always required", + + // "cookies.consent.app.required.title": "(always required)", + // TODO New key - Add a translation + "cookies.consent.app.required.title": "(always required)", + + // "cookies.consent.update": "There were changes since your last visit, please update your consent.", + // TODO New key - Add a translation + "cookies.consent.update": "There were changes since your last visit, please update your consent.", + + // "cookies.consent.close": "Close", + // TODO New key - Add a translation + "cookies.consent.close": "Close", + + // "cookies.consent.decline": "Decline", + // TODO New key - Add a translation + "cookies.consent.decline": "Decline", + + // "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: Authentication, Preferences, Acknowledgement and Statistics.
To learn more, please read our {privacyPolicy}.", + // TODO New key - Add a translation + "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: Authentication, Preferences, Acknowledgement and Statistics.
To learn more, please read our {privacyPolicy}.", + + // "cookies.consent.content-notice.learnMore": "Customize", + // TODO New key - Add a translation + "cookies.consent.content-notice.learnMore": "Customize", + + // "cookies.consent.content-modal.description": "Here you can see and customize the information that we collect about you.", + // TODO New key - Add a translation + "cookies.consent.content-modal.description": "Here you can see and customize the information that we collect about you.", + + // "cookies.consent.content-modal.privacy-policy.name": "privacy policy", + // TODO New key - Add a translation + "cookies.consent.content-modal.privacy-policy.name": "privacy policy", + + // "cookies.consent.content-modal.privacy-policy.text": "To learn more, please read our {privacyPolicy}.", + // TODO New key - Add a translation + "cookies.consent.content-modal.privacy-policy.text": "To learn more, please read our {privacyPolicy}.", + + // "cookies.consent.content-modal.title": "Information that we collect", + // TODO New key - Add a translation + "cookies.consent.content-modal.title": "Information that we collect", + + + + // "cookies.consent.app.title.authentication": "Authentication", + // TODO New key - Add a translation + "cookies.consent.app.title.authentication": "Authentication", + + // "cookies.consent.app.description.authentication": "Required for signing you in", + // TODO New key - Add a translation + "cookies.consent.app.description.authentication": "Required for signing you in", + + + // "cookies.consent.app.title.preferences": "Preferences", + // TODO New key - Add a translation + "cookies.consent.app.title.preferences": "Preferences", + + // "cookies.consent.app.description.preferences": "Required for saving your preferences", + // TODO New key - Add a translation + "cookies.consent.app.description.preferences": "Required for saving your preferences", + + + + // "cookies.consent.app.title.acknowledgement": "Acknowledgement", + // TODO New key - Add a translation + "cookies.consent.app.title.acknowledgement": "Acknowledgement", + + // "cookies.consent.app.description.acknowledgement": "Required for saving your acknowledgements and consents", + // TODO New key - Add a translation + "cookies.consent.app.description.acknowledgement": "Required for saving your acknowledgements and consents", + + + + // "cookies.consent.app.title.google-analytics": "Google Analytics", + // TODO New key - Add a translation + "cookies.consent.app.title.google-analytics": "Google Analytics", + + // "cookies.consent.app.description.google-analytics": "Allows us to track statistical data", + // TODO New key - Add a translation + "cookies.consent.app.description.google-analytics": "Allows us to track statistical data", + + + + // "cookies.consent.purpose.functional": "Functional", + // TODO New key - Add a translation + "cookies.consent.purpose.functional": "Functional", + + // "cookies.consent.purpose.statistical": "Statistical", + // TODO New key - Add a translation + "cookies.consent.purpose.statistical": "Statistical", + + + // "curation-task.task.checklinks.label": "Check Links in Metadata", + // TODO New key - Add a translation + "curation-task.task.checklinks.label": "Check Links in Metadata", + + // "curation-task.task.noop.label": "NOOP", + // TODO New key - Add a translation + "curation-task.task.noop.label": "NOOP", + + // "curation-task.task.profileformats.label": "Profile Bitstream Formats", + // TODO New key - Add a translation + "curation-task.task.profileformats.label": "Profile Bitstream Formats", + + // "curation-task.task.requiredmetadata.label": "Check for Required Metadata", + // TODO New key - Add a translation + "curation-task.task.requiredmetadata.label": "Check for Required Metadata", + + // "curation-task.task.translate.label": "Microsoft Translator", + // TODO New key - Add a translation + "curation-task.task.translate.label": "Microsoft Translator", + + // "curation-task.task.vscan.label": "Virus Scan", + // TODO New key - Add a translation + "curation-task.task.vscan.label": "Virus Scan", + + + + // "curation.form.task-select.label": "Task:", + // TODO New key - Add a translation + "curation.form.task-select.label": "Task:", + + // "curation.form.submit": "Start", + // TODO New key - Add a translation + "curation.form.submit": "Start", + + // "curation.form.submit.success.head": "The curation task has been started successfully", + // TODO New key - Add a translation + "curation.form.submit.success.head": "The curation task has been started successfully", + + // "curation.form.submit.success.content": "You will be redirected to the corresponding process page.", + // TODO New key - Add a translation + "curation.form.submit.success.content": "You will be redirected to the corresponding process page.", + + // "curation.form.submit.error.head": "Running the curation task failed", + // TODO New key - Add a translation + "curation.form.submit.error.head": "Running the curation task failed", + + // "curation.form.submit.error.content": "An error occured when trying to start the curation task.", + // TODO New key - Add a translation + "curation.form.submit.error.content": "An error occured when trying to start the curation task.", + + // "curation.form.handle.label": "Handle:", + // TODO New key - Add a translation + "curation.form.handle.label": "Handle:", + + // "curation.form.handle.hint": "Hint: Enter [your-handle-prefix]/0 to run a task across entire site (not all tasks may support this capability)", + // TODO New key - Add a translation + "curation.form.handle.hint": "Hint: Enter [your-handle-prefix]/0 to run a task across entire site (not all tasks may support this capability)", + + + + // "dso-selector.create.collection.head": "New collection", + // TODO New key - Add a translation + "dso-selector.create.collection.head": "New collection", + + // "dso-selector.create.collection.sub-level": "Create a new collection in", + // TODO New key - Add a translation + "dso-selector.create.collection.sub-level": "Create a new collection in", + + // "dso-selector.create.community.head": "New community", + // TODO New key - Add a translation + "dso-selector.create.community.head": "New community", + + // "dso-selector.create.community.sub-level": "Create a new community in", + // TODO New key - Add a translation + "dso-selector.create.community.sub-level": "Create a new community in", + + // "dso-selector.create.community.top-level": "Create a new top-level community", + // TODO New key - Add a translation + "dso-selector.create.community.top-level": "Create a new top-level community", + + // "dso-selector.create.item.head": "New item", + // TODO New key - Add a translation + "dso-selector.create.item.head": "New item", + + // "dso-selector.create.item.sub-level": "Create a new item in", + // TODO New key - Add a translation + "dso-selector.create.item.sub-level": "Create a new item in", + + // "dso-selector.create.submission.head": "New submission", + // TODO New key - Add a translation + "dso-selector.create.submission.head": "New submission", + + // "dso-selector.edit.collection.head": "Edit collection", + // TODO New key - Add a translation + "dso-selector.edit.collection.head": "Edit collection", + + // "dso-selector.edit.community.head": "Edit community", + // TODO New key - Add a translation + "dso-selector.edit.community.head": "Edit community", + + // "dso-selector.edit.item.head": "Edit item", + // TODO New key - Add a translation + "dso-selector.edit.item.head": "Edit item", + + // "dso-selector.export-metadata.dspaceobject.head": "Export metadata from", + // TODO New key - Add a translation + "dso-selector.export-metadata.dspaceobject.head": "Export metadata from", + + // "dso-selector.no-results": "No {{ type }} found", + // TODO New key - Add a translation + "dso-selector.no-results": "No {{ type }} found", + + // "dso-selector.placeholder": "Search for a {{ type }}", + // TODO New key - Add a translation + "dso-selector.placeholder": "Search for a {{ type }}", + + + + // "confirmation-modal.export-metadata.header": "Export metadata for {{ dsoName }}", + // TODO New key - Add a translation + "confirmation-modal.export-metadata.header": "Export metadata for {{ dsoName }}", + + // "confirmation-modal.export-metadata.info": "Are you sure you want to export metadata for {{ dsoName }}", + // TODO New key - Add a translation + "confirmation-modal.export-metadata.info": "Are you sure you want to export metadata for {{ dsoName }}", + + // "confirmation-modal.export-metadata.cancel": "Cancel", + // TODO New key - Add a translation + "confirmation-modal.export-metadata.cancel": "Cancel", + + // "confirmation-modal.export-metadata.confirm": "Export", + // TODO New key - Add a translation + "confirmation-modal.export-metadata.confirm": "Export", + + // "confirmation-modal.delete-eperson.header": "Delete EPerson \"{{ dsoName }}\"", + // TODO New key - Add a translation + "confirmation-modal.delete-eperson.header": "Delete EPerson \"{{ dsoName }}\"", + + // "confirmation-modal.delete-eperson.info": "Are you sure you want to delete EPerson \"{{ dsoName }}\"", + // TODO New key - Add a translation + "confirmation-modal.delete-eperson.info": "Are you sure you want to delete EPerson \"{{ dsoName }}\"", + + // "confirmation-modal.delete-eperson.cancel": "Cancel", + // TODO New key - Add a translation + "confirmation-modal.delete-eperson.cancel": "Cancel", + + // "confirmation-modal.delete-eperson.confirm": "Delete", + // TODO New key - Add a translation + "confirmation-modal.delete-eperson.confirm": "Delete", + + + // "error.bitstream": "Error fetching bitstream", + // TODO New key - Add a translation + "error.bitstream": "Error fetching bitstream", + + // "error.browse-by": "Error fetching items", + // TODO New key - Add a translation + "error.browse-by": "Error fetching items", + + // "error.collection": "Error fetching collection", + // TODO New key - Add a translation + "error.collection": "Error fetching collection", + + // "error.collections": "Error fetching collections", + // TODO New key - Add a translation + "error.collections": "Error fetching collections", + + // "error.community": "Error fetching community", + // TODO New key - Add a translation + "error.community": "Error fetching community", + + // "error.identifier": "No item found for the identifier", + // TODO New key - Add a translation + "error.identifier": "No item found for the identifier", + + // "error.default": "Error", + // TODO New key - Add a translation + "error.default": "Error", + + // "error.item": "Error fetching item", + // TODO New key - Add a translation + "error.item": "Error fetching item", + + // "error.items": "Error fetching items", + // TODO New key - Add a translation + "error.items": "Error fetching items", + + // "error.objects": "Error fetching objects", + // TODO New key - Add a translation + "error.objects": "Error fetching objects", + + // "error.recent-submissions": "Error fetching recent submissions", + // TODO New key - Add a translation + "error.recent-submissions": "Error fetching recent submissions", + + // "error.search-results": "Error fetching search results", + // TODO New key - Add a translation + "error.search-results": "Error fetching search results", + + // "error.sub-collections": "Error fetching sub-collections", + // TODO New key - Add a translation + "error.sub-collections": "Error fetching sub-collections", + + // "error.sub-communities": "Error fetching sub-communities", + // TODO New key - Add a translation + "error.sub-communities": "Error fetching sub-communities", + + // "error.submission.sections.init-form-error": "An error occurred during section initialize, please check your input-form configuration. Details are below :

", + // TODO New key - Add a translation + "error.submission.sections.init-form-error": "An error occurred during section initialize, please check your input-form configuration. Details are below :

", + + // "error.top-level-communities": "Error fetching top-level communities", + // TODO New key - Add a translation + "error.top-level-communities": "Error fetching top-level communities", + + // "error.validation.license.notgranted": "You must grant this license to complete your submission. If you are unable to grant this license at this time you may save your work and return later or remove the submission.", + // TODO New key - Add a translation + "error.validation.license.notgranted": "You must grant this license to complete your submission. If you are unable to grant this license at this time you may save your work and return later or remove the submission.", + + // "error.validation.pattern": "This input is restricted by the current pattern: {{ pattern }}.", + // TODO New key - Add a translation + "error.validation.pattern": "This input is restricted by the current pattern: {{ pattern }}.", + + // "error.validation.filerequired": "The file upload is mandatory", + // TODO New key - Add a translation + "error.validation.filerequired": "The file upload is mandatory", + + + + // "file-section.error.header": "Error obtaining files for this item", + // TODO New key - Add a translation + "file-section.error.header": "Error obtaining files for this item", + + + + // "footer.copyright": "copyright © 2002-{{ year }}", + // TODO New key - Add a translation + "footer.copyright": "copyright © 2002-{{ year }}", + + // "footer.link.dspace": "DSpace software", + // TODO New key - Add a translation + "footer.link.dspace": "DSpace software", + + // "footer.link.lyrasis": "LYRASIS", + // TODO New key - Add a translation + "footer.link.lyrasis": "LYRASIS", + + // "footer.link.cookies": "Cookie settings", + // TODO New key - Add a translation + "footer.link.cookies": "Cookie settings", + + // "footer.link.privacy-policy": "Privacy policy", + // TODO New key - Add a translation + "footer.link.privacy-policy": "Privacy policy", + + // "footer.link.end-user-agreement":"End User Agreement", + // TODO New key - Add a translation + "footer.link.end-user-agreement":"End User Agreement", + + + + // "forgot-email.form.header": "Forgot Password", + // TODO New key - Add a translation + "forgot-email.form.header": "Forgot Password", + + // "forgot-email.form.info": "Enter Register an account to subscribe to collections for email updates, and submit new items to DSpace.", + // TODO New key - Add a translation + "forgot-email.form.info": "Enter Register an account to subscribe to collections for email updates, and submit new items to DSpace.", + + // "forgot-email.form.email": "Email Address *", + // TODO New key - Add a translation + "forgot-email.form.email": "Email Address *", + + // "forgot-email.form.email.error.required": "Please fill in an email address", + // TODO New key - Add a translation + "forgot-email.form.email.error.required": "Please fill in an email address", + + // "forgot-email.form.email.error.pattern": "Please fill in a valid email address", + // TODO New key - Add a translation + "forgot-email.form.email.error.pattern": "Please fill in a valid email address", + + // "forgot-email.form.email.hint": "This address will be verified and used as your login name.", + // TODO New key - Add a translation + "forgot-email.form.email.hint": "This address will be verified and used as your login name.", + + // "forgot-email.form.submit": "Submit", + // TODO New key - Add a translation + "forgot-email.form.submit": "Submit", + + // "forgot-email.form.success.head": "Verification email sent", + // TODO New key - Add a translation + "forgot-email.form.success.head": "Verification email sent", + + // "forgot-email.form.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", + // TODO New key - Add a translation + "forgot-email.form.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", + + // "forgot-email.form.error.head": "Error when trying to register email", + // TODO New key - Add a translation + "forgot-email.form.error.head": "Error when trying to register email", + + // "forgot-email.form.error.content": "An error occured when registering the following email address: {{ email }}", + // TODO New key - Add a translation + "forgot-email.form.error.content": "An error occured when registering the following email address: {{ email }}", + + + + // "forgot-password.title": "Forgot Password", + // TODO New key - Add a translation + "forgot-password.title": "Forgot Password", + + // "forgot-password.form.head": "Forgot Password", + // TODO New key - Add a translation + "forgot-password.form.head": "Forgot Password", + + // "forgot-password.form.info": "Enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", + // TODO New key - Add a translation + "forgot-password.form.info": "Enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", + + // "forgot-password.form.card.security": "Security", + // TODO New key - Add a translation + "forgot-password.form.card.security": "Security", + + // "forgot-password.form.identification.header": "Identify", + // TODO New key - Add a translation + "forgot-password.form.identification.header": "Identify", + + // "forgot-password.form.identification.email": "Email address: ", + // TODO New key - Add a translation + "forgot-password.form.identification.email": "Email address: ", + + // "forgot-password.form.label.password": "Password", + // TODO New key - Add a translation + "forgot-password.form.label.password": "Password", + + // "forgot-password.form.label.passwordrepeat": "Retype to confirm", + // TODO New key - Add a translation + "forgot-password.form.label.passwordrepeat": "Retype to confirm", + + // "forgot-password.form.error.empty-password": "Please enter a password in the box below.", + // TODO New key - Add a translation + "forgot-password.form.error.empty-password": "Please enter a password in the box below.", + + // "forgot-password.form.error.matching-passwords": "The passwords do not match.", + // TODO New key - Add a translation + "forgot-password.form.error.matching-passwords": "The passwords do not match.", + + // "forgot-password.form.error.password-length": "The password should be at least 6 characters long.", + // TODO New key - Add a translation + "forgot-password.form.error.password-length": "The password should be at least 6 characters long.", + + // "forgot-password.form.notification.error.title": "Error when trying to submit new password", + // TODO New key - Add a translation + "forgot-password.form.notification.error.title": "Error when trying to submit new password", + + // "forgot-password.form.notification.success.content": "The password reset was successful. You have been logged in as the created user.", + // TODO New key - Add a translation + "forgot-password.form.notification.success.content": "The password reset was successful. You have been logged in as the created user.", + + // "forgot-password.form.notification.success.title": "Password reset completed", + // TODO New key - Add a translation + "forgot-password.form.notification.success.title": "Password reset completed", + + // "forgot-password.form.submit": "Submit password", + // TODO New key - Add a translation + "forgot-password.form.submit": "Submit password", + + + + // "form.add": "Add", + // TODO New key - Add a translation + "form.add": "Add", + + // "form.add-help": "Click here to add the current entry and to add another one", + // TODO New key - Add a translation + "form.add-help": "Click here to add the current entry and to add another one", + + // "form.cancel": "Cancel", + // TODO New key - Add a translation + "form.cancel": "Cancel", + + // "form.clear": "Clear", + // TODO New key - Add a translation + "form.clear": "Clear", + + // "form.clear-help": "Click here to remove the selected value", + // TODO New key - Add a translation + "form.clear-help": "Click here to remove the selected value", + + // "form.edit": "Edit", + // TODO New key - Add a translation + "form.edit": "Edit", + + // "form.edit-help": "Click here to edit the selected value", + // TODO New key - Add a translation + "form.edit-help": "Click here to edit the selected value", + + // "form.first-name": "First name", + // TODO New key - Add a translation + "form.first-name": "First name", + + // "form.group-collapse": "Collapse", + // TODO New key - Add a translation + "form.group-collapse": "Collapse", + + // "form.group-collapse-help": "Click here to collapse", + // TODO New key - Add a translation + "form.group-collapse-help": "Click here to collapse", + + // "form.group-expand": "Expand", + // TODO New key - Add a translation + "form.group-expand": "Expand", + + // "form.group-expand-help": "Click here to expand and add more elements", + // TODO New key - Add a translation + "form.group-expand-help": "Click here to expand and add more elements", + + // "form.last-name": "Last name", + // TODO New key - Add a translation + "form.last-name": "Last name", + + // "form.loading": "Loading...", + // TODO New key - Add a translation + "form.loading": "Loading...", + + // "form.lookup": "Lookup", + // TODO New key - Add a translation + "form.lookup": "Lookup", + + // "form.lookup-help": "Click here to look up an existing relation", + // TODO New key - Add a translation + "form.lookup-help": "Click here to look up an existing relation", + + // "form.no-results": "No results found", + // TODO New key - Add a translation + "form.no-results": "No results found", + + // "form.no-value": "No value entered", + // TODO New key - Add a translation + "form.no-value": "No value entered", + + // "form.other-information": {}, + // TODO New key - Add a translation + "form.other-information": {}, + + // "form.remove": "Remove", + // TODO New key - Add a translation + "form.remove": "Remove", + + // "form.save": "Save", + // TODO New key - Add a translation + "form.save": "Save", + + // "form.save-help": "Save changes", + // TODO New key - Add a translation + "form.save-help": "Save changes", + + // "form.search": "Search", + // TODO New key - Add a translation + "form.search": "Search", + + // "form.search-help": "Click here to look for an existing correspondence", + // TODO New key - Add a translation + "form.search-help": "Click here to look for an existing correspondence", + + // "form.submit": "Submit", + // TODO New key - Add a translation + "form.submit": "Submit", + + + + // "home.description": "", + // TODO New key - Add a translation + "home.description": "", + + // "home.breadcrumbs": "Home", + // TODO New key - Add a translation + "home.breadcrumbs": "Home", + + // "home.title": "DSpace Angular :: Home", + // TODO New key - Add a translation + "home.title": "DSpace Angular :: Home", + + // "home.top-level-communities.head": "Communities in DSpace", + // TODO New key - Add a translation + "home.top-level-communities.head": "Communities in DSpace", + + // "home.top-level-communities.help": "Select a community to browse its collections.", + // TODO New key - Add a translation + "home.top-level-communities.help": "Select a community to browse its collections.", + + + + // "info.end-user-agreement.accept": "I have read and I agree to the End User Agreement", + // TODO New key - Add a translation + "info.end-user-agreement.accept": "I have read and I agree to the End User Agreement", + + // "info.end-user-agreement.accept.error": "An error occurred accepting the End User Agreement", + // TODO New key - Add a translation + "info.end-user-agreement.accept.error": "An error occurred accepting the End User Agreement", + + // "info.end-user-agreement.accept.success": "Successfully updated the End User Agreement", + // TODO New key - Add a translation + "info.end-user-agreement.accept.success": "Successfully updated the End User Agreement", + + // "info.end-user-agreement.breadcrumbs": "End User Agreement", + // TODO New key - Add a translation + "info.end-user-agreement.breadcrumbs": "End User Agreement", + + // "info.end-user-agreement.buttons.cancel": "Cancel", + // TODO New key - Add a translation + "info.end-user-agreement.buttons.cancel": "Cancel", + + // "info.end-user-agreement.buttons.save": "Save", + // TODO New key - Add a translation + "info.end-user-agreement.buttons.save": "Save", + + // "info.end-user-agreement.head": "End User Agreement", + // TODO New key - Add a translation + "info.end-user-agreement.head": "End User Agreement", + + // "info.end-user-agreement.title": "End User Agreement", + // TODO New key - Add a translation + "info.end-user-agreement.title": "End User Agreement", + + // "info.privacy.breadcrumbs": "Privacy Statement", + // TODO New key - Add a translation + "info.privacy.breadcrumbs": "Privacy Statement", + + // "info.privacy.head": "Privacy Statement", + // TODO New key - Add a translation + "info.privacy.head": "Privacy Statement", + + // "info.privacy.title": "Privacy Statement", + // TODO New key - Add a translation + "info.privacy.title": "Privacy Statement", + + + + // "item.alerts.private": "This item is private", + // TODO New key - Add a translation + "item.alerts.private": "This item is private", + + // "item.alerts.withdrawn": "This item has been withdrawn", + // TODO New key - Add a translation + "item.alerts.withdrawn": "This item has been withdrawn", + + + + // "item.edit.authorizations.heading": "With this editor you can view and alter the policies of an item, plus alter policies of individual item components: bundles and bitstreams. Briefly, an item is a container of bundles, and bundles are containers of bitstreams. Containers usually have ADD/REMOVE/READ/WRITE policies, while bitstreams only have READ/WRITE policies.", + // TODO New key - Add a translation + "item.edit.authorizations.heading": "With this editor you can view and alter the policies of an item, plus alter policies of individual item components: bundles and bitstreams. Briefly, an item is a container of bundles, and bundles are containers of bitstreams. Containers usually have ADD/REMOVE/READ/WRITE policies, while bitstreams only have READ/WRITE policies.", + + // "item.edit.authorizations.title": "Edit item's Policies", + // TODO New key - Add a translation + "item.edit.authorizations.title": "Edit item's Policies", + + + + // "item.badge.private": "Private", + // TODO New key - Add a translation + "item.badge.private": "Private", + + // "item.badge.withdrawn": "Withdrawn", + // TODO New key - Add a translation + "item.badge.withdrawn": "Withdrawn", + + + + // "item.bitstreams.upload.bundle": "Bundle", + // TODO New key - Add a translation + "item.bitstreams.upload.bundle": "Bundle", + + // "item.bitstreams.upload.bundle.placeholder": "Select a bundle", + // TODO New key - Add a translation + "item.bitstreams.upload.bundle.placeholder": "Select a bundle", + + // "item.bitstreams.upload.bundle.new": "Create bundle", + // TODO New key - Add a translation + "item.bitstreams.upload.bundle.new": "Create bundle", + + // "item.bitstreams.upload.bundles.empty": "This item doesn\'t contain any bundles to upload a bitstream to.", + // TODO New key - Add a translation + "item.bitstreams.upload.bundles.empty": "This item doesn\'t contain any bundles to upload a bitstream to.", + + // "item.bitstreams.upload.cancel": "Cancel", + // TODO New key - Add a translation + "item.bitstreams.upload.cancel": "Cancel", + + // "item.bitstreams.upload.drop-message": "Drop a file to upload", + // TODO New key - Add a translation + "item.bitstreams.upload.drop-message": "Drop a file to upload", + + // "item.bitstreams.upload.item": "Item: ", + // TODO New key - Add a translation + "item.bitstreams.upload.item": "Item: ", + + // "item.bitstreams.upload.notifications.bundle.created.content": "Successfully created new bundle.", + // TODO New key - Add a translation + "item.bitstreams.upload.notifications.bundle.created.content": "Successfully created new bundle.", + + // "item.bitstreams.upload.notifications.bundle.created.title": "Created bundle", + // TODO New key - Add a translation + "item.bitstreams.upload.notifications.bundle.created.title": "Created bundle", + + // "item.bitstreams.upload.notifications.upload.failed": "Upload failed. Please verify the content before retrying.", + // TODO New key - Add a translation + "item.bitstreams.upload.notifications.upload.failed": "Upload failed. Please verify the content before retrying.", + + // "item.bitstreams.upload.title": "Upload bitstream", + // TODO New key - Add a translation + "item.bitstreams.upload.title": "Upload bitstream", + + + + // "item.edit.bitstreams.bundle.edit.buttons.upload": "Upload", + // TODO New key - Add a translation + "item.edit.bitstreams.bundle.edit.buttons.upload": "Upload", + + // "item.edit.bitstreams.bundle.displaying": "Currently displaying {{ amount }} bitstreams of {{ total }}.", + // TODO New key - Add a translation + "item.edit.bitstreams.bundle.displaying": "Currently displaying {{ amount }} bitstreams of {{ total }}.", + + // "item.edit.bitstreams.bundle.load.all": "Load all ({{ total }})", + // TODO New key - Add a translation + "item.edit.bitstreams.bundle.load.all": "Load all ({{ total }})", + + // "item.edit.bitstreams.bundle.load.more": "Load more", + // TODO New key - Add a translation + "item.edit.bitstreams.bundle.load.more": "Load more", + + // "item.edit.bitstreams.bundle.name": "BUNDLE: {{ name }}", + // TODO New key - Add a translation + "item.edit.bitstreams.bundle.name": "BUNDLE: {{ name }}", + + // "item.edit.bitstreams.discard-button": "Discard", + // TODO New key - Add a translation + "item.edit.bitstreams.discard-button": "Discard", + + // "item.edit.bitstreams.edit.buttons.download": "Download", + // TODO New key - Add a translation + "item.edit.bitstreams.edit.buttons.download": "Download", + + // "item.edit.bitstreams.edit.buttons.drag": "Drag", + // TODO New key - Add a translation + "item.edit.bitstreams.edit.buttons.drag": "Drag", + + // "item.edit.bitstreams.edit.buttons.edit": "Edit", + // TODO New key - Add a translation + "item.edit.bitstreams.edit.buttons.edit": "Edit", + + // "item.edit.bitstreams.edit.buttons.remove": "Remove", + // TODO New key - Add a translation + "item.edit.bitstreams.edit.buttons.remove": "Remove", + + // "item.edit.bitstreams.edit.buttons.undo": "Undo changes", + // TODO New key - Add a translation + "item.edit.bitstreams.edit.buttons.undo": "Undo changes", + + // "item.edit.bitstreams.empty": "This item doesn't contain any bitstreams. Click the upload button to create one.", + // TODO New key - Add a translation + "item.edit.bitstreams.empty": "This item doesn't contain any bitstreams. Click the upload button to create one.", + + // "item.edit.bitstreams.headers.actions": "Actions", + // TODO New key - Add a translation + "item.edit.bitstreams.headers.actions": "Actions", + + // "item.edit.bitstreams.headers.bundle": "Bundle", + // TODO New key - Add a translation + "item.edit.bitstreams.headers.bundle": "Bundle", + + // "item.edit.bitstreams.headers.description": "Description", + // TODO New key - Add a translation + "item.edit.bitstreams.headers.description": "Description", + + // "item.edit.bitstreams.headers.format": "Format", + // TODO New key - Add a translation + "item.edit.bitstreams.headers.format": "Format", + + // "item.edit.bitstreams.headers.name": "Name", + // TODO New key - Add a translation + "item.edit.bitstreams.headers.name": "Name", + + // "item.edit.bitstreams.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + // TODO New key - Add a translation + "item.edit.bitstreams.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + + // "item.edit.bitstreams.notifications.discarded.title": "Changes discarded", + // TODO New key - Add a translation + "item.edit.bitstreams.notifications.discarded.title": "Changes discarded", + + // "item.edit.bitstreams.notifications.move.failed.title": "Error moving bitstreams", + // TODO New key - Add a translation + "item.edit.bitstreams.notifications.move.failed.title": "Error moving bitstreams", + + // "item.edit.bitstreams.notifications.move.saved.content": "Your move changes to this item's bitstreams and bundles have been saved.", + // TODO New key - Add a translation + "item.edit.bitstreams.notifications.move.saved.content": "Your move changes to this item's bitstreams and bundles have been saved.", + + // "item.edit.bitstreams.notifications.move.saved.title": "Move changes saved", + // TODO New key - Add a translation + "item.edit.bitstreams.notifications.move.saved.title": "Move changes saved", + + // "item.edit.bitstreams.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", + // TODO New key - Add a translation + "item.edit.bitstreams.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", + + // "item.edit.bitstreams.notifications.outdated.title": "Changes outdated", + // TODO New key - Add a translation + "item.edit.bitstreams.notifications.outdated.title": "Changes outdated", + + // "item.edit.bitstreams.notifications.remove.failed.title": "Error deleting bitstream", + // TODO New key - Add a translation + "item.edit.bitstreams.notifications.remove.failed.title": "Error deleting bitstream", + + // "item.edit.bitstreams.notifications.remove.saved.content": "Your removal changes to this item's bitstreams have been saved.", + // TODO New key - Add a translation + "item.edit.bitstreams.notifications.remove.saved.content": "Your removal changes to this item's bitstreams have been saved.", + + // "item.edit.bitstreams.notifications.remove.saved.title": "Removal changes saved", + // TODO New key - Add a translation + "item.edit.bitstreams.notifications.remove.saved.title": "Removal changes saved", + + // "item.edit.bitstreams.reinstate-button": "Undo", + // TODO New key - Add a translation + "item.edit.bitstreams.reinstate-button": "Undo", + + // "item.edit.bitstreams.save-button": "Save", + // TODO New key - Add a translation + "item.edit.bitstreams.save-button": "Save", + + // "item.edit.bitstreams.upload-button": "Upload", + // TODO New key - Add a translation + "item.edit.bitstreams.upload-button": "Upload", + + + + // "item.edit.delete.cancel": "Cancel", + // TODO New key - Add a translation + "item.edit.delete.cancel": "Cancel", + + // "item.edit.delete.confirm": "Delete", + // TODO New key - Add a translation + "item.edit.delete.confirm": "Delete", + + // "item.edit.delete.description": "Are you sure this item should be completely deleted? Caution: At present, no tombstone would be left.", + // TODO New key - Add a translation + "item.edit.delete.description": "Are you sure this item should be completely deleted? Caution: At present, no tombstone would be left.", + + // "item.edit.delete.error": "An error occurred while deleting the item", + // TODO New key - Add a translation + "item.edit.delete.error": "An error occurred while deleting the item", + + // "item.edit.delete.header": "Delete item: {{ id }}", + // TODO New key - Add a translation + "item.edit.delete.header": "Delete item: {{ id }}", + + // "item.edit.delete.success": "The item has been deleted", + // TODO New key - Add a translation + "item.edit.delete.success": "The item has been deleted", + + // "item.edit.head": "Edit Item", + // TODO New key - Add a translation + "item.edit.head": "Edit Item", + + // "item.edit.breadcrumbs": "Edit Item", + // TODO New key - Add a translation + "item.edit.breadcrumbs": "Edit Item", + + + // "item.edit.tabs.mapper.head": "Collection Mapper", + // TODO New key - Add a translation + "item.edit.tabs.mapper.head": "Collection Mapper", + + // "item.edit.tabs.item-mapper.title": "Item Edit - Collection Mapper", + // TODO New key - Add a translation + "item.edit.tabs.item-mapper.title": "Item Edit - Collection Mapper", + + // "item.edit.item-mapper.buttons.add": "Map item to selected collections", + // TODO New key - Add a translation + "item.edit.item-mapper.buttons.add": "Map item to selected collections", + + // "item.edit.item-mapper.buttons.remove": "Remove item's mapping for selected collections", + // TODO New key - Add a translation + "item.edit.item-mapper.buttons.remove": "Remove item's mapping for selected collections", + + // "item.edit.item-mapper.cancel": "Cancel", + // TODO New key - Add a translation + "item.edit.item-mapper.cancel": "Cancel", + + // "item.edit.item-mapper.description": "This is the item mapper tool that allows administrators to map this item to other collections. You can search for collections and map them, or browse the list of collections the item is currently mapped to.", + // TODO New key - Add a translation + "item.edit.item-mapper.description": "This is the item mapper tool that allows administrators to map this item to other collections. You can search for collections and map them, or browse the list of collections the item is currently mapped to.", + + // "item.edit.item-mapper.head": "Item Mapper - Map Item to Collections", + // TODO New key - Add a translation + "item.edit.item-mapper.head": "Item Mapper - Map Item to Collections", + + // "item.edit.item-mapper.item": "Item: \"{{name}}\"", + // TODO New key - Add a translation + "item.edit.item-mapper.item": "Item: \"{{name}}\"", + + // "item.edit.item-mapper.no-search": "Please enter a query to search", + // TODO New key - Add a translation + "item.edit.item-mapper.no-search": "Please enter a query to search", + + // "item.edit.item-mapper.notifications.add.error.content": "Errors occurred for mapping of item to {{amount}} collections.", + // TODO New key - Add a translation + "item.edit.item-mapper.notifications.add.error.content": "Errors occurred for mapping of item to {{amount}} collections.", + + // "item.edit.item-mapper.notifications.add.error.head": "Mapping errors", + // TODO New key - Add a translation + "item.edit.item-mapper.notifications.add.error.head": "Mapping errors", + + // "item.edit.item-mapper.notifications.add.success.content": "Successfully mapped item to {{amount}} collections.", + // TODO New key - Add a translation + "item.edit.item-mapper.notifications.add.success.content": "Successfully mapped item to {{amount}} collections.", + + // "item.edit.item-mapper.notifications.add.success.head": "Mapping completed", + // TODO New key - Add a translation + "item.edit.item-mapper.notifications.add.success.head": "Mapping completed", + + // "item.edit.item-mapper.notifications.remove.error.content": "Errors occurred for the removal of the mapping to {{amount}} collections.", + // TODO New key - Add a translation + "item.edit.item-mapper.notifications.remove.error.content": "Errors occurred for the removal of the mapping to {{amount}} collections.", + + // "item.edit.item-mapper.notifications.remove.error.head": "Removal of mapping errors", + // TODO New key - Add a translation + "item.edit.item-mapper.notifications.remove.error.head": "Removal of mapping errors", + + // "item.edit.item-mapper.notifications.remove.success.content": "Successfully removed mapping of item to {{amount}} collections.", + // TODO New key - Add a translation + "item.edit.item-mapper.notifications.remove.success.content": "Successfully removed mapping of item to {{amount}} collections.", + + // "item.edit.item-mapper.notifications.remove.success.head": "Removal of mapping completed", + // TODO New key - Add a translation + "item.edit.item-mapper.notifications.remove.success.head": "Removal of mapping completed", + + // "item.edit.item-mapper.tabs.browse": "Browse mapped collections", + // TODO New key - Add a translation + "item.edit.item-mapper.tabs.browse": "Browse mapped collections", + + // "item.edit.item-mapper.tabs.map": "Map new collections", + // TODO New key - Add a translation + "item.edit.item-mapper.tabs.map": "Map new collections", + + + + // "item.edit.metadata.add-button": "Add", + // TODO New key - Add a translation + "item.edit.metadata.add-button": "Add", + + // "item.edit.metadata.discard-button": "Discard", + // TODO New key - Add a translation + "item.edit.metadata.discard-button": "Discard", + + // "item.edit.metadata.edit.buttons.edit": "Edit", + // TODO New key - Add a translation + "item.edit.metadata.edit.buttons.edit": "Edit", + + // "item.edit.metadata.edit.buttons.remove": "Remove", + // TODO New key - Add a translation + "item.edit.metadata.edit.buttons.remove": "Remove", + + // "item.edit.metadata.edit.buttons.undo": "Undo changes", + // TODO New key - Add a translation + "item.edit.metadata.edit.buttons.undo": "Undo changes", + + // "item.edit.metadata.edit.buttons.unedit": "Stop editing", + // TODO New key - Add a translation + "item.edit.metadata.edit.buttons.unedit": "Stop editing", + + // "item.edit.metadata.empty": "The item currently doesn't contain any metadata. Click Add to start adding a metadata value.", + // TODO New key - Add a translation + "item.edit.metadata.empty": "The item currently doesn't contain any metadata. Click Add to start adding a metadata value.", + + // "item.edit.metadata.headers.edit": "Edit", + // TODO New key - Add a translation + "item.edit.metadata.headers.edit": "Edit", + + // "item.edit.metadata.headers.field": "Field", + // TODO New key - Add a translation + "item.edit.metadata.headers.field": "Field", + + // "item.edit.metadata.headers.language": "Lang", + // TODO New key - Add a translation + "item.edit.metadata.headers.language": "Lang", + + // "item.edit.metadata.headers.value": "Value", + // TODO New key - Add a translation + "item.edit.metadata.headers.value": "Value", + + // "item.edit.metadata.metadatafield.invalid": "Please choose a valid metadata field", + // TODO New key - Add a translation + "item.edit.metadata.metadatafield.invalid": "Please choose a valid metadata field", + + // "item.edit.metadata.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + // TODO New key - Add a translation + "item.edit.metadata.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + + // "item.edit.metadata.notifications.discarded.title": "Changed discarded", + // TODO New key - Add a translation + "item.edit.metadata.notifications.discarded.title": "Changed discarded", + + // "item.edit.metadata.notifications.error.title": "An error occurred", + // TODO New key - Add a translation + "item.edit.metadata.notifications.error.title": "An error occurred", + + // "item.edit.metadata.notifications.invalid.content": "Your changes were not saved. Please make sure all fields are valid before you save.", + // TODO New key - Add a translation + "item.edit.metadata.notifications.invalid.content": "Your changes were not saved. Please make sure all fields are valid before you save.", + + // "item.edit.metadata.notifications.invalid.title": "Metadata invalid", + // TODO New key - Add a translation + "item.edit.metadata.notifications.invalid.title": "Metadata invalid", + + // "item.edit.metadata.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", + // TODO New key - Add a translation + "item.edit.metadata.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", + + // "item.edit.metadata.notifications.outdated.title": "Changed outdated", + // TODO New key - Add a translation + "item.edit.metadata.notifications.outdated.title": "Changed outdated", + + // "item.edit.metadata.notifications.saved.content": "Your changes to this item's metadata were saved.", + // TODO New key - Add a translation + "item.edit.metadata.notifications.saved.content": "Your changes to this item's metadata were saved.", + + // "item.edit.metadata.notifications.saved.title": "Metadata saved", + // TODO New key - Add a translation + "item.edit.metadata.notifications.saved.title": "Metadata saved", + + // "item.edit.metadata.reinstate-button": "Undo", + // TODO New key - Add a translation + "item.edit.metadata.reinstate-button": "Undo", + + // "item.edit.metadata.save-button": "Save", + // TODO New key - Add a translation + "item.edit.metadata.save-button": "Save", + + + + // "item.edit.modify.overview.field": "Field", + // TODO New key - Add a translation + "item.edit.modify.overview.field": "Field", + + // "item.edit.modify.overview.language": "Language", + // TODO New key - Add a translation + "item.edit.modify.overview.language": "Language", + + // "item.edit.modify.overview.value": "Value", + // TODO New key - Add a translation + "item.edit.modify.overview.value": "Value", + + + + // "item.edit.move.cancel": "Cancel", + // TODO New key - Add a translation + "item.edit.move.cancel": "Cancel", + + // "item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.", + // TODO New key - Add a translation + "item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.", + + // "item.edit.move.error": "An error occurred when attempting to move the item", + // TODO New key - Add a translation + "item.edit.move.error": "An error occurred when attempting to move the item", + + // "item.edit.move.head": "Move item: {{id}}", + // TODO New key - Add a translation + "item.edit.move.head": "Move item: {{id}}", + + // "item.edit.move.inheritpolicies.checkbox": "Inherit policies", + // TODO New key - Add a translation + "item.edit.move.inheritpolicies.checkbox": "Inherit policies", + + // "item.edit.move.inheritpolicies.description": "Inherit the default policies of the destination collection", + // TODO New key - Add a translation + "item.edit.move.inheritpolicies.description": "Inherit the default policies of the destination collection", + + // "item.edit.move.move": "Move", + // TODO New key - Add a translation + "item.edit.move.move": "Move", + + // "item.edit.move.processing": "Moving...", + // TODO New key - Add a translation + "item.edit.move.processing": "Moving...", + + // "item.edit.move.search.placeholder": "Enter a search query to look for collections", + // TODO New key - Add a translation + "item.edit.move.search.placeholder": "Enter a search query to look for collections", + + // "item.edit.move.success": "The item has been moved successfully", + // TODO New key - Add a translation + "item.edit.move.success": "The item has been moved successfully", + + // "item.edit.move.title": "Move item", + // TODO New key - Add a translation + "item.edit.move.title": "Move item", + + + + // "item.edit.private.cancel": "Cancel", + // TODO New key - Add a translation + "item.edit.private.cancel": "Cancel", + + // "item.edit.private.confirm": "Make it Private", + // TODO New key - Add a translation + "item.edit.private.confirm": "Make it Private", + + // "item.edit.private.description": "Are you sure this item should be made private in the archive?", + // TODO New key - Add a translation + "item.edit.private.description": "Are you sure this item should be made private in the archive?", + + // "item.edit.private.error": "An error occurred while making the item private", + // TODO New key - Add a translation + "item.edit.private.error": "An error occurred while making the item private", + + // "item.edit.private.header": "Make item private: {{ id }}", + // TODO New key - Add a translation + "item.edit.private.header": "Make item private: {{ id }}", + + // "item.edit.private.success": "The item is now private", + // TODO New key - Add a translation + "item.edit.private.success": "The item is now private", + + + + // "item.edit.public.cancel": "Cancel", + // TODO New key - Add a translation + "item.edit.public.cancel": "Cancel", + + // "item.edit.public.confirm": "Make it Public", + // TODO New key - Add a translation + "item.edit.public.confirm": "Make it Public", + + // "item.edit.public.description": "Are you sure this item should be made public in the archive?", + // TODO New key - Add a translation + "item.edit.public.description": "Are you sure this item should be made public in the archive?", + + // "item.edit.public.error": "An error occurred while making the item public", + // TODO New key - Add a translation + "item.edit.public.error": "An error occurred while making the item public", + + // "item.edit.public.header": "Make item public: {{ id }}", + // TODO New key - Add a translation + "item.edit.public.header": "Make item public: {{ id }}", + + // "item.edit.public.success": "The item is now public", + // TODO New key - Add a translation + "item.edit.public.success": "The item is now public", + + + + // "item.edit.reinstate.cancel": "Cancel", + // TODO New key - Add a translation + "item.edit.reinstate.cancel": "Cancel", + + // "item.edit.reinstate.confirm": "Reinstate", + // TODO New key - Add a translation + "item.edit.reinstate.confirm": "Reinstate", + + // "item.edit.reinstate.description": "Are you sure this item should be reinstated to the archive?", + // TODO New key - Add a translation + "item.edit.reinstate.description": "Are you sure this item should be reinstated to the archive?", + + // "item.edit.reinstate.error": "An error occurred while reinstating the item", + // TODO New key - Add a translation + "item.edit.reinstate.error": "An error occurred while reinstating the item", + + // "item.edit.reinstate.header": "Reinstate item: {{ id }}", + // TODO New key - Add a translation + "item.edit.reinstate.header": "Reinstate item: {{ id }}", + + // "item.edit.reinstate.success": "The item was reinstated successfully", + // TODO New key - Add a translation + "item.edit.reinstate.success": "The item was reinstated successfully", + + + + // "item.edit.relationships.discard-button": "Discard", + // TODO New key - Add a translation + "item.edit.relationships.discard-button": "Discard", + + // "item.edit.relationships.edit.buttons.add": "Add", + // TODO New key - Add a translation + "item.edit.relationships.edit.buttons.add": "Add", + + // "item.edit.relationships.edit.buttons.remove": "Remove", + // TODO New key - Add a translation + "item.edit.relationships.edit.buttons.remove": "Remove", + + // "item.edit.relationships.edit.buttons.undo": "Undo changes", + // TODO New key - Add a translation + "item.edit.relationships.edit.buttons.undo": "Undo changes", + + // "item.edit.relationships.no-relationships": "No relationships", + // TODO New key - Add a translation + "item.edit.relationships.no-relationships": "No relationships", + + // "item.edit.relationships.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + // TODO New key - Add a translation + "item.edit.relationships.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + + // "item.edit.relationships.notifications.discarded.title": "Changes discarded", + // TODO New key - Add a translation + "item.edit.relationships.notifications.discarded.title": "Changes discarded", + + // "item.edit.relationships.notifications.failed.title": "Error editing relationships", + // TODO New key - Add a translation + "item.edit.relationships.notifications.failed.title": "Error editing relationships", + + // "item.edit.relationships.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", + // TODO New key - Add a translation + "item.edit.relationships.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", + + // "item.edit.relationships.notifications.outdated.title": "Changes outdated", + // TODO New key - Add a translation + "item.edit.relationships.notifications.outdated.title": "Changes outdated", + + // "item.edit.relationships.notifications.saved.content": "Your changes to this item's relationships were saved.", + // TODO New key - Add a translation + "item.edit.relationships.notifications.saved.content": "Your changes to this item's relationships were saved.", + + // "item.edit.relationships.notifications.saved.title": "Relationships saved", + // TODO New key - Add a translation + "item.edit.relationships.notifications.saved.title": "Relationships saved", + + // "item.edit.relationships.reinstate-button": "Undo", + // TODO New key - Add a translation + "item.edit.relationships.reinstate-button": "Undo", + + // "item.edit.relationships.save-button": "Save", + // TODO New key - Add a translation + "item.edit.relationships.save-button": "Save", + + // "item.edit.relationships.no-entity-type": "Add 'dspace.entity.type' metadata to enable relationships for this item", + // TODO New key - Add a translation + "item.edit.relationships.no-entity-type": "Add 'dspace.entity.type' metadata to enable relationships for this item", + + + + // "item.edit.tabs.bitstreams.head": "Bitstreams", + // TODO New key - Add a translation + "item.edit.tabs.bitstreams.head": "Bitstreams", + + // "item.edit.tabs.bitstreams.title": "Item Edit - Bitstreams", + // TODO New key - Add a translation + "item.edit.tabs.bitstreams.title": "Item Edit - Bitstreams", + + // "item.edit.tabs.curate.head": "Curate", + // TODO New key - Add a translation + "item.edit.tabs.curate.head": "Curate", + + // "item.edit.tabs.curate.title": "Item Edit - Curate", + // TODO New key - Add a translation + "item.edit.tabs.curate.title": "Item Edit - Curate", + + // "item.edit.tabs.metadata.head": "Metadata", + // TODO New key - Add a translation + "item.edit.tabs.metadata.head": "Metadata", + + // "item.edit.tabs.metadata.title": "Item Edit - Metadata", + // TODO New key - Add a translation + "item.edit.tabs.metadata.title": "Item Edit - Metadata", + + // "item.edit.tabs.relationships.head": "Relationships", + // TODO New key - Add a translation + "item.edit.tabs.relationships.head": "Relationships", + + // "item.edit.tabs.relationships.title": "Item Edit - Relationships", + // TODO New key - Add a translation + "item.edit.tabs.relationships.title": "Item Edit - Relationships", + + // "item.edit.tabs.status.buttons.authorizations.button": "Authorizations...", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.authorizations.button": "Authorizations...", + + // "item.edit.tabs.status.buttons.authorizations.label": "Edit item's authorization policies", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.authorizations.label": "Edit item's authorization policies", + + // "item.edit.tabs.status.buttons.delete.button": "Permanently delete", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.delete.button": "Permanently delete", + + // "item.edit.tabs.status.buttons.delete.label": "Completely expunge item", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.delete.label": "Completely expunge item", + + // "item.edit.tabs.status.buttons.mappedCollections.button": "Mapped collections", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.mappedCollections.button": "Mapped collections", + + // "item.edit.tabs.status.buttons.mappedCollections.label": "Manage mapped collections", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.mappedCollections.label": "Manage mapped collections", + + // "item.edit.tabs.status.buttons.move.button": "Move...", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.move.button": "Move...", + + // "item.edit.tabs.status.buttons.move.label": "Move item to another collection", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.move.label": "Move item to another collection", + + // "item.edit.tabs.status.buttons.private.button": "Make it private...", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.private.button": "Make it private...", + + // "item.edit.tabs.status.buttons.private.label": "Make item private", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.private.label": "Make item private", + + // "item.edit.tabs.status.buttons.public.button": "Make it public...", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.public.button": "Make it public...", + + // "item.edit.tabs.status.buttons.public.label": "Make item public", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.public.label": "Make item public", + + // "item.edit.tabs.status.buttons.reinstate.button": "Reinstate...", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.reinstate.button": "Reinstate...", + + // "item.edit.tabs.status.buttons.reinstate.label": "Reinstate item into the repository", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.reinstate.label": "Reinstate item into the repository", + + // "item.edit.tabs.status.buttons.withdraw.button": "Withdraw...", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.withdraw.button": "Withdraw...", + + // "item.edit.tabs.status.buttons.withdraw.label": "Withdraw item from the repository", + // TODO New key - Add a translation + "item.edit.tabs.status.buttons.withdraw.label": "Withdraw item from the repository", + + // "item.edit.tabs.status.description": "Welcome to the item management page. From here you can withdraw, reinstate, move or delete the item. You may also update or add new metadata / bitstreams on the other tabs.", + // TODO New key - Add a translation + "item.edit.tabs.status.description": "Welcome to the item management page. From here you can withdraw, reinstate, move or delete the item. You may also update or add new metadata / bitstreams on the other tabs.", + + // "item.edit.tabs.status.head": "Status", + // TODO New key - Add a translation + "item.edit.tabs.status.head": "Status", + + // "item.edit.tabs.status.labels.handle": "Handle", + // TODO New key - Add a translation + "item.edit.tabs.status.labels.handle": "Handle", + + // "item.edit.tabs.status.labels.id": "Item Internal ID", + // TODO New key - Add a translation + "item.edit.tabs.status.labels.id": "Item Internal ID", + + // "item.edit.tabs.status.labels.itemPage": "Item Page", + // TODO New key - Add a translation + "item.edit.tabs.status.labels.itemPage": "Item Page", + + // "item.edit.tabs.status.labels.lastModified": "Last Modified", + // TODO New key - Add a translation + "item.edit.tabs.status.labels.lastModified": "Last Modified", + + // "item.edit.tabs.status.title": "Item Edit - Status", + // TODO New key - Add a translation + "item.edit.tabs.status.title": "Item Edit - Status", + + // "item.edit.tabs.versionhistory.head": "Version History", + // TODO New key - Add a translation + "item.edit.tabs.versionhistory.head": "Version History", + + // "item.edit.tabs.versionhistory.title": "Item Edit - Version History", + // TODO New key - Add a translation + "item.edit.tabs.versionhistory.title": "Item Edit - Version History", + + // "item.edit.tabs.versionhistory.under-construction": "Editing or adding new versions is not yet possible in this user interface.", + // TODO New key - Add a translation + "item.edit.tabs.versionhistory.under-construction": "Editing or adding new versions is not yet possible in this user interface.", + + // "item.edit.tabs.view.head": "View Item", + // TODO New key - Add a translation + "item.edit.tabs.view.head": "View Item", + + // "item.edit.tabs.view.title": "Item Edit - View", + // TODO New key - Add a translation + "item.edit.tabs.view.title": "Item Edit - View", + + + + // "item.edit.withdraw.cancel": "Cancel", + // TODO New key - Add a translation + "item.edit.withdraw.cancel": "Cancel", + + // "item.edit.withdraw.confirm": "Withdraw", + // TODO New key - Add a translation + "item.edit.withdraw.confirm": "Withdraw", + + // "item.edit.withdraw.description": "Are you sure this item should be withdrawn from the archive?", + // TODO New key - Add a translation + "item.edit.withdraw.description": "Are you sure this item should be withdrawn from the archive?", + + // "item.edit.withdraw.error": "An error occurred while withdrawing the item", + // TODO New key - Add a translation + "item.edit.withdraw.error": "An error occurred while withdrawing the item", + + // "item.edit.withdraw.header": "Withdraw item: {{ id }}", + // TODO New key - Add a translation + "item.edit.withdraw.header": "Withdraw item: {{ id }}", + + // "item.edit.withdraw.success": "The item was withdrawn successfully", + // TODO New key - Add a translation + "item.edit.withdraw.success": "The item was withdrawn successfully", + + + + // "item.listelement.badge": "Item", + // TODO New key - Add a translation + "item.listelement.badge": "Item", + + // "item.page.description": "Description", + // TODO New key - Add a translation + "item.page.description": "Description", + + // "item.page.edit": "Edit this item", + // TODO New key - Add a translation + "item.page.edit": "Edit this item", + + // "item.page.journal-issn": "Journal ISSN", + // TODO New key - Add a translation + "item.page.journal-issn": "Journal ISSN", + + // "item.page.journal-title": "Journal Title", + // TODO New key - Add a translation + "item.page.journal-title": "Journal Title", + + // "item.page.publisher": "Publisher", + // TODO New key - Add a translation + "item.page.publisher": "Publisher", + + // "item.page.titleprefix": "Item: ", + // TODO New key - Add a translation + "item.page.titleprefix": "Item: ", + + // "item.page.volume-title": "Volume Title", + // TODO New key - Add a translation + "item.page.volume-title": "Volume Title", + + // "item.search.results.head": "Item Search Results", + // TODO New key - Add a translation + "item.search.results.head": "Item Search Results", + + // "item.search.title": "DSpace Angular :: Item Search", + // TODO New key - Add a translation + "item.search.title": "DSpace Angular :: Item Search", + + + + // "item.page.abstract": "Abstract", + // TODO New key - Add a translation + "item.page.abstract": "Abstract", + + // "item.page.author": "Authors", + // TODO New key - Add a translation + "item.page.author": "Authors", + + // "item.page.citation": "Citation", + // TODO New key - Add a translation + "item.page.citation": "Citation", + + // "item.page.collections": "Collections", + // TODO New key - Add a translation + "item.page.collections": "Collections", + + // "item.page.date": "Date", + // TODO New key - Add a translation + "item.page.date": "Date", + + // "item.page.edit": "Edit this item", + // TODO New key - Add a translation + "item.page.edit": "Edit this item", + + // "item.page.files": "Files", + // TODO New key - Add a translation + "item.page.files": "Files", + + // "item.page.filesection.description": "Description:", + // TODO New key - Add a translation + "item.page.filesection.description": "Description:", + + // "item.page.filesection.download": "Download", + // TODO New key - Add a translation + "item.page.filesection.download": "Download", + + // "item.page.filesection.format": "Format:", + // TODO New key - Add a translation + "item.page.filesection.format": "Format:", + + // "item.page.filesection.name": "Name:", + // TODO New key - Add a translation + "item.page.filesection.name": "Name:", + + // "item.page.filesection.size": "Size:", + // TODO New key - Add a translation + "item.page.filesection.size": "Size:", + + // "item.page.journal.search.title": "Articles in this journal", + // TODO New key - Add a translation + "item.page.journal.search.title": "Articles in this journal", + + // "item.page.link.full": "Full item page", + // TODO New key - Add a translation + "item.page.link.full": "Full item page", + + // "item.page.link.simple": "Simple item page", + // TODO New key - Add a translation + "item.page.link.simple": "Simple item page", + + // "item.page.person.search.title": "Articles by this author", + // TODO New key - Add a translation + "item.page.person.search.title": "Articles by this author", + + // "item.page.related-items.view-more": "Show {{ amount }} more", + // TODO New key - Add a translation + "item.page.related-items.view-more": "Show {{ amount }} more", + + // "item.page.related-items.view-less": "Hide last {{ amount }}", + // TODO New key - Add a translation + "item.page.related-items.view-less": "Hide last {{ amount }}", + + // "item.page.relationships.isAuthorOfPublication": "Publications", + // TODO New key - Add a translation + "item.page.relationships.isAuthorOfPublication": "Publications", + + // "item.page.relationships.isJournalOfPublication": "Publications", + // TODO New key - Add a translation + "item.page.relationships.isJournalOfPublication": "Publications", + + // "item.page.relationships.isOrgUnitOfPerson": "Authors", + // TODO New key - Add a translation + "item.page.relationships.isOrgUnitOfPerson": "Authors", + + // "item.page.relationships.isOrgUnitOfProject": "Research Projects", + // TODO New key - Add a translation + "item.page.relationships.isOrgUnitOfProject": "Research Projects", + + // "item.page.subject": "Keywords", + // TODO New key - Add a translation + "item.page.subject": "Keywords", + + // "item.page.uri": "URI", + // TODO New key - Add a translation + "item.page.uri": "URI", + + // "item.page.bitstreams.view-more": "Show more", + // TODO New key - Add a translation + "item.page.bitstreams.view-more": "Show more", + + // "item.page.bitstreams.collapse": "Collapse", + // TODO New key - Add a translation + "item.page.bitstreams.collapse": "Collapse", + + // "item.page.filesection.original.bundle" : "Original bundle", + // TODO New key - Add a translation + "item.page.filesection.original.bundle" : "Original bundle", + + // "item.page.filesection.license.bundle" : "License bundle", + // TODO New key - Add a translation + "item.page.filesection.license.bundle" : "License bundle", + + // "item.preview.dc.identifier.uri": "Identifier:", + // TODO New key - Add a translation + "item.preview.dc.identifier.uri": "Identifier:", + + // "item.preview.dc.contributor.author": "Authors:", + // TODO New key - Add a translation + "item.preview.dc.contributor.author": "Authors:", + + // "item.preview.dc.date.issued": "Published date:", + // TODO New key - Add a translation + "item.preview.dc.date.issued": "Published date:", + + // "item.preview.dc.description.abstract": "Abstract:", + // TODO New key - Add a translation + "item.preview.dc.description.abstract": "Abstract:", + + // "item.preview.dc.identifier.other": "Other identifier:", + // TODO New key - Add a translation + "item.preview.dc.identifier.other": "Other identifier:", + + // "item.preview.dc.language.iso": "Language:", + // TODO New key - Add a translation + "item.preview.dc.language.iso": "Language:", + + // "item.preview.dc.subject": "Subjects:", + // TODO New key - Add a translation + "item.preview.dc.subject": "Subjects:", + + // "item.preview.dc.title": "Title:", + // TODO New key - Add a translation + "item.preview.dc.title": "Title:", + + // "item.preview.person.familyName": "Surname:", + // TODO New key - Add a translation + "item.preview.person.familyName": "Surname:", + + // "item.preview.person.givenName": "Name:", + // TODO New key - Add a translation + "item.preview.person.givenName": "Name:", + + // "item.preview.person.identifier.orcid": "ORCID:", + // TODO New key - Add a translation + "item.preview.person.identifier.orcid": "ORCID:", + + + // "item.select.confirm": "Confirm selected", + // TODO New key - Add a translation + "item.select.confirm": "Confirm selected", + + // "item.select.empty": "No items to show", + // TODO New key - Add a translation + "item.select.empty": "No items to show", + + // "item.select.table.author": "Author", + // TODO New key - Add a translation + "item.select.table.author": "Author", + + // "item.select.table.collection": "Collection", + // TODO New key - Add a translation + "item.select.table.collection": "Collection", + + // "item.select.table.title": "Title", + // TODO New key - Add a translation + "item.select.table.title": "Title", + + + // "item.version.history.empty": "There are no other versions for this item yet.", + // TODO New key - Add a translation + "item.version.history.empty": "There are no other versions for this item yet.", + + // "item.version.history.head": "Version History", + // TODO New key - Add a translation + "item.version.history.head": "Version History", + + // "item.version.history.return": "Return", + // TODO New key - Add a translation + "item.version.history.return": "Return", + + // "item.version.history.selected": "Selected version", + // TODO New key - Add a translation + "item.version.history.selected": "Selected version", + + // "item.version.history.table.version": "Version", + // TODO New key - Add a translation + "item.version.history.table.version": "Version", + + // "item.version.history.table.item": "Item", + // TODO New key - Add a translation + "item.version.history.table.item": "Item", + + // "item.version.history.table.editor": "Editor", + // TODO New key - Add a translation + "item.version.history.table.editor": "Editor", + + // "item.version.history.table.date": "Date", + // TODO New key - Add a translation + "item.version.history.table.date": "Date", + + // "item.version.history.table.summary": "Summary", + // TODO New key - Add a translation + "item.version.history.table.summary": "Summary", + + + + // "item.version.notice": "This is not the latest version of this item. The latest version can be found here.", + // TODO New key - Add a translation + "item.version.notice": "This is not the latest version of this item. The latest version can be found here.", + + + + // "journal.listelement.badge": "Journal", + // TODO New key - Add a translation + "journal.listelement.badge": "Journal", + + // "journal.page.description": "Description", + // TODO New key - Add a translation + "journal.page.description": "Description", + + // "journal.page.edit": "Edit this item", + // TODO New key - Add a translation + "journal.page.edit": "Edit this item", + + // "journal.page.editor": "Editor-in-Chief", + // TODO New key - Add a translation + "journal.page.editor": "Editor-in-Chief", + + // "journal.page.issn": "ISSN", + // TODO New key - Add a translation + "journal.page.issn": "ISSN", + + // "journal.page.publisher": "Publisher", + // TODO New key - Add a translation + "journal.page.publisher": "Publisher", + + // "journal.page.titleprefix": "Journal: ", + // TODO New key - Add a translation + "journal.page.titleprefix": "Journal: ", + + // "journal.search.results.head": "Journal Search Results", + // TODO New key - Add a translation + "journal.search.results.head": "Journal Search Results", + + // "journal.search.title": "DSpace Angular :: Journal Search", + // TODO New key - Add a translation + "journal.search.title": "DSpace Angular :: Journal Search", + + + + // "journalissue.listelement.badge": "Journal Issue", + // TODO New key - Add a translation + "journalissue.listelement.badge": "Journal Issue", + + // "journalissue.page.description": "Description", + // TODO New key - Add a translation + "journalissue.page.description": "Description", + + // "journalissue.page.edit": "Edit this item", + // TODO New key - Add a translation + "journalissue.page.edit": "Edit this item", + + // "journalissue.page.issuedate": "Issue Date", + // TODO New key - Add a translation + "journalissue.page.issuedate": "Issue Date", + + // "journalissue.page.journal-issn": "Journal ISSN", + // TODO New key - Add a translation + "journalissue.page.journal-issn": "Journal ISSN", + + // "journalissue.page.journal-title": "Journal Title", + // TODO New key - Add a translation + "journalissue.page.journal-title": "Journal Title", + + // "journalissue.page.keyword": "Keywords", + // TODO New key - Add a translation + "journalissue.page.keyword": "Keywords", + + // "journalissue.page.number": "Number", + // TODO New key - Add a translation + "journalissue.page.number": "Number", + + // "journalissue.page.titleprefix": "Journal Issue: ", + // TODO New key - Add a translation + "journalissue.page.titleprefix": "Journal Issue: ", + + + + // "journalvolume.listelement.badge": "Journal Volume", + // TODO New key - Add a translation + "journalvolume.listelement.badge": "Journal Volume", + + // "journalvolume.page.description": "Description", + // TODO New key - Add a translation + "journalvolume.page.description": "Description", + + // "journalvolume.page.edit": "Edit this item", + // TODO New key - Add a translation + "journalvolume.page.edit": "Edit this item", + + // "journalvolume.page.issuedate": "Issue Date", + // TODO New key - Add a translation + "journalvolume.page.issuedate": "Issue Date", + + // "journalvolume.page.titleprefix": "Journal Volume: ", + // TODO New key - Add a translation + "journalvolume.page.titleprefix": "Journal Volume: ", + + // "journalvolume.page.volume": "Volume", + // TODO New key - Add a translation + "journalvolume.page.volume": "Volume", + + + + // "loading.bitstream": "Loading bitstream...", + // TODO New key - Add a translation + "loading.bitstream": "Loading bitstream...", + + // "loading.bitstreams": "Loading bitstreams...", + // TODO New key - Add a translation + "loading.bitstreams": "Loading bitstreams...", + + // "loading.browse-by": "Loading items...", + // TODO New key - Add a translation + "loading.browse-by": "Loading items...", + + // "loading.browse-by-page": "Loading page...", + // TODO New key - Add a translation + "loading.browse-by-page": "Loading page...", + + // "loading.collection": "Loading collection...", + // TODO New key - Add a translation + "loading.collection": "Loading collection...", + + // "loading.collections": "Loading collections...", + // TODO New key - Add a translation + "loading.collections": "Loading collections...", + + // "loading.content-source": "Loading content source...", + // TODO New key - Add a translation + "loading.content-source": "Loading content source...", + + // "loading.community": "Loading community...", + // TODO New key - Add a translation + "loading.community": "Loading community...", + + // "loading.default": "Loading...", + // TODO New key - Add a translation + "loading.default": "Loading...", + + // "loading.item": "Loading item...", + // TODO New key - Add a translation + "loading.item": "Loading item...", + + // "loading.items": "Loading items...", + // TODO New key - Add a translation + "loading.items": "Loading items...", + + // "loading.mydspace-results": "Loading items...", + // TODO New key - Add a translation + "loading.mydspace-results": "Loading items...", + + // "loading.objects": "Loading...", + // TODO New key - Add a translation + "loading.objects": "Loading...", + + // "loading.recent-submissions": "Loading recent submissions...", + // TODO New key - Add a translation + "loading.recent-submissions": "Loading recent submissions...", + + // "loading.search-results": "Loading search results...", + // TODO New key - Add a translation + "loading.search-results": "Loading search results...", + + // "loading.sub-collections": "Loading sub-collections...", + // TODO New key - Add a translation + "loading.sub-collections": "Loading sub-collections...", + + // "loading.sub-communities": "Loading sub-communities...", + // TODO New key - Add a translation + "loading.sub-communities": "Loading sub-communities...", + + // "loading.top-level-communities": "Loading top-level communities...", + // TODO New key - Add a translation + "loading.top-level-communities": "Loading top-level communities...", + + + + // "login.form.email": "Email address", + // TODO New key - Add a translation + "login.form.email": "Email address", + + // "login.form.forgot-password": "Have you forgotten your password?", + // TODO New key - Add a translation + "login.form.forgot-password": "Have you forgotten your password?", + + // "login.form.header": "Please log in to DSpace", + // TODO New key - Add a translation + "login.form.header": "Please log in to DSpace", + + // "login.form.new-user": "New user? Click here to register.", + // TODO New key - Add a translation + "login.form.new-user": "New user? Click here to register.", + + // "login.form.or-divider": "or", + // TODO New key - Add a translation + "login.form.or-divider": "or", + + // "login.form.password": "Password", + // TODO New key - Add a translation + "login.form.password": "Password", + + // "login.form.shibboleth": "Log in with Shibboleth", + // TODO New key - Add a translation + "login.form.shibboleth": "Log in with Shibboleth", + + // "login.form.submit": "Log in", + // TODO New key - Add a translation + "login.form.submit": "Log in", + + // "login.title": "Login", + // TODO New key - Add a translation + "login.title": "Login", + + // "login.breadcrumbs": "Login", + // TODO New key - Add a translation + "login.breadcrumbs": "Login", + + + + // "logout.form.header": "Log out from DSpace", + // TODO New key - Add a translation + "logout.form.header": "Log out from DSpace", + + // "logout.form.submit": "Log out", + // TODO New key - Add a translation + "logout.form.submit": "Log out", + + // "logout.title": "Logout", + // TODO New key - Add a translation + "logout.title": "Logout", + + + + // "menu.header.admin": "Admin", + // TODO New key - Add a translation + "menu.header.admin": "Admin", + + // "menu.header.image.logo": "Repository logo", + // TODO New key - Add a translation + "menu.header.image.logo": "Repository logo", + + + + // "menu.section.access_control": "Access Control", + // TODO New key - Add a translation + "menu.section.access_control": "Access Control", + + // "menu.section.access_control_authorizations": "Authorizations", + // TODO New key - Add a translation + "menu.section.access_control_authorizations": "Authorizations", + + // "menu.section.access_control_groups": "Groups", + // TODO New key - Add a translation + "menu.section.access_control_groups": "Groups", + + // "menu.section.access_control_people": "People", + // TODO New key - Add a translation + "menu.section.access_control_people": "People", + + + + // "menu.section.admin_search": "Admin Search", + // TODO New key - Add a translation + "menu.section.admin_search": "Admin Search", + + + + // "menu.section.browse_community": "This Community", + // TODO New key - Add a translation + "menu.section.browse_community": "This Community", + + // "menu.section.browse_community_by_author": "By Author", + // TODO New key - Add a translation + "menu.section.browse_community_by_author": "By Author", + + // "menu.section.browse_community_by_issue_date": "By Issue Date", + // TODO New key - Add a translation + "menu.section.browse_community_by_issue_date": "By Issue Date", + + // "menu.section.browse_community_by_title": "By Title", + // TODO New key - Add a translation + "menu.section.browse_community_by_title": "By Title", + + // "menu.section.browse_global": "All of DSpace", + // TODO New key - Add a translation + "menu.section.browse_global": "All of DSpace", + + // "menu.section.browse_global_by_author": "By Author", + // TODO New key - Add a translation + "menu.section.browse_global_by_author": "By Author", + + // "menu.section.browse_global_by_dateissued": "By Issue Date", + // TODO New key - Add a translation + "menu.section.browse_global_by_dateissued": "By Issue Date", + + // "menu.section.browse_global_by_subject": "By Subject", + // TODO New key - Add a translation + "menu.section.browse_global_by_subject": "By Subject", + + // "menu.section.browse_global_by_title": "By Title", + // TODO New key - Add a translation + "menu.section.browse_global_by_title": "By Title", + + // "menu.section.browse_global_communities_and_collections": "Communities & Collections", + // TODO New key - Add a translation + "menu.section.browse_global_communities_and_collections": "Communities & Collections", + + + + // "menu.section.control_panel": "Control Panel", + // TODO New key - Add a translation + "menu.section.control_panel": "Control Panel", + + // "menu.section.curation_task": "Curation Task", + // TODO New key - Add a translation + "menu.section.curation_task": "Curation Task", + + + + // "menu.section.edit": "Edit", + // TODO New key - Add a translation + "menu.section.edit": "Edit", + + // "menu.section.edit_collection": "Collection", + // TODO New key - Add a translation + "menu.section.edit_collection": "Collection", + + // "menu.section.edit_community": "Community", + // TODO New key - Add a translation + "menu.section.edit_community": "Community", + + // "menu.section.edit_item": "Item", + // TODO New key - Add a translation + "menu.section.edit_item": "Item", + + + + // "menu.section.export": "Export", + // TODO New key - Add a translation + "menu.section.export": "Export", + + // "menu.section.export_collection": "Collection", + // TODO New key - Add a translation + "menu.section.export_collection": "Collection", + + // "menu.section.export_community": "Community", + // TODO New key - Add a translation + "menu.section.export_community": "Community", + + // "menu.section.export_item": "Item", + // TODO New key - Add a translation + "menu.section.export_item": "Item", + + // "menu.section.export_metadata": "Metadata", + // TODO New key - Add a translation + "menu.section.export_metadata": "Metadata", + + + + // "menu.section.icon.access_control": "Access Control menu section", + // TODO New key - Add a translation + "menu.section.icon.access_control": "Access Control menu section", + + // "menu.section.icon.admin_search": "Admin search menu section", + // TODO New key - Add a translation + "menu.section.icon.admin_search": "Admin search menu section", + + // "menu.section.icon.control_panel": "Control Panel menu section", + // TODO New key - Add a translation + "menu.section.icon.control_panel": "Control Panel menu section", + + // "menu.section.icon.curation_task": "Curation Task menu section", + // TODO New key - Add a translation + "menu.section.icon.curation_task": "Curation Task menu section", + + // "menu.section.icon.edit": "Edit menu section", + // TODO New key - Add a translation + "menu.section.icon.edit": "Edit menu section", + + // "menu.section.icon.export": "Export menu section", + // TODO New key - Add a translation + "menu.section.icon.export": "Export menu section", + + // "menu.section.icon.find": "Find menu section", + // TODO New key - Add a translation + "menu.section.icon.find": "Find menu section", + + // "menu.section.icon.import": "Import menu section", + // TODO New key - Add a translation + "menu.section.icon.import": "Import menu section", + + // "menu.section.icon.new": "New menu section", + // TODO New key - Add a translation + "menu.section.icon.new": "New menu section", + + // "menu.section.icon.pin": "Pin sidebar", + // TODO New key - Add a translation + "menu.section.icon.pin": "Pin sidebar", + + // "menu.section.icon.processes": "Processes menu section", + // TODO New key - Add a translation + "menu.section.icon.processes": "Processes menu section", + + // "menu.section.icon.registries": "Registries menu section", + // TODO New key - Add a translation + "menu.section.icon.registries": "Registries menu section", + + // "menu.section.icon.statistics_task": "Statistics Task menu section", + // TODO New key - Add a translation + "menu.section.icon.statistics_task": "Statistics Task menu section", + + // "menu.section.icon.unpin": "Unpin sidebar", + // TODO New key - Add a translation + "menu.section.icon.unpin": "Unpin sidebar", + + + + // "menu.section.import": "Import", + // TODO New key - Add a translation + "menu.section.import": "Import", + + // "menu.section.import_batch": "Batch Import (ZIP)", + // TODO New key - Add a translation + "menu.section.import_batch": "Batch Import (ZIP)", + + // "menu.section.import_metadata": "Metadata", + // TODO New key - Add a translation + "menu.section.import_metadata": "Metadata", + + + + // "menu.section.new": "New", + // TODO New key - Add a translation + "menu.section.new": "New", + + // "menu.section.new_collection": "Collection", + // TODO New key - Add a translation + "menu.section.new_collection": "Collection", + + // "menu.section.new_community": "Community", + // TODO New key - Add a translation + "menu.section.new_community": "Community", + + // "menu.section.new_item": "Item", + // TODO New key - Add a translation + "menu.section.new_item": "Item", + + // "menu.section.new_item_version": "Item Version", + // TODO New key - Add a translation + "menu.section.new_item_version": "Item Version", + + // "menu.section.new_process": "Process", + // TODO New key - Add a translation + "menu.section.new_process": "Process", + + + + // "menu.section.pin": "Pin sidebar", + // TODO New key - Add a translation + "menu.section.pin": "Pin sidebar", + + // "menu.section.unpin": "Unpin sidebar", + // TODO New key - Add a translation + "menu.section.unpin": "Unpin sidebar", + + + + // "menu.section.processes": "Processes", + // TODO New key - Add a translation + "menu.section.processes": "Processes", + + + + // "menu.section.registries": "Registries", + // TODO New key - Add a translation + "menu.section.registries": "Registries", + + // "menu.section.registries_format": "Format", + // TODO New key - Add a translation + "menu.section.registries_format": "Format", + + // "menu.section.registries_metadata": "Metadata", + // TODO New key - Add a translation + "menu.section.registries_metadata": "Metadata", + + + + // "menu.section.statistics": "Statistics", + // TODO New key - Add a translation + "menu.section.statistics": "Statistics", + + // "menu.section.statistics_task": "Statistics Task", + // TODO New key - Add a translation + "menu.section.statistics_task": "Statistics Task", + + + + // "menu.section.toggle.access_control": "Toggle Access Control section", + // TODO New key - Add a translation + "menu.section.toggle.access_control": "Toggle Access Control section", + + // "menu.section.toggle.control_panel": "Toggle Control Panel section", + // TODO New key - Add a translation + "menu.section.toggle.control_panel": "Toggle Control Panel section", + + // "menu.section.toggle.curation_task": "Toggle Curation Task section", + // TODO New key - Add a translation + "menu.section.toggle.curation_task": "Toggle Curation Task section", + + // "menu.section.toggle.edit": "Toggle Edit section", + // TODO New key - Add a translation + "menu.section.toggle.edit": "Toggle Edit section", + + // "menu.section.toggle.export": "Toggle Export section", + // TODO New key - Add a translation + "menu.section.toggle.export": "Toggle Export section", + + // "menu.section.toggle.find": "Toggle Find section", + // TODO New key - Add a translation + "menu.section.toggle.find": "Toggle Find section", + + // "menu.section.toggle.import": "Toggle Import section", + // TODO New key - Add a translation + "menu.section.toggle.import": "Toggle Import section", + + // "menu.section.toggle.new": "Toggle New section", + // TODO New key - Add a translation + "menu.section.toggle.new": "Toggle New section", + + // "menu.section.toggle.registries": "Toggle Registries section", + // TODO New key - Add a translation + "menu.section.toggle.registries": "Toggle Registries section", + + // "menu.section.toggle.statistics_task": "Toggle Statistics Task section", + // TODO New key - Add a translation + "menu.section.toggle.statistics_task": "Toggle Statistics Task section", + + + // "menu.section.workflow": "Administer Workflow", + // TODO New key - Add a translation + "menu.section.workflow": "Administer Workflow", + + + // "mydspace.description": "", + // TODO New key - Add a translation + "mydspace.description": "", + + // "mydspace.general.text-here": "here", + // TODO New key - Add a translation + "mydspace.general.text-here": "here", + + // "mydspace.messages.controller-help": "Select this option to send a message to item's submitter.", + // TODO New key - Add a translation + "mydspace.messages.controller-help": "Select this option to send a message to item's submitter.", + + // "mydspace.messages.description-placeholder": "Insert your message here...", + // TODO New key - Add a translation + "mydspace.messages.description-placeholder": "Insert your message here...", + + // "mydspace.messages.hide-msg": "Hide message", + // TODO New key - Add a translation + "mydspace.messages.hide-msg": "Hide message", + + // "mydspace.messages.mark-as-read": "Mark as read", + // TODO New key - Add a translation + "mydspace.messages.mark-as-read": "Mark as read", + + // "mydspace.messages.mark-as-unread": "Mark as unread", + // TODO New key - Add a translation + "mydspace.messages.mark-as-unread": "Mark as unread", + + // "mydspace.messages.no-content": "No content.", + // TODO New key - Add a translation + "mydspace.messages.no-content": "No content.", + + // "mydspace.messages.no-messages": "No messages yet.", + // TODO New key - Add a translation + "mydspace.messages.no-messages": "No messages yet.", + + // "mydspace.messages.send-btn": "Send", + // TODO New key - Add a translation + "mydspace.messages.send-btn": "Send", + + // "mydspace.messages.show-msg": "Show message", + // TODO New key - Add a translation + "mydspace.messages.show-msg": "Show message", + + // "mydspace.messages.subject-placeholder": "Subject...", + // TODO New key - Add a translation + "mydspace.messages.subject-placeholder": "Subject...", + + // "mydspace.messages.submitter-help": "Select this option to send a message to controller.", + // TODO New key - Add a translation + "mydspace.messages.submitter-help": "Select this option to send a message to controller.", + + // "mydspace.messages.title": "Messages", + // TODO New key - Add a translation + "mydspace.messages.title": "Messages", + + // "mydspace.messages.to": "To", + // TODO New key - Add a translation + "mydspace.messages.to": "To", + + // "mydspace.new-submission": "New submission", + // TODO New key - Add a translation + "mydspace.new-submission": "New submission", + + // "mydspace.new-submission-external": "Import metadata from external source", + // TODO New key - Add a translation + "mydspace.new-submission-external": "Import metadata from external source", + + // "mydspace.new-submission-external-short": "Import metadata", + // TODO New key - Add a translation + "mydspace.new-submission-external-short": "Import metadata", + + // "mydspace.results.head": "Your submissions", + // TODO New key - Add a translation + "mydspace.results.head": "Your submissions", + + // "mydspace.results.no-abstract": "No Abstract", + // TODO New key - Add a translation + "mydspace.results.no-abstract": "No Abstract", + + // "mydspace.results.no-authors": "No Authors", + // TODO New key - Add a translation + "mydspace.results.no-authors": "No Authors", + + // "mydspace.results.no-collections": "No Collections", + // TODO New key - Add a translation + "mydspace.results.no-collections": "No Collections", + + // "mydspace.results.no-date": "No Date", + // TODO New key - Add a translation + "mydspace.results.no-date": "No Date", + + // "mydspace.results.no-files": "No Files", + // TODO New key - Add a translation + "mydspace.results.no-files": "No Files", + + // "mydspace.results.no-results": "There were no items to show", + // TODO New key - Add a translation + "mydspace.results.no-results": "There were no items to show", + + // "mydspace.results.no-title": "No title", + // TODO New key - Add a translation + "mydspace.results.no-title": "No title", + + // "mydspace.results.no-uri": "No Uri", + // TODO New key - Add a translation + "mydspace.results.no-uri": "No Uri", + + // "mydspace.show.workflow": "All tasks", + // TODO New key - Add a translation + "mydspace.show.workflow": "All tasks", + + // "mydspace.show.workspace": "Your Submissions", + // TODO New key - Add a translation + "mydspace.show.workspace": "Your Submissions", + + // "mydspace.status.archived": "Archived", + // TODO New key - Add a translation + "mydspace.status.archived": "Archived", + + // "mydspace.status.validation": "Validation", + // TODO New key - Add a translation + "mydspace.status.validation": "Validation", + + // "mydspace.status.waiting-for-controller": "Waiting for controller", + // TODO New key - Add a translation + "mydspace.status.waiting-for-controller": "Waiting for controller", + + // "mydspace.status.workflow": "Workflow", + // TODO New key - Add a translation + "mydspace.status.workflow": "Workflow", + + // "mydspace.status.workspace": "Workspace", + // TODO New key - Add a translation + "mydspace.status.workspace": "Workspace", + + // "mydspace.title": "MyDSpace", + // TODO New key - Add a translation + "mydspace.title": "MyDSpace", + + // "mydspace.upload.upload-failed": "Error creating new workspace. Please verify the content uploaded before retry.", + // TODO New key - Add a translation + "mydspace.upload.upload-failed": "Error creating new workspace. Please verify the content uploaded before retry.", + + // "mydspace.upload.upload-failed-manyentries": "Unprocessable file. Detected too many entries but allowed only one for file.", + // TODO New key - Add a translation + "mydspace.upload.upload-failed-manyentries": "Unprocessable file. Detected too many entries but allowed only one for file.", + + // "mydspace.upload.upload-failed-moreonefile": "Unprocessable request. Only one file is allowed.", + // TODO New key - Add a translation + "mydspace.upload.upload-failed-moreonefile": "Unprocessable request. Only one file is allowed.", + + // "mydspace.upload.upload-multiple-successful": "{{qty}} new workspace items created.", + // TODO New key - Add a translation + "mydspace.upload.upload-multiple-successful": "{{qty}} new workspace items created.", + + // "mydspace.upload.upload-successful": "New workspace item created. Click {{here}} for edit it.", + // TODO New key - Add a translation + "mydspace.upload.upload-successful": "New workspace item created. Click {{here}} for edit it.", + + // "mydspace.view-btn": "View", + // TODO New key - Add a translation + "mydspace.view-btn": "View", + + + + // "nav.browse.header": "All of DSpace", + // TODO New key - Add a translation + "nav.browse.header": "All of DSpace", + + // "nav.community-browse.header": "By Community", + // TODO New key - Add a translation + "nav.community-browse.header": "By Community", + + // "nav.language": "Language switch", + // TODO New key - Add a translation + "nav.language": "Language switch", + + // "nav.login": "Log In", + // TODO New key - Add a translation + "nav.login": "Log In", + + // "nav.logout": "Log Out", + // TODO New key - Add a translation + "nav.logout": "Log Out", + + // "nav.mydspace": "MyDSpace", + // TODO New key - Add a translation + "nav.mydspace": "MyDSpace", + + // "nav.profile": "Profile", + // TODO New key - Add a translation + "nav.profile": "Profile", + + // "nav.search": "Search", + // TODO New key - Add a translation + "nav.search": "Search", + + // "nav.statistics.header": "Statistics", + // TODO New key - Add a translation + "nav.statistics.header": "Statistics", + + // "nav.stop-impersonating": "Stop impersonating EPerson", + // TODO New key - Add a translation + "nav.stop-impersonating": "Stop impersonating EPerson", + + + + // "orgunit.listelement.badge": "Organizational Unit", + // TODO New key - Add a translation + "orgunit.listelement.badge": "Organizational Unit", + + // "orgunit.page.city": "City", + // TODO New key - Add a translation + "orgunit.page.city": "City", + + // "orgunit.page.country": "Country", + // TODO New key - Add a translation + "orgunit.page.country": "Country", + + // "orgunit.page.dateestablished": "Date established", + // TODO New key - Add a translation + "orgunit.page.dateestablished": "Date established", + + // "orgunit.page.description": "Description", + // TODO New key - Add a translation + "orgunit.page.description": "Description", + + // "orgunit.page.edit": "Edit this item", + // TODO New key - Add a translation + "orgunit.page.edit": "Edit this item", + + // "orgunit.page.id": "ID", + // TODO New key - Add a translation + "orgunit.page.id": "ID", + + // "orgunit.page.titleprefix": "Organizational Unit: ", + // TODO New key - Add a translation + "orgunit.page.titleprefix": "Organizational Unit: ", + + + + // "pagination.results-per-page": "Results Per Page", + // TODO New key - Add a translation + "pagination.results-per-page": "Results Per Page", + + // "pagination.showing.detail": "{{ range }} of {{ total }}", + // TODO New key - Add a translation + "pagination.showing.detail": "{{ range }} of {{ total }}", + + // "pagination.showing.label": "Now showing ", + // TODO New key - Add a translation + "pagination.showing.label": "Now showing ", + + // "pagination.sort-direction": "Sort Options", + // TODO New key - Add a translation + "pagination.sort-direction": "Sort Options", + + + + // "person.listelement.badge": "Person", + // TODO New key - Add a translation + "person.listelement.badge": "Person", + + // "person.listelement.no-title": "No name found", + // TODO New key - Add a translation + "person.listelement.no-title": "No name found", + + // "person.page.birthdate": "Birth Date", + // TODO New key - Add a translation + "person.page.birthdate": "Birth Date", + + // "person.page.edit": "Edit this item", + // TODO New key - Add a translation + "person.page.edit": "Edit this item", + + // "person.page.email": "Email Address", + // TODO New key - Add a translation + "person.page.email": "Email Address", + + // "person.page.firstname": "First Name", + // TODO New key - Add a translation + "person.page.firstname": "First Name", + + // "person.page.jobtitle": "Job Title", + // TODO New key - Add a translation + "person.page.jobtitle": "Job Title", + + // "person.page.lastname": "Last Name", + // TODO New key - Add a translation + "person.page.lastname": "Last Name", + + // "person.page.link.full": "Show all metadata", + // TODO New key - Add a translation + "person.page.link.full": "Show all metadata", + + // "person.page.orcid": "ORCID", + // TODO New key - Add a translation + "person.page.orcid": "ORCID", + + // "person.page.staffid": "Staff ID", + // TODO New key - Add a translation + "person.page.staffid": "Staff ID", + + // "person.page.titleprefix": "Person: ", + // TODO New key - Add a translation + "person.page.titleprefix": "Person: ", + + // "person.search.results.head": "Person Search Results", + // TODO New key - Add a translation + "person.search.results.head": "Person Search Results", + + // "person.search.title": "DSpace Angular :: Person Search", + // TODO New key - Add a translation + "person.search.title": "DSpace Angular :: Person Search", + + + + // "process.new.select-parameters": "Parameters", + // TODO New key - Add a translation + "process.new.select-parameters": "Parameters", + + // "process.new.cancel": "Cancel", + // TODO New key - Add a translation + "process.new.cancel": "Cancel", + + // "process.new.submit": "Submit", + // TODO New key - Add a translation + "process.new.submit": "Submit", + + // "process.new.select-script": "Script", + // TODO New key - Add a translation + "process.new.select-script": "Script", + + // "process.new.select-script.placeholder": "Choose a script...", + // TODO New key - Add a translation + "process.new.select-script.placeholder": "Choose a script...", + + // "process.new.select-script.required": "Script is required", + // TODO New key - Add a translation + "process.new.select-script.required": "Script is required", + + // "process.new.parameter.file.upload-button": "Select file...", + // TODO New key - Add a translation + "process.new.parameter.file.upload-button": "Select file...", + + // "process.new.parameter.file.required": "Please select a file", + // TODO New key - Add a translation + "process.new.parameter.file.required": "Please select a file", + + // "process.new.parameter.string.required": "Parameter value is required", + // TODO New key - Add a translation + "process.new.parameter.string.required": "Parameter value is required", + + // "process.new.parameter.type.value": "value", + // TODO New key - Add a translation + "process.new.parameter.type.value": "value", + + // "process.new.parameter.type.file": "file", + // TODO New key - Add a translation + "process.new.parameter.type.file": "file", + + // "process.new.parameter.required.missing": "The following parameters are required but still missing:", + // TODO New key - Add a translation + "process.new.parameter.required.missing": "The following parameters are required but still missing:", + + // "process.new.notification.success.title": "Success", + // TODO New key - Add a translation + "process.new.notification.success.title": "Success", + + // "process.new.notification.success.content": "The process was successfully created", + // TODO New key - Add a translation + "process.new.notification.success.content": "The process was successfully created", + + // "process.new.notification.error.title": "Error", + // TODO New key - Add a translation + "process.new.notification.error.title": "Error", + + // "process.new.notification.error.content": "An error occurred while creating this process", + // TODO New key - Add a translation + "process.new.notification.error.content": "An error occurred while creating this process", + + // "process.new.header": "Create a new process", + // TODO New key - Add a translation + "process.new.header": "Create a new process", + + // "process.new.title": "Create a new process", + // TODO New key - Add a translation + "process.new.title": "Create a new process", + + // "process.new.breadcrumbs": "Create a new process", + // TODO New key - Add a translation + "process.new.breadcrumbs": "Create a new process", + + + + // "process.detail.arguments" : "Arguments", + // TODO New key - Add a translation + "process.detail.arguments" : "Arguments", + + // "process.detail.arguments.empty" : "This process doesn't contain any arguments", + // TODO New key - Add a translation + "process.detail.arguments.empty" : "This process doesn't contain any arguments", + + // "process.detail.back" : "Back", + // TODO New key - Add a translation + "process.detail.back" : "Back", + + // "process.detail.output" : "Process Output", + // TODO New key - Add a translation + "process.detail.output" : "Process Output", + + // "process.detail.logs.button": "Retrieve process output", + // TODO New key - Add a translation + "process.detail.logs.button": "Retrieve process output", + + // "process.detail.logs.loading": "Retrieving", + // TODO New key - Add a translation + "process.detail.logs.loading": "Retrieving", + + // "process.detail.logs.none": "This process has no output", + // TODO New key - Add a translation + "process.detail.logs.none": "This process has no output", + + // "process.detail.output-files" : "Output Files", + // TODO New key - Add a translation + "process.detail.output-files" : "Output Files", + + // "process.detail.output-files.empty" : "This process doesn't contain any output files", + // TODO New key - Add a translation + "process.detail.output-files.empty" : "This process doesn't contain any output files", + + // "process.detail.script" : "Script", + // TODO New key - Add a translation + "process.detail.script" : "Script", + + // "process.detail.title" : "Process: {{ id }} - {{ name }}", + // TODO New key - Add a translation + "process.detail.title" : "Process: {{ id }} - {{ name }}", + + // "process.detail.start-time" : "Start time", + // TODO New key - Add a translation + "process.detail.start-time" : "Start time", + + // "process.detail.end-time" : "Finish time", + // TODO New key - Add a translation + "process.detail.end-time" : "Finish time", + + // "process.detail.status" : "Status", + // TODO New key - Add a translation + "process.detail.status" : "Status", + + // "process.detail.create" : "Create similar process", + // TODO New key - Add a translation + "process.detail.create" : "Create similar process", + + + + // "process.overview.table.finish" : "Finish time", + // TODO New key - Add a translation + "process.overview.table.finish" : "Finish time", + + // "process.overview.table.id" : "Process ID", + // TODO New key - Add a translation + "process.overview.table.id" : "Process ID", + + // "process.overview.table.name" : "Name", + // TODO New key - Add a translation + "process.overview.table.name" : "Name", + + // "process.overview.table.start" : "Start time", + // TODO New key - Add a translation + "process.overview.table.start" : "Start time", + + // "process.overview.table.status" : "Status", + // TODO New key - Add a translation + "process.overview.table.status" : "Status", + + // "process.overview.table.user" : "User", + // TODO New key - Add a translation + "process.overview.table.user" : "User", + + // "process.overview.title": "Processes Overview", + // TODO New key - Add a translation + "process.overview.title": "Processes Overview", + + // "process.overview.breadcrumbs": "Processes Overview", + // TODO New key - Add a translation + "process.overview.breadcrumbs": "Processes Overview", + + // "process.overview.new": "New", + // TODO New key - Add a translation + "process.overview.new": "New", + + + // "profile.breadcrumbs": "Update Profile", + // TODO New key - Add a translation + "profile.breadcrumbs": "Update Profile", + + // "profile.card.identify": "Identify", + // TODO New key - Add a translation + "profile.card.identify": "Identify", + + // "profile.card.security": "Security", + // TODO New key - Add a translation + "profile.card.security": "Security", + + // "profile.form.submit": "Update Profile", + // TODO New key - Add a translation + "profile.form.submit": "Update Profile", + + // "profile.groups.head": "Authorization groups you belong to", + // TODO New key - Add a translation + "profile.groups.head": "Authorization groups you belong to", + + // "profile.head": "Update Profile", + // TODO New key - Add a translation + "profile.head": "Update Profile", + + // "profile.metadata.form.error.firstname.required": "First Name is required", + // TODO New key - Add a translation + "profile.metadata.form.error.firstname.required": "First Name is required", + + // "profile.metadata.form.error.lastname.required": "Last Name is required", + // TODO New key - Add a translation + "profile.metadata.form.error.lastname.required": "Last Name is required", + + // "profile.metadata.form.label.email": "Email Address", + // TODO New key - Add a translation + "profile.metadata.form.label.email": "Email Address", + + // "profile.metadata.form.label.firstname": "First Name", + // TODO New key - Add a translation + "profile.metadata.form.label.firstname": "First Name", + + // "profile.metadata.form.label.language": "Language", + // TODO New key - Add a translation + "profile.metadata.form.label.language": "Language", + + // "profile.metadata.form.label.lastname": "Last Name", + // TODO New key - Add a translation + "profile.metadata.form.label.lastname": "Last Name", + + // "profile.metadata.form.label.phone": "Contact Telephone", + // TODO New key - Add a translation + "profile.metadata.form.label.phone": "Contact Telephone", + + // "profile.metadata.form.notifications.success.content": "Your changes to the profile were saved.", + // TODO New key - Add a translation + "profile.metadata.form.notifications.success.content": "Your changes to the profile were saved.", + + // "profile.metadata.form.notifications.success.title": "Profile saved", + // TODO New key - Add a translation + "profile.metadata.form.notifications.success.title": "Profile saved", + + // "profile.notifications.warning.no-changes.content": "No changes were made to the Profile.", + // TODO New key - Add a translation + "profile.notifications.warning.no-changes.content": "No changes were made to the Profile.", + + // "profile.notifications.warning.no-changes.title": "No changes", + // TODO New key - Add a translation + "profile.notifications.warning.no-changes.title": "No changes", + + // "profile.security.form.error.matching-passwords": "The passwords do not match.", + // TODO New key - Add a translation + "profile.security.form.error.matching-passwords": "The passwords do not match.", + + // "profile.security.form.error.password-length": "The password should be at least 6 characters long.", + // TODO New key - Add a translation + "profile.security.form.error.password-length": "The password should be at least 6 characters long.", + + // "profile.security.form.info": "Optionally, you can enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", + // TODO New key - Add a translation + "profile.security.form.info": "Optionally, you can enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", + + // "profile.security.form.label.password": "Password", + // TODO New key - Add a translation + "profile.security.form.label.password": "Password", + + // "profile.security.form.label.passwordrepeat": "Retype to confirm", + // TODO New key - Add a translation + "profile.security.form.label.passwordrepeat": "Retype to confirm", + + // "profile.security.form.notifications.success.content": "Your changes to the password were saved.", + // TODO New key - Add a translation + "profile.security.form.notifications.success.content": "Your changes to the password were saved.", + + // "profile.security.form.notifications.success.title": "Password saved", + // TODO New key - Add a translation + "profile.security.form.notifications.success.title": "Password saved", + + // "profile.security.form.notifications.error.title": "Error changing passwords", + // TODO New key - Add a translation + "profile.security.form.notifications.error.title": "Error changing passwords", + + // "profile.security.form.notifications.error.not-long-enough": "The password has to be at least 6 characters long.", + // TODO New key - Add a translation + "profile.security.form.notifications.error.not-long-enough": "The password has to be at least 6 characters long.", + + // "profile.security.form.notifications.error.not-same": "The provided passwords are not the same.", + // TODO New key - Add a translation + "profile.security.form.notifications.error.not-same": "The provided passwords are not the same.", + + // "profile.title": "Update Profile", + // TODO New key - Add a translation + "profile.title": "Update Profile", + + + + // "project.listelement.badge": "Research Project", + // TODO New key - Add a translation + "project.listelement.badge": "Research Project", + + // "project.page.contributor": "Contributors", + // TODO New key - Add a translation + "project.page.contributor": "Contributors", + + // "project.page.description": "Description", + // TODO New key - Add a translation + "project.page.description": "Description", + + // "project.page.edit": "Edit this item", + // TODO New key - Add a translation + "project.page.edit": "Edit this item", + + // "project.page.expectedcompletion": "Expected Completion", + // TODO New key - Add a translation + "project.page.expectedcompletion": "Expected Completion", + + // "project.page.funder": "Funders", + // TODO New key - Add a translation + "project.page.funder": "Funders", + + // "project.page.id": "ID", + // TODO New key - Add a translation + "project.page.id": "ID", + + // "project.page.keyword": "Keywords", + // TODO New key - Add a translation + "project.page.keyword": "Keywords", + + // "project.page.status": "Status", + // TODO New key - Add a translation + "project.page.status": "Status", + + // "project.page.titleprefix": "Research Project: ", + // TODO New key - Add a translation + "project.page.titleprefix": "Research Project: ", + + // "project.search.results.head": "Project Search Results", + // TODO New key - Add a translation + "project.search.results.head": "Project Search Results", + + + + // "publication.listelement.badge": "Publication", + // TODO New key - Add a translation + "publication.listelement.badge": "Publication", + + // "publication.page.description": "Description", + // TODO New key - Add a translation + "publication.page.description": "Description", + + // "publication.page.edit": "Edit this item", + // TODO New key - Add a translation + "publication.page.edit": "Edit this item", + + // "publication.page.journal-issn": "Journal ISSN", + // TODO New key - Add a translation + "publication.page.journal-issn": "Journal ISSN", + + // "publication.page.journal-title": "Journal Title", + // TODO New key - Add a translation + "publication.page.journal-title": "Journal Title", + + // "publication.page.publisher": "Publisher", + // TODO New key - Add a translation + "publication.page.publisher": "Publisher", + + // "publication.page.titleprefix": "Publication: ", + // TODO New key - Add a translation + "publication.page.titleprefix": "Publication: ", + + // "publication.page.volume-title": "Volume Title", + // TODO New key - Add a translation + "publication.page.volume-title": "Volume Title", + + // "publication.search.results.head": "Publication Search Results", + // TODO New key - Add a translation + "publication.search.results.head": "Publication Search Results", + + // "publication.search.title": "DSpace Angular :: Publication Search", + // TODO New key - Add a translation + "publication.search.title": "DSpace Angular :: Publication Search", + + + // "register-email.title": "New user registration", + // TODO New key - Add a translation + "register-email.title": "New user registration", + + // "register-page.create-profile.header": "Create Profile", + // TODO New key - Add a translation + "register-page.create-profile.header": "Create Profile", + + // "register-page.create-profile.identification.header": "Identify", + // TODO New key - Add a translation + "register-page.create-profile.identification.header": "Identify", + + // "register-page.create-profile.identification.email": "Email Address", + // TODO New key - Add a translation + "register-page.create-profile.identification.email": "Email Address", + + // "register-page.create-profile.identification.first-name": "First Name *", + // TODO New key - Add a translation + "register-page.create-profile.identification.first-name": "First Name *", + + // "register-page.create-profile.identification.first-name.error": "Please fill in a First Name", + // TODO New key - Add a translation + "register-page.create-profile.identification.first-name.error": "Please fill in a First Name", + + // "register-page.create-profile.identification.last-name": "Last Name *", + // TODO New key - Add a translation + "register-page.create-profile.identification.last-name": "Last Name *", + + // "register-page.create-profile.identification.last-name.error": "Please fill in a Last Name", + // TODO New key - Add a translation + "register-page.create-profile.identification.last-name.error": "Please fill in a Last Name", + + // "register-page.create-profile.identification.contact": "Contact Telephone", + // TODO New key - Add a translation + "register-page.create-profile.identification.contact": "Contact Telephone", + + // "register-page.create-profile.identification.language": "Language", + // TODO New key - Add a translation + "register-page.create-profile.identification.language": "Language", + + // "register-page.create-profile.security.header": "Security", + // TODO New key - Add a translation + "register-page.create-profile.security.header": "Security", + + // "register-page.create-profile.security.info": "Please enter a password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", + // TODO New key - Add a translation + "register-page.create-profile.security.info": "Please enter a password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", + + // "register-page.create-profile.security.label.password": "Password *", + // TODO New key - Add a translation + "register-page.create-profile.security.label.password": "Password *", + + // "register-page.create-profile.security.label.passwordrepeat": "Retype to confirm *", + // TODO New key - Add a translation + "register-page.create-profile.security.label.passwordrepeat": "Retype to confirm *", + + // "register-page.create-profile.security.error.empty-password": "Please enter a password in the box below.", + // TODO New key - Add a translation + "register-page.create-profile.security.error.empty-password": "Please enter a password in the box below.", + + // "register-page.create-profile.security.error.matching-passwords": "The passwords do not match.", + // TODO New key - Add a translation + "register-page.create-profile.security.error.matching-passwords": "The passwords do not match.", + + // "register-page.create-profile.security.error.password-length": "The password should be at least 6 characters long.", + // TODO New key - Add a translation + "register-page.create-profile.security.error.password-length": "The password should be at least 6 characters long.", + + // "register-page.create-profile.submit": "Complete Registration", + // TODO New key - Add a translation + "register-page.create-profile.submit": "Complete Registration", + + // "register-page.create-profile.submit.error.content": "Something went wrong while registering a new user.", + // TODO New key - Add a translation + "register-page.create-profile.submit.error.content": "Something went wrong while registering a new user.", + + // "register-page.create-profile.submit.error.head": "Registration failed", + // TODO New key - Add a translation + "register-page.create-profile.submit.error.head": "Registration failed", + + // "register-page.create-profile.submit.success.content": "The registration was successful. You have been logged in as the created user.", + // TODO New key - Add a translation + "register-page.create-profile.submit.success.content": "The registration was successful. You have been logged in as the created user.", + + // "register-page.create-profile.submit.success.head": "Registration completed", + // TODO New key - Add a translation + "register-page.create-profile.submit.success.head": "Registration completed", + + + // "register-page.registration.header": "New user registration", + // TODO New key - Add a translation + "register-page.registration.header": "New user registration", + + // "register-page.registration.info": "Register an account to subscribe to collections for email updates, and submit new items to DSpace.", + // TODO New key - Add a translation + "register-page.registration.info": "Register an account to subscribe to collections for email updates, and submit new items to DSpace.", + + // "register-page.registration.email": "Email Address *", + // TODO New key - Add a translation + "register-page.registration.email": "Email Address *", + + // "register-page.registration.email.error.required": "Please fill in an email address", + // TODO New key - Add a translation + "register-page.registration.email.error.required": "Please fill in an email address", + + // "register-page.registration.email.error.pattern": "Please fill in a valid email address", + // TODO New key - Add a translation + "register-page.registration.email.error.pattern": "Please fill in a valid email address", + + // "register-page.registration.email.hint": "This address will be verified and used as your login name.", + // TODO New key - Add a translation + "register-page.registration.email.hint": "This address will be verified and used as your login name.", + + // "register-page.registration.submit": "Register", + // TODO New key - Add a translation + "register-page.registration.submit": "Register", + + // "register-page.registration.success.head": "Verification email sent", + // TODO New key - Add a translation + "register-page.registration.success.head": "Verification email sent", + + // "register-page.registration.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", + // TODO New key - Add a translation + "register-page.registration.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", + + // "register-page.registration.error.head": "Error when trying to register email", + // TODO New key - Add a translation + "register-page.registration.error.head": "Error when trying to register email", + + // "register-page.registration.error.content": "An error occured when registering the following email address: {{ email }}", + // TODO New key - Add a translation + "register-page.registration.error.content": "An error occured when registering the following email address: {{ email }}", + + + + // "relationships.add.error.relationship-type.content": "No suitable match could be found for relationship type {{ type }} between the two items", + // TODO New key - Add a translation + "relationships.add.error.relationship-type.content": "No suitable match could be found for relationship type {{ type }} between the two items", + + // "relationships.add.error.server.content": "The server returned an error", + // TODO New key - Add a translation + "relationships.add.error.server.content": "The server returned an error", + + // "relationships.add.error.title": "Unable to add relationship", + // TODO New key - Add a translation + "relationships.add.error.title": "Unable to add relationship", + + // "relationships.isAuthorOf": "Authors", + // TODO New key - Add a translation + "relationships.isAuthorOf": "Authors", + + // "relationships.isAuthorOf.Person": "Authors (persons)", + // TODO New key - Add a translation + "relationships.isAuthorOf.Person": "Authors (persons)", + + // "relationships.isAuthorOf.OrgUnit": "Authors (organizational units)", + // TODO New key - Add a translation + "relationships.isAuthorOf.OrgUnit": "Authors (organizational units)", + + // "relationships.isIssueOf": "Journal Issues", + // TODO New key - Add a translation + "relationships.isIssueOf": "Journal Issues", + + // "relationships.isJournalIssueOf": "Journal Issue", + // TODO New key - Add a translation + "relationships.isJournalIssueOf": "Journal Issue", + + // "relationships.isJournalOf": "Journals", + // TODO New key - Add a translation + "relationships.isJournalOf": "Journals", + + // "relationships.isOrgUnitOf": "Organizational Units", + // TODO New key - Add a translation + "relationships.isOrgUnitOf": "Organizational Units", + + // "relationships.isPersonOf": "Authors", + // TODO New key - Add a translation + "relationships.isPersonOf": "Authors", + + // "relationships.isProjectOf": "Research Projects", + // TODO New key - Add a translation + "relationships.isProjectOf": "Research Projects", + + // "relationships.isPublicationOf": "Publications", + // TODO New key - Add a translation + "relationships.isPublicationOf": "Publications", + + // "relationships.isPublicationOfJournalIssue": "Articles", + // TODO New key - Add a translation + "relationships.isPublicationOfJournalIssue": "Articles", + + // "relationships.isSingleJournalOf": "Journal", + // TODO New key - Add a translation + "relationships.isSingleJournalOf": "Journal", + + // "relationships.isSingleVolumeOf": "Journal Volume", + // TODO New key - Add a translation + "relationships.isSingleVolumeOf": "Journal Volume", + + // "relationships.isVolumeOf": "Journal Volumes", + // TODO New key - Add a translation + "relationships.isVolumeOf": "Journal Volumes", + + // "relationships.isContributorOf": "Contributors", + // TODO New key - Add a translation + "relationships.isContributorOf": "Contributors", + + + + // "resource-policies.add.button": "Add", + // TODO New key - Add a translation + "resource-policies.add.button": "Add", + + // "resource-policies.add.for.": "Add a new policy", + // TODO New key - Add a translation + "resource-policies.add.for.": "Add a new policy", + + // "resource-policies.add.for.bitstream": "Add a new Bitstream policy", + // TODO New key - Add a translation + "resource-policies.add.for.bitstream": "Add a new Bitstream policy", + + // "resource-policies.add.for.bundle": "Add a new Bundle policy", + // TODO New key - Add a translation + "resource-policies.add.for.bundle": "Add a new Bundle policy", + + // "resource-policies.add.for.item": "Add a new Item policy", + // TODO New key - Add a translation + "resource-policies.add.for.item": "Add a new Item policy", + + // "resource-policies.add.for.community": "Add a new Community policy", + // TODO New key - Add a translation + "resource-policies.add.for.community": "Add a new Community policy", + + // "resource-policies.add.for.collection": "Add a new Collection policy", + // TODO New key - Add a translation + "resource-policies.add.for.collection": "Add a new Collection policy", + + // "resource-policies.create.page.heading": "Create new resource policy for ", + // TODO New key - Add a translation + "resource-policies.create.page.heading": "Create new resource policy for ", + + // "resource-policies.create.page.failure.content": "An error occurred while creating the resource policy.", + // TODO New key - Add a translation + "resource-policies.create.page.failure.content": "An error occurred while creating the resource policy.", + + // "resource-policies.create.page.success.content": "Operation successful", + // TODO New key - Add a translation + "resource-policies.create.page.success.content": "Operation successful", + + // "resource-policies.create.page.title": "Create new resource policy", + // TODO New key - Add a translation + "resource-policies.create.page.title": "Create new resource policy", + + // "resource-policies.delete.btn": "Delete selected", + // TODO New key - Add a translation + "resource-policies.delete.btn": "Delete selected", + + // "resource-policies.delete.btn.title": "Delete selected resource policies", + // TODO New key - Add a translation + "resource-policies.delete.btn.title": "Delete selected resource policies", + + // "resource-policies.delete.failure.content": "An error occurred while deleting selected resource policies.", + // TODO New key - Add a translation + "resource-policies.delete.failure.content": "An error occurred while deleting selected resource policies.", + + // "resource-policies.delete.success.content": "Operation successful", + // TODO New key - Add a translation + "resource-policies.delete.success.content": "Operation successful", + + // "resource-policies.edit.page.heading": "Edit resource policy ", + // TODO New key - Add a translation + "resource-policies.edit.page.heading": "Edit resource policy ", + + // "resource-policies.edit.page.failure.content": "An error occurred while editing the resource policy.", + // TODO New key - Add a translation + "resource-policies.edit.page.failure.content": "An error occurred while editing the resource policy.", + + // "resource-policies.edit.page.success.content": "Operation successful", + // TODO New key - Add a translation + "resource-policies.edit.page.success.content": "Operation successful", + + // "resource-policies.edit.page.title": "Edit resource policy", + // TODO New key - Add a translation + "resource-policies.edit.page.title": "Edit resource policy", + + // "resource-policies.form.action-type.label": "Select the action type", + // TODO New key - Add a translation + "resource-policies.form.action-type.label": "Select the action type", + + // "resource-policies.form.action-type.required": "You must select the resource policy action.", + // TODO New key - Add a translation + "resource-policies.form.action-type.required": "You must select the resource policy action.", + + // "resource-policies.form.eperson-group-list.label": "The eperson or group that will be granted the permission", + // TODO New key - Add a translation + "resource-policies.form.eperson-group-list.label": "The eperson or group that will be granted the permission", + + // "resource-policies.form.eperson-group-list.select.btn": "Select", + // TODO New key - Add a translation + "resource-policies.form.eperson-group-list.select.btn": "Select", + + // "resource-policies.form.eperson-group-list.tab.eperson": "Search for a ePerson", + // TODO New key - Add a translation + "resource-policies.form.eperson-group-list.tab.eperson": "Search for a ePerson", + + // "resource-policies.form.eperson-group-list.tab.group": "Search for a group", + // TODO New key - Add a translation + "resource-policies.form.eperson-group-list.tab.group": "Search for a group", + + // "resource-policies.form.eperson-group-list.table.headers.action": "Action", + // TODO New key - Add a translation + "resource-policies.form.eperson-group-list.table.headers.action": "Action", + + // "resource-policies.form.eperson-group-list.table.headers.id": "ID", + // TODO New key - Add a translation + "resource-policies.form.eperson-group-list.table.headers.id": "ID", + + // "resource-policies.form.eperson-group-list.table.headers.name": "Name", + // TODO New key - Add a translation + "resource-policies.form.eperson-group-list.table.headers.name": "Name", + + // "resource-policies.form.date.end.label": "End Date", + // TODO New key - Add a translation + "resource-policies.form.date.end.label": "End Date", + + // "resource-policies.form.date.start.label": "Start Date", + // TODO New key - Add a translation + "resource-policies.form.date.start.label": "Start Date", + + // "resource-policies.form.description.label": "Description", + // TODO New key - Add a translation + "resource-policies.form.description.label": "Description", + + // "resource-policies.form.name.label": "Name", + // TODO New key - Add a translation + "resource-policies.form.name.label": "Name", + + // "resource-policies.form.policy-type.label": "Select the policy type", + // TODO New key - Add a translation + "resource-policies.form.policy-type.label": "Select the policy type", + + // "resource-policies.form.policy-type.required": "You must select the resource policy type.", + // TODO New key - Add a translation + "resource-policies.form.policy-type.required": "You must select the resource policy type.", + + // "resource-policies.table.headers.action": "Action", + // TODO New key - Add a translation + "resource-policies.table.headers.action": "Action", + + // "resource-policies.table.headers.date.end": "End Date", + // TODO New key - Add a translation + "resource-policies.table.headers.date.end": "End Date", + + // "resource-policies.table.headers.date.start": "Start Date", + // TODO New key - Add a translation + "resource-policies.table.headers.date.start": "Start Date", + + // "resource-policies.table.headers.edit": "Edit", + // TODO New key - Add a translation + "resource-policies.table.headers.edit": "Edit", + + // "resource-policies.table.headers.edit.group": "Edit group", + // TODO New key - Add a translation + "resource-policies.table.headers.edit.group": "Edit group", + + // "resource-policies.table.headers.edit.policy": "Edit policy", + // TODO New key - Add a translation + "resource-policies.table.headers.edit.policy": "Edit policy", + + // "resource-policies.table.headers.eperson": "EPerson", + // TODO New key - Add a translation + "resource-policies.table.headers.eperson": "EPerson", + + // "resource-policies.table.headers.group": "Group", + // TODO New key - Add a translation + "resource-policies.table.headers.group": "Group", + + // "resource-policies.table.headers.id": "ID", + // TODO New key - Add a translation + "resource-policies.table.headers.id": "ID", + + // "resource-policies.table.headers.name": "Name", + // TODO New key - Add a translation + "resource-policies.table.headers.name": "Name", + + // "resource-policies.table.headers.policyType": "type", + // TODO New key - Add a translation + "resource-policies.table.headers.policyType": "type", + + // "resource-policies.table.headers.title.for.bitstream": "Policies for Bitstream", + // TODO New key - Add a translation + "resource-policies.table.headers.title.for.bitstream": "Policies for Bitstream", + + // "resource-policies.table.headers.title.for.bundle": "Policies for Bundle", + // TODO New key - Add a translation + "resource-policies.table.headers.title.for.bundle": "Policies for Bundle", + + // "resource-policies.table.headers.title.for.item": "Policies for Item", + // TODO New key - Add a translation + "resource-policies.table.headers.title.for.item": "Policies for Item", + + // "resource-policies.table.headers.title.for.community": "Policies for Community", + // TODO New key - Add a translation + "resource-policies.table.headers.title.for.community": "Policies for Community", + + // "resource-policies.table.headers.title.for.collection": "Policies for Collection", + // TODO New key - Add a translation + "resource-policies.table.headers.title.for.collection": "Policies for Collection", + + + + // "search.description": "", + // TODO New key - Add a translation + "search.description": "", + + // "search.switch-configuration.title": "Show", + // TODO New key - Add a translation + "search.switch-configuration.title": "Show", + + // "search.title": "DSpace Angular :: Search", + // TODO New key - Add a translation + "search.title": "DSpace Angular :: Search", + + // "search.breadcrumbs": "Search", + // TODO New key - Add a translation + "search.breadcrumbs": "Search", + + + // "search.filters.applied.f.author": "Author", + // TODO New key - Add a translation + "search.filters.applied.f.author": "Author", + + // "search.filters.applied.f.dateIssued.max": "End date", + // TODO New key - Add a translation + "search.filters.applied.f.dateIssued.max": "End date", + + // "search.filters.applied.f.dateIssued.min": "Start date", + // TODO New key - Add a translation + "search.filters.applied.f.dateIssued.min": "Start date", + + // "search.filters.applied.f.dateSubmitted": "Date submitted", + // TODO New key - Add a translation + "search.filters.applied.f.dateSubmitted": "Date submitted", + + // "search.filters.applied.f.discoverable": "Private", + // TODO New key - Add a translation + "search.filters.applied.f.discoverable": "Private", + + // "search.filters.applied.f.entityType": "Item Type", + // TODO New key - Add a translation + "search.filters.applied.f.entityType": "Item Type", + + // "search.filters.applied.f.has_content_in_original_bundle": "Has files", + // TODO New key - Add a translation + "search.filters.applied.f.has_content_in_original_bundle": "Has files", + + // "search.filters.applied.f.itemtype": "Type", + // TODO New key - Add a translation + "search.filters.applied.f.itemtype": "Type", + + // "search.filters.applied.f.namedresourcetype": "Status", + // TODO New key - Add a translation + "search.filters.applied.f.namedresourcetype": "Status", + + // "search.filters.applied.f.subject": "Subject", + // TODO New key - Add a translation + "search.filters.applied.f.subject": "Subject", + + // "search.filters.applied.f.submitter": "Submitter", + // TODO New key - Add a translation + "search.filters.applied.f.submitter": "Submitter", + + // "search.filters.applied.f.jobTitle": "Job Title", + // TODO New key - Add a translation + "search.filters.applied.f.jobTitle": "Job Title", + + // "search.filters.applied.f.birthDate.max": "End birth date", + // TODO New key - Add a translation + "search.filters.applied.f.birthDate.max": "End birth date", + + // "search.filters.applied.f.birthDate.min": "Start birth date", + // TODO New key - Add a translation + "search.filters.applied.f.birthDate.min": "Start birth date", + + // "search.filters.applied.f.withdrawn": "Withdrawn", + // TODO New key - Add a translation + "search.filters.applied.f.withdrawn": "Withdrawn", + + + + // "search.filters.filter.author.head": "Author", + // TODO New key - Add a translation + "search.filters.filter.author.head": "Author", + + // "search.filters.filter.author.placeholder": "Author name", + // TODO New key - Add a translation + "search.filters.filter.author.placeholder": "Author name", + + // "search.filters.filter.birthDate.head": "Birth Date", + // TODO New key - Add a translation + "search.filters.filter.birthDate.head": "Birth Date", + + // "search.filters.filter.birthDate.placeholder": "Birth Date", + // TODO New key - Add a translation + "search.filters.filter.birthDate.placeholder": "Birth Date", + + // "search.filters.filter.creativeDatePublished.head": "Date Published", + // TODO New key - Add a translation + "search.filters.filter.creativeDatePublished.head": "Date Published", + + // "search.filters.filter.creativeDatePublished.placeholder": "Date Published", + // TODO New key - Add a translation + "search.filters.filter.creativeDatePublished.placeholder": "Date Published", + + // "search.filters.filter.creativeWorkEditor.head": "Editor", + // TODO New key - Add a translation + "search.filters.filter.creativeWorkEditor.head": "Editor", + + // "search.filters.filter.creativeWorkEditor.placeholder": "Editor", + // TODO New key - Add a translation + "search.filters.filter.creativeWorkEditor.placeholder": "Editor", + + // "search.filters.filter.creativeWorkKeywords.head": "Subject", + // TODO New key - Add a translation + "search.filters.filter.creativeWorkKeywords.head": "Subject", + + // "search.filters.filter.creativeWorkKeywords.placeholder": "Subject", + // TODO New key - Add a translation + "search.filters.filter.creativeWorkKeywords.placeholder": "Subject", + + // "search.filters.filter.creativeWorkPublisher.head": "Publisher", + // TODO New key - Add a translation + "search.filters.filter.creativeWorkPublisher.head": "Publisher", + + // "search.filters.filter.creativeWorkPublisher.placeholder": "Publisher", + // TODO New key - Add a translation + "search.filters.filter.creativeWorkPublisher.placeholder": "Publisher", + + // "search.filters.filter.dateIssued.head": "Date", + // TODO New key - Add a translation + "search.filters.filter.dateIssued.head": "Date", + + // "search.filters.filter.dateIssued.max.placeholder": "Minimum Date", + // TODO New key - Add a translation + "search.filters.filter.dateIssued.max.placeholder": "Minimum Date", + + // "search.filters.filter.dateIssued.min.placeholder": "Maximum Date", + // TODO New key - Add a translation + "search.filters.filter.dateIssued.min.placeholder": "Maximum Date", + + // "search.filters.filter.dateSubmitted.head": "Date submitted", + // TODO New key - Add a translation + "search.filters.filter.dateSubmitted.head": "Date submitted", + + // "search.filters.filter.dateSubmitted.placeholder": "Date submitted", + // TODO New key - Add a translation + "search.filters.filter.dateSubmitted.placeholder": "Date submitted", + + // "search.filters.filter.discoverable.head": "Private", + // TODO New key - Add a translation + "search.filters.filter.discoverable.head": "Private", + + // "search.filters.filter.withdrawn.head": "Withdrawn", + // TODO New key - Add a translation + "search.filters.filter.withdrawn.head": "Withdrawn", + + // "search.filters.filter.entityType.head": "Item Type", + // TODO New key - Add a translation + "search.filters.filter.entityType.head": "Item Type", + + // "search.filters.filter.entityType.placeholder": "Item Type", + // TODO New key - Add a translation + "search.filters.filter.entityType.placeholder": "Item Type", + + // "search.filters.filter.has_content_in_original_bundle.head": "Has files", + // TODO New key - Add a translation + "search.filters.filter.has_content_in_original_bundle.head": "Has files", + + // "search.filters.filter.itemtype.head": "Type", + // TODO New key - Add a translation + "search.filters.filter.itemtype.head": "Type", + + // "search.filters.filter.itemtype.placeholder": "Type", + // TODO New key - Add a translation + "search.filters.filter.itemtype.placeholder": "Type", + + // "search.filters.filter.jobTitle.head": "Job Title", + // TODO New key - Add a translation + "search.filters.filter.jobTitle.head": "Job Title", + + // "search.filters.filter.jobTitle.placeholder": "Job Title", + // TODO New key - Add a translation + "search.filters.filter.jobTitle.placeholder": "Job Title", + + // "search.filters.filter.knowsLanguage.head": "Known language", + // TODO New key - Add a translation + "search.filters.filter.knowsLanguage.head": "Known language", + + // "search.filters.filter.knowsLanguage.placeholder": "Known language", + // TODO New key - Add a translation + "search.filters.filter.knowsLanguage.placeholder": "Known language", + + // "search.filters.filter.namedresourcetype.head": "Status", + // TODO New key - Add a translation + "search.filters.filter.namedresourcetype.head": "Status", + + // "search.filters.filter.namedresourcetype.placeholder": "Status", + // TODO New key - Add a translation + "search.filters.filter.namedresourcetype.placeholder": "Status", + + // "search.filters.filter.objectpeople.head": "People", + // TODO New key - Add a translation + "search.filters.filter.objectpeople.head": "People", + + // "search.filters.filter.objectpeople.placeholder": "People", + // TODO New key - Add a translation + "search.filters.filter.objectpeople.placeholder": "People", + + // "search.filters.filter.organizationAddressCountry.head": "Country", + // TODO New key - Add a translation + "search.filters.filter.organizationAddressCountry.head": "Country", + + // "search.filters.filter.organizationAddressCountry.placeholder": "Country", + // TODO New key - Add a translation + "search.filters.filter.organizationAddressCountry.placeholder": "Country", + + // "search.filters.filter.organizationAddressLocality.head": "City", + // TODO New key - Add a translation + "search.filters.filter.organizationAddressLocality.head": "City", + + // "search.filters.filter.organizationAddressLocality.placeholder": "City", + // TODO New key - Add a translation + "search.filters.filter.organizationAddressLocality.placeholder": "City", + + // "search.filters.filter.organizationFoundingDate.head": "Date Founded", + // TODO New key - Add a translation + "search.filters.filter.organizationFoundingDate.head": "Date Founded", + + // "search.filters.filter.organizationFoundingDate.placeholder": "Date Founded", + // TODO New key - Add a translation + "search.filters.filter.organizationFoundingDate.placeholder": "Date Founded", + + // "search.filters.filter.scope.head": "Scope", + // TODO New key - Add a translation + "search.filters.filter.scope.head": "Scope", + + // "search.filters.filter.scope.placeholder": "Scope filter", + // TODO New key - Add a translation + "search.filters.filter.scope.placeholder": "Scope filter", + + // "search.filters.filter.show-less": "Collapse", + // TODO New key - Add a translation + "search.filters.filter.show-less": "Collapse", + + // "search.filters.filter.show-more": "Show more", + // TODO New key - Add a translation + "search.filters.filter.show-more": "Show more", + + // "search.filters.filter.subject.head": "Subject", + // TODO New key - Add a translation + "search.filters.filter.subject.head": "Subject", + + // "search.filters.filter.subject.placeholder": "Subject", + // TODO New key - Add a translation + "search.filters.filter.subject.placeholder": "Subject", + + // "search.filters.filter.submitter.head": "Submitter", + // TODO New key - Add a translation + "search.filters.filter.submitter.head": "Submitter", + + // "search.filters.filter.submitter.placeholder": "Submitter", + // TODO New key - Add a translation + "search.filters.filter.submitter.placeholder": "Submitter", + + + + // "search.filters.entityType.JournalIssue": "Journal Issue", + // TODO New key - Add a translation + "search.filters.entityType.JournalIssue": "Journal Issue", + + // "search.filters.entityType.JournalVolume": "Journal Volume", + // TODO New key - Add a translation + "search.filters.entityType.JournalVolume": "Journal Volume", + + // "search.filters.entityType.OrgUnit": "Organizational Unit", + // TODO New key - Add a translation + "search.filters.entityType.OrgUnit": "Organizational Unit", + + // "search.filters.has_content_in_original_bundle.true": "Yes", + // TODO New key - Add a translation + "search.filters.has_content_in_original_bundle.true": "Yes", + + // "search.filters.has_content_in_original_bundle.false": "No", + // TODO New key - Add a translation + "search.filters.has_content_in_original_bundle.false": "No", + + // "search.filters.discoverable.true": "No", + // TODO New key - Add a translation + "search.filters.discoverable.true": "No", + + // "search.filters.discoverable.false": "Yes", + // TODO New key - Add a translation + "search.filters.discoverable.false": "Yes", + + // "search.filters.withdrawn.true": "Yes", + // TODO New key - Add a translation + "search.filters.withdrawn.true": "Yes", + + // "search.filters.withdrawn.false": "No", + // TODO New key - Add a translation + "search.filters.withdrawn.false": "No", + + + // "search.filters.head": "Filters", + // TODO New key - Add a translation + "search.filters.head": "Filters", + + // "search.filters.reset": "Reset filters", + // TODO New key - Add a translation + "search.filters.reset": "Reset filters", + + + + // "search.form.search": "Search", + // TODO New key - Add a translation + "search.form.search": "Search", + + // "search.form.search_dspace": "Search DSpace", + // TODO New key - Add a translation + "search.form.search_dspace": "Search DSpace", + + // "search.form.search_mydspace": "Search MyDSpace", + // TODO New key - Add a translation + "search.form.search_mydspace": "Search MyDSpace", + + + + // "search.results.head": "Search Results", + // TODO New key - Add a translation + "search.results.head": "Search Results", + + // "search.results.no-results": "Your search returned no results. Having trouble finding what you're looking for? Try putting", + // TODO New key - Add a translation + "search.results.no-results": "Your search returned no results. Having trouble finding what you're looking for? Try putting", + + // "search.results.no-results-link": "quotes around it", + // TODO New key - Add a translation + "search.results.no-results-link": "quotes around it", + + // "search.results.empty": "Your search returned no results.", + // TODO New key - Add a translation + "search.results.empty": "Your search returned no results.", + + + + // "search.sidebar.close": "Back to results", + // TODO New key - Add a translation + "search.sidebar.close": "Back to results", + + // "search.sidebar.filters.title": "Filters", + // TODO New key - Add a translation + "search.sidebar.filters.title": "Filters", + + // "search.sidebar.open": "Search Tools", + // TODO New key - Add a translation + "search.sidebar.open": "Search Tools", + + // "search.sidebar.results": "results", + // TODO New key - Add a translation + "search.sidebar.results": "results", + + // "search.sidebar.settings.rpp": "Results per page", + // TODO New key - Add a translation + "search.sidebar.settings.rpp": "Results per page", + + // "search.sidebar.settings.sort-by": "Sort By", + // TODO New key - Add a translation + "search.sidebar.settings.sort-by": "Sort By", + + // "search.sidebar.settings.title": "Settings", + // TODO New key - Add a translation + "search.sidebar.settings.title": "Settings", + + + + // "search.view-switch.show-detail": "Show detail", + // TODO New key - Add a translation + "search.view-switch.show-detail": "Show detail", + + // "search.view-switch.show-grid": "Show as grid", + // TODO New key - Add a translation + "search.view-switch.show-grid": "Show as grid", + + // "search.view-switch.show-list": "Show as list", + // TODO New key - Add a translation + "search.view-switch.show-list": "Show as list", + + + + // "sorting.ASC": "Ascending", + // TODO New key - Add a translation + "sorting.ASC": "Ascending", + + // "sorting.DESC": "Descending", + // TODO New key - Add a translation + "sorting.DESC": "Descending", + + // "sorting.dc.title.ASC": "Title Ascending", + // TODO New key - Add a translation + "sorting.dc.title.ASC": "Title Ascending", + + // "sorting.dc.title.DESC": "Title Descending", + // TODO New key - Add a translation + "sorting.dc.title.DESC": "Title Descending", + + // "sorting.score.DESC": "Relevance", + // TODO New key - Add a translation + "sorting.score.DESC": "Relevance", + + + + // "statistics.title": "Statistics", + // TODO New key - Add a translation + "statistics.title": "Statistics", + + // "statistics.header": "Statistics for {{ scope }}", + // TODO New key - Add a translation + "statistics.header": "Statistics for {{ scope }}", + + // "statistics.breadcrumbs": "Statistics", + // TODO New key - Add a translation + "statistics.breadcrumbs": "Statistics", + + // "statistics.page.no-data": "No data available", + // TODO New key - Add a translation + "statistics.page.no-data": "No data available", + + // "statistics.table.no-data": "No data available", + // TODO New key - Add a translation + "statistics.table.no-data": "No data available", + + // "statistics.table.title.TotalVisits": "Total visits", + // TODO New key - Add a translation + "statistics.table.title.TotalVisits": "Total visits", + + // "statistics.table.title.TotalVisitsPerMonth": "Total visits per month", + // TODO New key - Add a translation + "statistics.table.title.TotalVisitsPerMonth": "Total visits per month", + + // "statistics.table.title.TotalDownloads": "File Visits", + // TODO New key - Add a translation + "statistics.table.title.TotalDownloads": "File Visits", + + // "statistics.table.title.TopCountries": "Top country views", + // TODO New key - Add a translation + "statistics.table.title.TopCountries": "Top country views", + + // "statistics.table.title.TopCities": "Top city views", + // TODO New key - Add a translation + "statistics.table.title.TopCities": "Top city views", + + // "statistics.table.header.views": "Views", + // TODO New key - Add a translation + "statistics.table.header.views": "Views", + + + + // "submission.edit.title": "Edit Submission", + // TODO New key - Add a translation + "submission.edit.title": "Edit Submission", + + // "submission.general.cannot_submit": "You have not the privilege to make a new submission.", + // TODO New key - Add a translation + "submission.general.cannot_submit": "You have not the privilege to make a new submission.", + + // "submission.general.deposit": "Deposit", + // TODO New key - Add a translation + "submission.general.deposit": "Deposit", + + // "submission.general.discard.confirm.cancel": "Cancel", + // TODO New key - Add a translation + "submission.general.discard.confirm.cancel": "Cancel", + + // "submission.general.discard.confirm.info": "This operation can't be undone. Are you sure?", + // TODO New key - Add a translation + "submission.general.discard.confirm.info": "This operation can't be undone. Are you sure?", + + // "submission.general.discard.confirm.submit": "Yes, I'm sure", + // TODO New key - Add a translation + "submission.general.discard.confirm.submit": "Yes, I'm sure", + + // "submission.general.discard.confirm.title": "Discard submission", + // TODO New key - Add a translation + "submission.general.discard.confirm.title": "Discard submission", + + // "submission.general.discard.submit": "Discard", + // TODO New key - Add a translation + "submission.general.discard.submit": "Discard", + + // "submission.general.save": "Save", + // TODO New key - Add a translation + "submission.general.save": "Save", + + // "submission.general.save-later": "Save for later", + // TODO New key - Add a translation + "submission.general.save-later": "Save for later", + + + // "submission.import-external.page.title": "Import metadata from an external source", + // TODO New key - Add a translation + "submission.import-external.page.title": "Import metadata from an external source", + + // "submission.import-external.title": "Import metadata from an external source", + // TODO New key - Add a translation + "submission.import-external.title": "Import metadata from an external source", + + // "submission.import-external.page.hint": "Enter a query above to find items from the web to import in to DSpace.", + // TODO New key - Add a translation + "submission.import-external.page.hint": "Enter a query above to find items from the web to import in to DSpace.", + + // "submission.import-external.back-to-my-dspace": "Back to MyDSpace", + // TODO New key - Add a translation + "submission.import-external.back-to-my-dspace": "Back to MyDSpace", + + // "submission.import-external.search.placeholder": "Search the external source", + // TODO New key - Add a translation + "submission.import-external.search.placeholder": "Search the external source", + + // "submission.import-external.search.button": "Search", + // TODO New key - Add a translation + "submission.import-external.search.button": "Search", + + // "submission.import-external.search.button.hint": "Write some words to search", + // TODO New key - Add a translation + "submission.import-external.search.button.hint": "Write some words to search", + + // "submission.import-external.search.source.hint": "Pick an external source", + // TODO New key - Add a translation + "submission.import-external.search.source.hint": "Pick an external source", + + // "submission.import-external.source.arxiv": "arXiv", + // TODO New key - Add a translation + "submission.import-external.source.arxiv": "arXiv", + + // "submission.import-external.source.loading": "Loading ...", + // TODO New key - Add a translation + "submission.import-external.source.loading": "Loading ...", + + // "submission.import-external.source.sherpaJournal": "SHERPA Journals", + // TODO New key - Add a translation + "submission.import-external.source.sherpaJournal": "SHERPA Journals", + + // "submission.import-external.source.sherpaPublisher": "SHERPA Publishers", + // TODO New key - Add a translation + "submission.import-external.source.sherpaPublisher": "SHERPA Publishers", + + // "submission.import-external.source.orcid": "ORCID", + // TODO New key - Add a translation + "submission.import-external.source.orcid": "ORCID", + + // "submission.import-external.source.pubmed": "Pubmed", + // TODO New key - Add a translation + "submission.import-external.source.pubmed": "Pubmed", + + // "submission.import-external.source.lcname": "Library of Congress Names", + // TODO New key - Add a translation + "submission.import-external.source.lcname": "Library of Congress Names", + + // "submission.import-external.preview.title": "Item Preview", + // TODO New key - Add a translation + "submission.import-external.preview.title": "Item Preview", + + // "submission.import-external.preview.subtitle": "The metadata below was imported from an external source. It will be pre-filled when you start the submission.", + // TODO New key - Add a translation + "submission.import-external.preview.subtitle": "The metadata below was imported from an external source. It will be pre-filled when you start the submission.", + + // "submission.import-external.preview.button.import": "Start submission", + // TODO New key - Add a translation + "submission.import-external.preview.button.import": "Start submission", + + // "submission.import-external.preview.error.import.title": "Submission error", + // TODO New key - Add a translation + "submission.import-external.preview.error.import.title": "Submission error", + + // "submission.import-external.preview.error.import.body": "An error occurs during the external source entry import process.", + // TODO New key - Add a translation + "submission.import-external.preview.error.import.body": "An error occurs during the external source entry import process.", + + // "submission.sections.describe.relationship-lookup.close": "Close", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.close": "Close", + + // "submission.sections.describe.relationship-lookup.external-source.added": "Successfully added local entry to the selection", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.added": "Successfully added local entry to the selection", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.isAuthorOfPublication": "Import remote author", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-button-title.isAuthorOfPublication": "Import remote author", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal": "Import remote journal", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal": "Import remote journal", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Issue": "Import remote journal issue", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Issue": "Import remote journal issue", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "Import remote journal volume", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "Import remote journal volume", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "Import Remote Author", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "Import Remote Author", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "Successfully added local author to the selection", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "Successfully added local author to the selection", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.new-entity": "Successfully imported and added external author to the selection", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.new-entity": "Successfully imported and added external author to the selection", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "Authority", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "Authority", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.authority.new": "Import as a new local authority entry", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.authority.new": "Import as a new local authority entry", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.cancel": "Cancel", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.cancel": "Cancel", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.collection": "Select a collection to import new entries to", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.collection": "Select a collection to import new entries to", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.entities": "Entities", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.entities": "Entities", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.entities.new": "Import as a new local entity", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.entities.new": "Import as a new local entity", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.lcname": "Importing from LC Name", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.head.lcname": "Importing from LC Name", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.orcid": "Importing from ORCID", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.head.orcid": "Importing from ORCID", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaJournal": "Importing from Sherpa Journal", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaJournal": "Importing from Sherpa Journal", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaPublisher": "Importing from Sherpa Publisher", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaPublisher": "Importing from Sherpa Publisher", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.pubmed": "Importing from PubMed", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.head.pubmed": "Importing from PubMed", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.arxiv": "Importing from arXiv", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.head.arxiv": "Importing from arXiv", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.import": "Import", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.import": "Import", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.title": "Import Remote Journal", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.title": "Import Remote Journal", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.local-entity": "Successfully added local journal to the selection", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.local-entity": "Successfully added local journal to the selection", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.new-entity": "Successfully imported and added external journal to the selection", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.new-entity": "Successfully imported and added external journal to the selection", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.title": "Import Remote Journal Issue", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.title": "Import Remote Journal Issue", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.local-entity": "Successfully added local journal issue to the selection", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.local-entity": "Successfully added local journal issue to the selection", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.new-entity": "Successfully imported and added external journal issue to the selection", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.new-entity": "Successfully imported and added external journal issue to the selection", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.title": "Import Remote Journal Volume", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.title": "Import Remote Journal Volume", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.local-entity": "Successfully added local journal volume to the selection", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.local-entity": "Successfully added local journal volume to the selection", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.new-entity": "Successfully imported and added external journal volume to the selection", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.new-entity": "Successfully imported and added external journal volume to the selection", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.select": "Select a local match:", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.external-source.import-modal.select": "Select a local match:", + + // "submission.sections.describe.relationship-lookup.search-tab.deselect-all": "Deselect all", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.deselect-all": "Deselect all", + + // "submission.sections.describe.relationship-lookup.search-tab.deselect-page": "Deselect page", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.deselect-page": "Deselect page", + + // "submission.sections.describe.relationship-lookup.search-tab.loading": "Loading...", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.loading": "Loading...", + + // "submission.sections.describe.relationship-lookup.search-tab.placeholder": "Search query", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.placeholder": "Search query", + + // "submission.sections.describe.relationship-lookup.search-tab.search": "Go", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.search": "Go", + + // "submission.sections.describe.relationship-lookup.search-tab.select-all": "Select all", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.select-all": "Select all", + + // "submission.sections.describe.relationship-lookup.search-tab.select-page": "Select page", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.select-page": "Select page", + + // "submission.sections.describe.relationship-lookup.selected": "Selected {{ size }} items", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selected": "Selected {{ size }} items", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "Local Authors ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "Local Authors ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalOfPublication": "Local Journals ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalOfPublication": "Local Journals ({{ count }})", + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Project": "Local Projects ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Project": "Local Projects ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Publication": "Local Publications ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Publication": "Local Publications ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "Local Authors ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "Local Authors ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "Local Organizational Units ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "Local Organizational Units ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataPackage": "Local Data Packages ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataPackage": "Local Data Packages ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataFile": "Local Data Files ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataFile": "Local Data Files ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Journal": "Local Journals ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Journal": "Local Journals ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalIssueOfPublication": "Local Journal Issues ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalIssueOfPublication": "Local Journal Issues ({{ count }})", + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalIssue": "Local Journal Issues ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalIssue": "Local Journal Issues ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalVolumeOfPublication": "Local Journal Volumes ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalVolumeOfPublication": "Local Journal Volumes ({{ count }})", + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalVolume": "Local Journal Volumes ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalVolume": "Local Journal Volumes ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaJournal": "Sherpa Journals ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaJournal": "Sherpa Journals ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaPublisher": "Sherpa Publishers ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaPublisher": "Sherpa Publishers ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.orcid": "ORCID ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.orcid": "ORCID ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.lcname": "LC Names ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.lcname": "LC Names ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.pubmed": "PubMed ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.pubmed": "PubMed ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.arxiv": "arXiv ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.arxiv": "arXiv ({{ count }})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfPublication": "Search for Funding Agencies", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfPublication": "Search for Funding Agencies", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingOfPublication": "Search for Funding", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingOfPublication": "Search for Funding", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isChildOrgUnitOf": "Search for Organizational Units", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isChildOrgUnitOf": "Search for Organizational Units", + + // "submission.sections.describe.relationship-lookup.selection-tab.tab-title": "Current Selection ({{ count }})", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.tab-title": "Current Selection ({{ count }})", + + // "submission.sections.describe.relationship-lookup.title.isJournalIssueOfPublication": "Journal Issues", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.isJournalIssueOfPublication": "Journal Issues", + // "submission.sections.describe.relationship-lookup.title.JournalIssue": "Journal Issues", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.JournalIssue": "Journal Issues", + + // "submission.sections.describe.relationship-lookup.title.isJournalVolumeOfPublication": "Journal Volumes", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.isJournalVolumeOfPublication": "Journal Volumes", + // "submission.sections.describe.relationship-lookup.title.JournalVolume": "Journal Volumes", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.JournalVolume": "Journal Volumes", + + // "submission.sections.describe.relationship-lookup.title.isJournalOfPublication": "Journals", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.isJournalOfPublication": "Journals", + + // "submission.sections.describe.relationship-lookup.title.isAuthorOfPublication": "Authors", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.isAuthorOfPublication": "Authors", + + // "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfPublication": "Funding Agency", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfPublication": "Funding Agency", + // "submission.sections.describe.relationship-lookup.title.Project": "Projects", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.Project": "Projects", + + // "submission.sections.describe.relationship-lookup.title.Publication": "Publications", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.Publication": "Publications", + + // "submission.sections.describe.relationship-lookup.title.Person": "Authors", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.Person": "Authors", + + // "submission.sections.describe.relationship-lookup.title.OrgUnit": "Organizational Units", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.OrgUnit": "Organizational Units", + + // "submission.sections.describe.relationship-lookup.title.DataPackage": "Data Packages", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.DataPackage": "Data Packages", + + // "submission.sections.describe.relationship-lookup.title.DataFile": "Data Files", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.DataFile": "Data Files", + + // "submission.sections.describe.relationship-lookup.title.Funding Agency": "Funding Agency", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.Funding Agency": "Funding Agency", + + // "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Funding", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Funding", + + // "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "Parent Organizational Unit", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "Parent Organizational Unit", + + // "submission.sections.describe.relationship-lookup.search-tab.toggle-dropdown": "Toggle dropdown", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.search-tab.toggle-dropdown": "Toggle dropdown", + + // "submission.sections.describe.relationship-lookup.selection-tab.settings": "Settings", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.settings": "Settings", + + // "submission.sections.describe.relationship-lookup.selection-tab.no-selection": "Your selection is currently empty.", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.no-selection": "Your selection is currently empty.", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isAuthorOfPublication": "Selected Authors", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.isAuthorOfPublication": "Selected Authors", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalOfPublication": "Selected Journals", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalOfPublication": "Selected Journals", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalVolumeOfPublication": "Selected Journal Volume", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalVolumeOfPublication": "Selected Journal Volume", + // "submission.sections.describe.relationship-lookup.selection-tab.title.Project": "Selected Projects", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.Project": "Selected Projects", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.Publication": "Selected Publications", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.Publication": "Selected Publications", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.Person": "Selected Authors", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.Person": "Selected Authors", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.OrgUnit": "Selected Organizational Units", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.OrgUnit": "Selected Organizational Units", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.DataPackage": "Selected Data Packages", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.DataPackage": "Selected Data Packages", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.DataFile": "Selected Data Files", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.DataFile": "Selected Data Files", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.Journal": "Selected Journals", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.Journal": "Selected Journals", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalIssueOfPublication": "Selected Issue", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalIssueOfPublication": "Selected Issue", + // "submission.sections.describe.relationship-lookup.selection-tab.title.JournalVolume": "Selected Journal Volume", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.JournalVolume": "Selected Journal Volume", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingAgencyOfPublication": "Selected Funding Agency", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingAgencyOfPublication": "Selected Funding Agency", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingOfPublication": "Selected Funding", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingOfPublication": "Selected Funding", + // "submission.sections.describe.relationship-lookup.selection-tab.title.JournalIssue": "Selected Issue", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.JournalIssue": "Selected Issue", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isChildOrgUnitOf": "Selected Organizational Unit", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.isChildOrgUnitOf": "Selected Organizational Unit", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaJournal": "Search Results", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaJournal": "Search Results", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaPublisher": "Search Results", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaPublisher": "Search Results", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.orcid": "Search Results", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.orcid": "Search Results", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.orcidv2": "Search Results", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.orcidv2": "Search Results", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.lcname": "Search Results", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.lcname": "Search Results", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.pubmed": "Search Results", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.pubmed": "Search Results", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.arxiv": "Search Results", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.selection-tab.title.arxiv": "Search Results", + + // "submission.sections.describe.relationship-lookup.name-variant.notification.content": "Would you like to save \"{{ value }}\" as a name variant for this person so you and others can reuse it for future submissions? If you don\'t you can still use it for this submission.", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.name-variant.notification.content": "Would you like to save \"{{ value }}\" as a name variant for this person so you and others can reuse it for future submissions? If you don\'t you can still use it for this submission.", + + // "submission.sections.describe.relationship-lookup.name-variant.notification.confirm": "Save a new name variant", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.name-variant.notification.confirm": "Save a new name variant", + + // "submission.sections.describe.relationship-lookup.name-variant.notification.decline": "Use only for this submission", + // TODO New key - Add a translation + "submission.sections.describe.relationship-lookup.name-variant.notification.decline": "Use only for this submission", + + // "submission.sections.ccLicense.type": "License Type", + // TODO New key - Add a translation + "submission.sections.ccLicense.type": "License Type", + + // "submission.sections.ccLicense.select": "Select a license type…", + // TODO New key - Add a translation + "submission.sections.ccLicense.select": "Select a license type…", + + // "submission.sections.ccLicense.change": "Change your license type…", + // TODO New key - Add a translation + "submission.sections.ccLicense.change": "Change your license type…", + + // "submission.sections.ccLicense.none": "No licenses available", + // TODO New key - Add a translation + "submission.sections.ccLicense.none": "No licenses available", + + // "submission.sections.ccLicense.option.select": "Select an option…", + // TODO New key - Add a translation + "submission.sections.ccLicense.option.select": "Select an option…", + + // "submission.sections.ccLicense.link": "You’ve selected the following license:", + // TODO New key - Add a translation + "submission.sections.ccLicense.link": "You’ve selected the following license:", + + // "submission.sections.ccLicense.confirmation": "I grant the license above", + // TODO New key - Add a translation + "submission.sections.ccLicense.confirmation": "I grant the license above", + + // "submission.sections.general.add-more": "Add more", + // TODO New key - Add a translation + "submission.sections.general.add-more": "Add more", + + // "submission.sections.general.collection": "Collection", + // TODO New key - Add a translation + "submission.sections.general.collection": "Collection", + + // "submission.sections.general.deposit_error_notice": "There was an issue when submitting the item, please try again later.", + // TODO New key - Add a translation + "submission.sections.general.deposit_error_notice": "There was an issue when submitting the item, please try again later.", + + // "submission.sections.general.deposit_success_notice": "Submission deposited successfully.", + // TODO New key - Add a translation + "submission.sections.general.deposit_success_notice": "Submission deposited successfully.", + + // "submission.sections.general.discard_error_notice": "There was an issue when discarding the item, please try again later.", + // TODO New key - Add a translation + "submission.sections.general.discard_error_notice": "There was an issue when discarding the item, please try again later.", + + // "submission.sections.general.discard_success_notice": "Submission discarded successfully.", + // TODO New key - Add a translation + "submission.sections.general.discard_success_notice": "Submission discarded successfully.", + + // "submission.sections.general.metadata-extracted": "New metadata have been extracted and added to the {{sectionId}} section.", + // TODO New key - Add a translation + "submission.sections.general.metadata-extracted": "New metadata have been extracted and added to the {{sectionId}} section.", + + // "submission.sections.general.metadata-extracted-new-section": "New {{sectionId}} section has been added to submission.", + // TODO New key - Add a translation + "submission.sections.general.metadata-extracted-new-section": "New {{sectionId}} section has been added to submission.", + + // "submission.sections.general.no-collection": "No collection found", + // TODO New key - Add a translation + "submission.sections.general.no-collection": "No collection found", + + // "submission.sections.general.no-sections": "No options available", + // TODO New key - Add a translation + "submission.sections.general.no-sections": "No options available", + + // "submission.sections.general.save_error_notice": "There was an issue when saving the item, please try again later.", + // TODO New key - Add a translation + "submission.sections.general.save_error_notice": "There was an issue when saving the item, please try again later.", + + // "submission.sections.general.save_success_notice": "Submission saved successfully.", + // TODO New key - Add a translation + "submission.sections.general.save_success_notice": "Submission saved successfully.", + + // "submission.sections.general.search-collection": "Search for a collection", + // TODO New key - Add a translation + "submission.sections.general.search-collection": "Search for a collection", + + // "submission.sections.general.sections_not_valid": "There are incomplete sections.", + // TODO New key - Add a translation + "submission.sections.general.sections_not_valid": "There are incomplete sections.", + + + + // "submission.sections.submit.progressbar.CClicense": "Creative commons license", + // TODO New key - Add a translation + "submission.sections.submit.progressbar.CClicense": "Creative commons license", + + // "submission.sections.submit.progressbar.describe.recycle": "Recycle", + // TODO New key - Add a translation + "submission.sections.submit.progressbar.describe.recycle": "Recycle", + + // "submission.sections.submit.progressbar.describe.stepcustom": "Describe", + // TODO New key - Add a translation + "submission.sections.submit.progressbar.describe.stepcustom": "Describe", + + // "submission.sections.submit.progressbar.describe.stepone": "Describe", + // TODO New key - Add a translation + "submission.sections.submit.progressbar.describe.stepone": "Describe", + + // "submission.sections.submit.progressbar.describe.steptwo": "Describe", + // TODO New key - Add a translation + "submission.sections.submit.progressbar.describe.steptwo": "Describe", + + // "submission.sections.submit.progressbar.detect-duplicate": "Potential duplicates", + // TODO New key - Add a translation + "submission.sections.submit.progressbar.detect-duplicate": "Potential duplicates", + + // "submission.sections.submit.progressbar.license": "Deposit license", + // TODO New key - Add a translation + "submission.sections.submit.progressbar.license": "Deposit license", + + // "submission.sections.submit.progressbar.upload": "Upload files", + // TODO New key - Add a translation + "submission.sections.submit.progressbar.upload": "Upload files", + + + + // "submission.sections.upload.delete.confirm.cancel": "Cancel", + // TODO New key - Add a translation + "submission.sections.upload.delete.confirm.cancel": "Cancel", + + // "submission.sections.upload.delete.confirm.info": "This operation can't be undone. Are you sure?", + // TODO New key - Add a translation + "submission.sections.upload.delete.confirm.info": "This operation can't be undone. Are you sure?", + + // "submission.sections.upload.delete.confirm.submit": "Yes, I'm sure", + // TODO New key - Add a translation + "submission.sections.upload.delete.confirm.submit": "Yes, I'm sure", + + // "submission.sections.upload.delete.confirm.title": "Delete bitstream", + // TODO New key - Add a translation + "submission.sections.upload.delete.confirm.title": "Delete bitstream", + + // "submission.sections.upload.delete.submit": "Delete", + // TODO New key - Add a translation + "submission.sections.upload.delete.submit": "Delete", + + // "submission.sections.upload.drop-message": "Drop files to attach them to the item", + // TODO New key - Add a translation + "submission.sections.upload.drop-message": "Drop files to attach them to the item", + + // "submission.sections.upload.form.access-condition-label": "Access condition type", + // TODO New key - Add a translation + "submission.sections.upload.form.access-condition-label": "Access condition type", + + // "submission.sections.upload.form.date-required": "Date is required.", + // TODO New key - Add a translation + "submission.sections.upload.form.date-required": "Date is required.", + + // "submission.sections.upload.form.from-label": "Grant access from", + // TODO New key - Add a translation + "submission.sections.upload.form.from-label": "Grant access from", + + // "submission.sections.upload.form.from-placeholder": "From", + // TODO New key - Add a translation + "submission.sections.upload.form.from-placeholder": "From", + + // "submission.sections.upload.form.group-label": "Group", + // TODO New key - Add a translation + "submission.sections.upload.form.group-label": "Group", + + // "submission.sections.upload.form.group-required": "Group is required.", + // TODO New key - Add a translation + "submission.sections.upload.form.group-required": "Group is required.", + + // "submission.sections.upload.form.until-label": "Grant access until", + // TODO New key - Add a translation + "submission.sections.upload.form.until-label": "Grant access until", + + // "submission.sections.upload.form.until-placeholder": "Until", + // TODO New key - Add a translation + "submission.sections.upload.form.until-placeholder": "Until", + + // "submission.sections.upload.header.policy.default.nolist": "Uploaded files in the {{collectionName}} collection will be accessible according to the following group(s):", + // TODO New key - Add a translation + "submission.sections.upload.header.policy.default.nolist": "Uploaded files in the {{collectionName}} collection will be accessible according to the following group(s):", + + // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", + // TODO New key - Add a translation + "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", + + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // TODO New key - Add a translation + "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + + // "submission.sections.upload.no-entry": "No", + // TODO New key - Add a translation + "submission.sections.upload.no-entry": "No", + + // "submission.sections.upload.no-file-uploaded": "No file uploaded yet.", + // TODO New key - Add a translation + "submission.sections.upload.no-file-uploaded": "No file uploaded yet.", + + // "submission.sections.upload.save-metadata": "Save metadata", + // TODO New key - Add a translation + "submission.sections.upload.save-metadata": "Save metadata", + + // "submission.sections.upload.undo": "Cancel", + // TODO New key - Add a translation + "submission.sections.upload.undo": "Cancel", + + // "submission.sections.upload.upload-failed": "Upload failed", + // TODO New key - Add a translation + "submission.sections.upload.upload-failed": "Upload failed", + + // "submission.sections.upload.upload-successful": "Upload successful", + // TODO New key - Add a translation + "submission.sections.upload.upload-successful": "Upload successful", + + + + // "submission.submit.title": "Submission", + // TODO New key - Add a translation + "submission.submit.title": "Submission", + + + + // "submission.workflow.generic.delete": "Delete", + "submission.workflow.generic.delete": "Өшіру", + + // "submission.workflow.generic.delete-help": "If you would to discard this item, select \"Delete\". You will then be asked to confirm it.", + // TODO New key - Add a translation + "submission.workflow.generic.delete-help": "If you would to discard this item, select \"Delete\". You will then be asked to confirm it.", + + // "submission.workflow.generic.edit": "Edit", + // TODO New key - Add a translation + "submission.workflow.generic.edit": "Edit", + + // "submission.workflow.generic.edit-help": "Select this option to change the item's metadata.", + // TODO New key - Add a translation + "submission.workflow.generic.edit-help": "Select this option to change the item's metadata.", + + // "submission.workflow.generic.view": "View", + // TODO New key - Add a translation + "submission.workflow.generic.view": "View", + + // "submission.workflow.generic.view-help": "Select this option to view the item's metadata.", + // TODO New key - Add a translation + "submission.workflow.generic.view-help": "Select this option to view the item's metadata.", + + + + // "submission.workflow.tasks.claimed.approve": "Approve", + // TODO New key - Add a translation + "submission.workflow.tasks.claimed.approve": "Approve", + + // "submission.workflow.tasks.claimed.approve_help": "If you have reviewed the item and it is suitable for inclusion in the collection, select \"Approve\".", + // TODO New key - Add a translation + "submission.workflow.tasks.claimed.approve_help": "If you have reviewed the item and it is suitable for inclusion in the collection, select \"Approve\".", + + // "submission.workflow.tasks.claimed.edit": "Edit", + // TODO New key - Add a translation + "submission.workflow.tasks.claimed.edit": "Edit", + + // "submission.workflow.tasks.claimed.edit_help": "Select this option to change the item's metadata.", + // TODO New key - Add a translation + "submission.workflow.tasks.claimed.edit_help": "Select this option to change the item's metadata.", + + // "submission.workflow.tasks.claimed.reject.reason.info": "Please enter your reason for rejecting the submission into the box below, indicating whether the submitter may fix a problem and resubmit.", + // TODO New key - Add a translation + "submission.workflow.tasks.claimed.reject.reason.info": "Please enter your reason for rejecting the submission into the box below, indicating whether the submitter may fix a problem and resubmit.", + + // "submission.workflow.tasks.claimed.reject.reason.placeholder": "Describe the reason of reject", + // TODO New key - Add a translation + "submission.workflow.tasks.claimed.reject.reason.placeholder": "Describe the reason of reject", + + // "submission.workflow.tasks.claimed.reject.reason.submit": "Reject item", + // TODO New key - Add a translation + "submission.workflow.tasks.claimed.reject.reason.submit": "Reject item", + + // "submission.workflow.tasks.claimed.reject.reason.title": "Reason", + // TODO New key - Add a translation + "submission.workflow.tasks.claimed.reject.reason.title": "Reason", + + // "submission.workflow.tasks.claimed.reject.submit": "Reject", + // TODO New key - Add a translation + "submission.workflow.tasks.claimed.reject.submit": "Reject", + + // "submission.workflow.tasks.claimed.reject_help": "If you have reviewed the item and found it is not suitable for inclusion in the collection, select \"Reject\". You will then be asked to enter a message indicating why the item is unsuitable, and whether the submitter should change something and resubmit.", + // TODO New key - Add a translation + "submission.workflow.tasks.claimed.reject_help": "If you have reviewed the item and found it is not suitable for inclusion in the collection, select \"Reject\". You will then be asked to enter a message indicating why the item is unsuitable, and whether the submitter should change something and resubmit.", + + // "submission.workflow.tasks.claimed.return": "Return to pool", + // TODO New key - Add a translation + "submission.workflow.tasks.claimed.return": "Return to pool", + + // "submission.workflow.tasks.claimed.return_help": "Return the task to the pool so that another user may perform the task.", + // TODO New key - Add a translation + "submission.workflow.tasks.claimed.return_help": "Return the task to the pool so that another user may perform the task.", + + + + // "submission.workflow.tasks.generic.error": "Error occurred during operation...", + // TODO New key - Add a translation + "submission.workflow.tasks.generic.error": "Error occurred during operation...", + + // "submission.workflow.tasks.generic.processing": "Processing...", + // TODO New key - Add a translation + "submission.workflow.tasks.generic.processing": "Processing...", + + // "submission.workflow.tasks.generic.submitter": "Submitter", + // TODO New key - Add a translation + "submission.workflow.tasks.generic.submitter": "Submitter", + + // "submission.workflow.tasks.generic.success": "Operation successful", + // TODO New key - Add a translation + "submission.workflow.tasks.generic.success": "Operation successful", + + + + // "submission.workflow.tasks.pool.claim": "Claim", + // TODO New key - Add a translation + "submission.workflow.tasks.pool.claim": "Claim", + + // "submission.workflow.tasks.pool.claim_help": "Assign this task to yourself.", + // TODO New key - Add a translation + "submission.workflow.tasks.pool.claim_help": "Assign this task to yourself.", + + // "submission.workflow.tasks.pool.hide-detail": "Hide detail", + // TODO New key - Add a translation + "submission.workflow.tasks.pool.hide-detail": "Hide detail", + + // "submission.workflow.tasks.pool.show-detail": "Show detail", + // TODO New key - Add a translation + "submission.workflow.tasks.pool.show-detail": "Show detail", + + + + // "title": "DSpace", + // TODO New key - Add a translation + "title": "DSpace", + + + + // "vocabulary-treeview.header": "Hierarchical tree view", + // TODO New key - Add a translation + "vocabulary-treeview.header": "Hierarchical tree view", + + // "vocabulary-treeview.load-more": "Load more", + // TODO New key - Add a translation + "vocabulary-treeview.load-more": "Load more", + + // "vocabulary-treeview.search.form.reset": "Reset", + // TODO New key - Add a translation + "vocabulary-treeview.search.form.reset": "Reset", + + // "vocabulary-treeview.search.form.search": "Search", + // TODO New key - Add a translation + "vocabulary-treeview.search.form.search": "Search", + + // "vocabulary-treeview.search.no-result": "There were no items to show", + // TODO New key - Add a translation + "vocabulary-treeview.search.no-result": "There were no items to show", + + // "vocabulary-treeview.tree.description.nsi": "The Norwegian Science Index", + // TODO New key - Add a translation + "vocabulary-treeview.tree.description.nsi": "The Norwegian Science Index", + + // "vocabulary-treeview.tree.description.srsc": "Research Subject Categories", + // TODO New key - Add a translation + "vocabulary-treeview.tree.description.srsc": "Research Subject Categories", + + + + // "uploader.browse": "browse", + // TODO New key - Add a translation + "uploader.browse": "browse", + + // "uploader.drag-message": "Drag & Drop your files here", + // TODO New key - Add a translation + "uploader.drag-message": "Drag & Drop your files here", + + // "uploader.or": ", or ", + // TODO New key - Add a translation + "uploader.or": ", or ", + + // "uploader.processing": "Processing", + // TODO New key - Add a translation + "uploader.processing": "Processing", + + // "uploader.queue-length": "Queue length", + // TODO New key - Add a translation + "uploader.queue-length": "Queue length", + + // "virtual-metadata.delete-item.info": "Select the types for which you want to save the virtual metadata as real metadata", + // TODO New key - Add a translation + "virtual-metadata.delete-item.info": "Select the types for which you want to save the virtual metadata as real metadata", + + // "virtual-metadata.delete-item.modal-head": "The virtual metadata of this relation", + // TODO New key - Add a translation + "virtual-metadata.delete-item.modal-head": "The virtual metadata of this relation", + + // "virtual-metadata.delete-relationship.modal-head": "Select the items for which you want to save the virtual metadata as real metadata", + // TODO New key - Add a translation + "virtual-metadata.delete-relationship.modal-head": "Select the items for which you want to save the virtual metadata as real metadata", + + + + // "workflowAdmin.search.results.head": "Administer Workflow", + // TODO New key - Add a translation + "workflowAdmin.search.results.head": "Administer Workflow", + + + + // "workflow-item.delete.notification.success.title": "Deleted", + // TODO New key - Add a translation + "workflow-item.delete.notification.success.title": "Deleted", + + // "workflow-item.delete.notification.success.content": "This workflow item was successfully deleted", + // TODO New key - Add a translation + "workflow-item.delete.notification.success.content": "This workflow item was successfully deleted", + + // "workflow-item.delete.notification.error.title": "Something went wrong", + // TODO New key - Add a translation + "workflow-item.delete.notification.error.title": "Something went wrong", + + // "workflow-item.delete.notification.error.content": "The workflow item could not be deleted", + // TODO New key - Add a translation + "workflow-item.delete.notification.error.content": "The workflow item could not be deleted", + + // "workflow-item.delete.title": "Delete workflow item", + // TODO New key - Add a translation + "workflow-item.delete.title": "Delete workflow item", + + // "workflow-item.delete.header": "Delete workflow item", + // TODO New key - Add a translation + "workflow-item.delete.header": "Delete workflow item", + + // "workflow-item.delete.button.cancel": "Cancel", + // TODO New key - Add a translation + "workflow-item.delete.button.cancel": "Cancel", + + // "workflow-item.delete.button.confirm": "Delete", + // TODO New key - Add a translation + "workflow-item.delete.button.confirm": "Delete", + + + // "workflow-item.send-back.notification.success.title": "Sent back to submitter", + // TODO New key - Add a translation + "workflow-item.send-back.notification.success.title": "Sent back to submitter", + + // "workflow-item.send-back.notification.success.content": "This workflow item was successfully sent back to the submitter", + // TODO New key - Add a translation + "workflow-item.send-back.notification.success.content": "This workflow item was successfully sent back to the submitter", + + // "workflow-item.send-back.notification.error.title": "Something went wrong", + // TODO New key - Add a translation + "workflow-item.send-back.notification.error.title": "Something went wrong", + + // "workflow-item.send-back.notification.error.content": "The workflow item could not be sent back to the submitter", + // TODO New key - Add a translation + "workflow-item.send-back.notification.error.content": "The workflow item could not be sent back to the submitter", + + // "workflow-item.send-back.title": "Send workflow item back to submitter", + // TODO New key - Add a translation + "workflow-item.send-back.title": "Send workflow item back to submitter", + + // "workflow-item.send-back.header": "Send workflow item back to submitter", + // TODO New key - Add a translation + "workflow-item.send-back.header": "Send workflow item back to submitter", + + // "workflow-item.send-back.button.cancel": "Cancel", + "workflow-item.send-back.button.cancel": "Алып тастау", + + // "workflow-item.send-back.button.confirm": "Send back" + // TODO New key - Add a translation + "workflow-item.send-back.button.confirm": "Send back" + + +} From 14b1fd463dd6930586d0fc5f5dad321afe0c8f49 Mon Sep 17 00:00:00 2001 From: Yura Date: Wed, 20 Oct 2021 11:27:55 +0200 Subject: [PATCH 0002/2129] 84367: SearchForm/SearchComponent: add option to hide scope selection dropdown --- .../search-page/configuration-search-page.component.ts | 6 ++++++ src/app/search-page/search.component.html | 1 + src/app/search-page/search.component.ts | 5 +++++ src/app/shared/search-form/search-form.component.html | 4 ++-- .../shared/search-form/search-form.component.spec.ts | 10 ++++++++++ src/app/shared/search-form/search-form.component.ts | 5 +++++ 6 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/app/search-page/configuration-search-page.component.ts b/src/app/search-page/configuration-search-page.component.ts index 1eefeeb569c..5ba318b8504 100644 --- a/src/app/search-page/configuration-search-page.component.ts +++ b/src/app/search-page/configuration-search-page.component.ts @@ -47,6 +47,12 @@ export class ConfigurationSearchPageComponent extends SearchComponent implements */ @Input() fixedFilterQuery: string; + + /** + * Whether to show the scope selection dropdown + */ + @Input() scopeSelectable = true; + constructor(protected service: SearchService, protected sidebarService: SidebarService, protected windowService: HostWindowService, diff --git a/src/app/search-page/search.component.html b/src/app/search-page/search.component.html index d8aa25e4a3c..499f6522004 100644 --- a/src/app/search-page/search.component.html +++ b/src/app/search-page/search.component.html @@ -45,6 +45,7 @@ -
+
-
+
diff --git a/src/app/shared/search-form/search-form.component.spec.ts b/src/app/shared/search-form/search-form.component.spec.ts index 1469eac5663..bbaee5709d7 100644 --- a/src/app/shared/search-form/search-form.component.spec.ts +++ b/src/app/shared/search-form/search-form.component.spec.ts @@ -72,6 +72,16 @@ describe('SearchFormComponent', () => { expect(select).toBeNull(); }); + it('should not display scopes when scopeSelectable is false', () => { + comp.scopeSelectable = false; + comp.scopes = objects; + comp.scope = objects[1].id; + + fixture.detectChanges(); + const select = de.query(By.css('select')); + expect(select).toBeNull(); + }); + it('should display set query value in input field', fakeAsync(() => { const testString = 'This is a test query'; comp.query = testString; diff --git a/src/app/shared/search-form/search-form.component.ts b/src/app/shared/search-form/search-form.component.ts index 2791aee378f..1cf3c119131 100644 --- a/src/app/shared/search-form/search-form.component.ts +++ b/src/app/shared/search-form/search-form.component.ts @@ -66,6 +66,11 @@ export class SearchFormComponent { */ @Output() submitSearch = new EventEmitter(); + /** + * Whether to show the scope selection dropdown + */ + @Input() scopeSelectable = true; + constructor(private router: Router, private searchService: SearchService, private paginationService: PaginationService, private searchConfig: SearchConfigurationService From 931560ee2627c2b7d130ea22006251e53adf1224 Mon Sep 17 00:00:00 2001 From: Yura Date: Thu, 21 Oct 2021 10:22:23 +0200 Subject: [PATCH 0003/2129] 84367: Make ComcolPageBrowseByComponent themeable --- .../browse-by-metadata-page.component.html | 2 +- .../collection-page.component.html | 4 +-- .../community-page.component.html | 4 +-- .../themed-comcol-page-browse-by.component.ts | 33 +++++++++++++++++++ src/app/shared/shared.module.ts | 2 ++ 5 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 src/app/shared/comcol-page-browse-by/themed-comcol-page-browse-by.component.ts diff --git a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html index 2321da02041..324a581ae0a 100644 --- a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html +++ b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html @@ -18,7 +18,7 @@ - +
diff --git a/src/app/collection-page/collection-page.component.html b/src/app/collection-page/collection-page.component.html index 9d598a3b697..6eceb696bd2 100644 --- a/src/app/collection-page/collection-page.component.html +++ b/src/app/collection-page/collection-page.component.html @@ -40,10 +40,10 @@
- - +
diff --git a/src/app/community-page/community-page.component.html b/src/app/community-page/community-page.component.html index cf7282eb4bd..27420e95b33 100644 --- a/src/app/community-page/community-page.component.html +++ b/src/app/community-page/community-page.component.html @@ -26,8 +26,8 @@
- - + + diff --git a/src/app/shared/comcol-page-browse-by/themed-comcol-page-browse-by.component.ts b/src/app/shared/comcol-page-browse-by/themed-comcol-page-browse-by.component.ts new file mode 100644 index 00000000000..410c1f53dad --- /dev/null +++ b/src/app/shared/comcol-page-browse-by/themed-comcol-page-browse-by.component.ts @@ -0,0 +1,33 @@ +import { Component, Input } from '@angular/core'; +import { ThemedComponent } from '../theme-support/themed.component'; +import { ComcolPageBrowseByComponent } from './comcol-page-browse-by.component'; + +/** + * Themed wrapper for ComcolPageBrowseByComponent + */ +@Component({ + selector: 'ds-themed-comcol-page-browse-by', + styleUrls: [], + templateUrl: '../theme-support/themed.component.html', +}) +export class ThemedComcolPageBrowseByComponent extends ThemedComponent { + /** + * The ID of the Community or Collection + */ + @Input() id: string; + @Input() contentType: string; + + inAndOutputNames: (keyof ComcolPageBrowseByComponent & keyof this)[] = ['id', 'contentType']; + + protected getComponentName(): string { + return 'ComcolPageBrowseByComponent'; + } + + protected importThemedComponent(themeName: string): Promise { + return import(`../../../themes/${themeName}/app/shared/comcol-page-browse-by/comcol-page-browse-by.component`); + } + + protected importUnthemedComponent(): Promise { + return import('./comcol-page-browse-by.component'); + } +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 9b993e551f6..9d5a0151c4a 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -233,6 +233,7 @@ import { OnClickMenuItemComponent } from './menu/menu-item/onclick-menu-item.com import { TextMenuItemComponent } from './menu/menu-item/text-menu-item.component'; import { ThemedConfigurationSearchPageComponent } from '../search-page/themed-configuration-search-page.component'; import { SearchNavbarComponent } from '../search-navbar/search-navbar.component'; +import { ThemedComcolPageBrowseByComponent } from './comcol-page-browse-by/themed-comcol-page-browse-by.component'; /** * Declaration needed to make sure all decorator functions are called in time @@ -303,6 +304,7 @@ const COMPONENTS = [ EditComColPageComponent, DeleteComColPageComponent, ComcolPageBrowseByComponent, + ThemedComcolPageBrowseByComponent, ComcolRoleComponent, DsDynamicFormComponent, DsDynamicFormControlContainerComponent, From 859ff4a2f5e06c3c73fee0d8654fe4f391e76a4c Mon Sep 17 00:00:00 2001 From: Yura Date: Thu, 21 Oct 2021 10:33:17 +0200 Subject: [PATCH 0004/2129] 84367: Use DSONameService for ds-dso-selector names --- .../authorized-collection-selector.component.ts | 14 +++++++++----- .../dso-selector/dso-selector.component.html | 2 +- .../dso-selector/dso-selector.component.ts | 14 +++++++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/app/shared/dso-selector/dso-selector/authorized-collection-selector/authorized-collection-selector.component.ts b/src/app/shared/dso-selector/dso-selector/authorized-collection-selector/authorized-collection-selector.component.ts index bca17275423..08853307b03 100644 --- a/src/app/shared/dso-selector/dso-selector/authorized-collection-selector/authorized-collection-selector.component.ts +++ b/src/app/shared/dso-selector/dso-selector/authorized-collection-selector/authorized-collection-selector.component.ts @@ -14,6 +14,7 @@ import { RemoteData } from '../../../../core/data/remote-data'; import { hasValue } from '../../../empty.util'; import { NotificationsService } from '../../../notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; +import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; @Component({ selector: 'ds-authorized-collection-selector', @@ -24,11 +25,14 @@ import { TranslateService } from '@ngx-translate/core'; * Component rendering a list of collections to select from */ export class AuthorizedCollectionSelectorComponent extends DSOSelectorComponent { - constructor(protected searchService: SearchService, - protected collectionDataService: CollectionDataService, - protected notifcationsService: NotificationsService, - protected translate: TranslateService) { - super(searchService, notifcationsService, translate); + constructor( + protected searchService: SearchService, + protected collectionDataService: CollectionDataService, + protected notifcationsService: NotificationsService, + protected translate: TranslateService, + protected dsoNameService: DSONameService, + ) { + super(searchService, notifcationsService, translate, dsoNameService); } /** diff --git a/src/app/shared/dso-selector/dso-selector/dso-selector.component.html b/src/app/shared/dso-selector/dso-selector/dso-selector.component.html index ab2ea6cd8b7..a3b460fe90f 100644 --- a/src/app/shared/dso-selector/dso-selector/dso-selector.component.html +++ b/src/app/shared/dso-selector/dso-selector/dso-selector.component.html @@ -22,7 +22,7 @@ \ No newline at end of file diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.scss b/src/app/shared/search/search-export-csv/search-export-csv.component.scss new file mode 100644 index 00000000000..4b0ab3c44ad --- /dev/null +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.scss @@ -0,0 +1,4 @@ +.export-button { + background: var(--ds-admin-sidebar-bg); + border-color: var(--ds-admin-sidebar-bg); +} \ No newline at end of file diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts b/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts new file mode 100644 index 00000000000..f8dc089c6ae --- /dev/null +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts @@ -0,0 +1,179 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { of as observableOf } from 'rxjs'; +import { TranslateModule } from '@ngx-translate/core'; +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { SearchExportCsvComponent } from './search-export-csv.component'; +import { ScriptDataService } from '../../../core/data/processes/script-data.service'; +import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../remote-data.utils'; +import { Script } from '../../../process-page/scripts/script.model'; +import { Process } from '../../../process-page/processes/process.model'; +import { NotificationsServiceStub } from '../../testing/notifications-service.stub'; +import { NotificationsService } from '../../notifications/notifications.service'; +import { Router } from '@angular/router'; +import { By } from '@angular/platform-browser'; +import { PaginatedSearchOptions } from '../paginated-search-options.model'; +import { SearchFilter } from '../search-filter.model'; +import { getProcessDetailRoute } from '../../../process-page/process-page-routing.paths'; + +describe('SearchExportCsvComponent', () => { + let component: SearchExportCsvComponent; + let fixture: ComponentFixture; + + let scriptDataService: ScriptDataService; + let authorizationDataService: AuthorizationDataService; + let notificationsService; + let router; + + const script = Object.assign(new Script(), {id: 'metadata-export-search', name: 'metadata-export-search'}); + const process = Object.assign(new Process(), {processId: 5, scriptName: 'metadata-export-search'}); + + const searchConfig = new PaginatedSearchOptions({ + configuration: 'test-configuration', + scope: 'test-scope', + query: 'test-query', + filters: [ + new SearchFilter('f.filter1', ['filter1value1,equals', 'filter1value2,equals']), + new SearchFilter('f.filter2', ['filter2value1,contains']) + ] + }); + + function initBeforeEachAsync() { + scriptDataService = jasmine.createSpyObj('scriptDataService', { + findById: createSuccessfulRemoteDataObject$(script), + invoke: createSuccessfulRemoteDataObject$(process) + }); + authorizationDataService = jasmine.createSpyObj('authorizationService', { + isAuthorized: observableOf(true) + }); + + notificationsService = new NotificationsServiceStub(); + + router = jasmine.createSpyObj('authorizationService', ['navigateByUrl']); + TestBed.configureTestingModule({ + declarations: [SearchExportCsvComponent], + imports: [TranslateModule.forRoot(), NgbModule], + providers: [ + {provide: ScriptDataService, useValue: scriptDataService}, + {provide: AuthorizationDataService, useValue: authorizationDataService}, + {provide: NotificationsService, useValue: notificationsService}, + {provide: Router, useValue: router}, + ] + }).compileComponents(); + } + + function initBeforeEach() { + fixture = TestBed.createComponent(SearchExportCsvComponent); + component = fixture.componentInstance; + component.searchConfig = searchConfig; + fixture.detectChanges(); + } + + describe('init', () => { + describe('comp', () => { + beforeEach(waitForAsync(() => { + initBeforeEachAsync(); + })); + beforeEach(() => { + initBeforeEach(); + }); + it('should init the comp', () => { + expect(component).toBeTruthy(); + }); + }); + describe('when the user is an admin and the metadata-export-search script is present ', () => { + beforeEach(waitForAsync(() => { + initBeforeEachAsync(); + })); + beforeEach(() => { + initBeforeEach(); + }); + it('should add the button', () => { + const debugElement = fixture.debugElement.query(By.css('button.export-button')); + expect(debugElement).toBeDefined(); + }); + }); + describe('when the user is not an admin', () => { + beforeEach(waitForAsync(() => { + initBeforeEachAsync(); + (authorizationDataService.isAuthorized as jasmine.Spy).and.returnValue(observableOf(false)); + })); + beforeEach(() => { + initBeforeEach(); + }); + it('should not add the button', () => { + const debugElement = fixture.debugElement.query(By.css('button.export-button')); + expect(debugElement).toBeNull(); + }); + }); + describe('when the metadata-export-search script is not present', () => { + beforeEach(waitForAsync(() => { + initBeforeEachAsync(); + (scriptDataService.findById as jasmine.Spy).and.returnValue(createFailedRemoteDataObject$('Not found', 404)); + })); + beforeEach(() => { + initBeforeEach(); + }); + it('should should not add the button', () => { + const debugElement = fixture.debugElement.query(By.css('button.export-button')); + expect(debugElement).toBeNull(); + }); + }); + }); + describe('export', () => { + beforeEach(waitForAsync(() => { + initBeforeEachAsync(); + })); + beforeEach(() => { + initBeforeEach(); + }); + it('should call the invoke script method with the correct parameters', () => { + component.export(); + expect(scriptDataService.invoke).toHaveBeenCalledWith('metadata-export-search', + [ + {name: '-q', value: searchConfig.query}, + {name: '-s', value: searchConfig.scope}, + {name: '-c', value: searchConfig.configuration}, + {name: '-f', value: 'filter1,equals=filter1value1,filter1value2'}, + {name: '-f', value: 'filter2,contains=filter2value1'}, + ], []); + + component.searchConfig = null; + fixture.detectChanges(); + + component.export(); + expect(scriptDataService.invoke).toHaveBeenCalledWith('metadata-export-search', [], []); + + }); + it('should show a success message when the script was invoked successfully and redirect to the corresponding process page', () => { + component.export(); + + expect(notificationsService.success).toHaveBeenCalled(); + expect(router.navigateByUrl).toHaveBeenCalledWith(getProcessDetailRoute(process.processId)); + }); + it('should show an error message when the script was not invoked successfully and stay on the current page', () => { + (scriptDataService.invoke as jasmine.Spy).and.returnValue(createFailedRemoteDataObject$('Error', 500)); + + component.export(); + + expect(notificationsService.error).toHaveBeenCalled(); + expect(router.navigateByUrl).not.toHaveBeenCalled(); + }); + }); + describe('clicking the button', () => { + beforeEach(waitForAsync(() => { + initBeforeEachAsync(); + })); + beforeEach(() => { + initBeforeEach(); + }); + it('should trigger the export function', () => { + spyOn(component, 'export'); + + const debugElement = fixture.debugElement.query(By.css('button.export-button')); + debugElement.triggerEventHandler('click', null); + + expect(component.export).toHaveBeenCalled(); + }); + }); +}); diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.ts b/src/app/shared/search/search-export-csv/search-export-csv.component.ts new file mode 100644 index 00000000000..a1bdf1c7e17 --- /dev/null +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.ts @@ -0,0 +1,102 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { PaginatedSearchOptions } from '../paginated-search-options.model'; +import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; +import { ScriptDataService } from '../../../core/data/processes/script-data.service'; +import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; +import { map, tap } from 'rxjs/operators'; +import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { hasValue, isNotEmpty } from '../../empty.util'; +import { RemoteData } from '../../../core/data/remote-data'; +import { Process } from '../../../process-page/processes/process.model'; +import { getProcessDetailRoute } from '../../../process-page/process-page-routing.paths'; +import { NotificationsService } from '../../notifications/notifications.service'; +import { TranslateService } from '@ngx-translate/core'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'ds-search-export-csv', + styleUrls: ['./search-export-csv.component.scss'], + templateUrl: './search-export-csv.component.html', +}) +/** + * Display a button to export the current search results as csv + */ +export class SearchExportCsvComponent implements OnInit { + + /** + * The current configuration of the search + */ + @Input() searchConfig: PaginatedSearchOptions; + + /** + * Observable used to determine whether the button should be shown + */ + shouldShowButton$: Observable; + + /** + * The message key used for the tooltip of the button + */ + tooltipMsg = 'metadata-export-search.tooltip'; + + constructor(private scriptDataService: ScriptDataService, + private authorizationDataService: AuthorizationDataService, + private notificationsService: NotificationsService, + private translateService: TranslateService, + private router: Router + ) { + } + + ngOnInit(): void { + const scriptExists$ = this.scriptDataService.findById('metadata-export-search').pipe( + getFirstCompletedRemoteData(), + map((rd) => rd.isSuccess && hasValue(rd.payload)) + ); + + const isAuthorized$ = this.authorizationDataService.isAuthorized(FeatureID.AdministratorOf); + + this.shouldShowButton$ = observableCombineLatest([scriptExists$, isAuthorized$]).pipe( + tap((v) => console.log('showbutton', v)), + map(([scriptExists, isAuthorized]: [boolean, boolean]) => scriptExists && isAuthorized) + ); + } + + /** + * Start the export of the items based on the current search configuration + */ + export() { + const parameters = []; + if (hasValue(this.searchConfig)) { + if (isNotEmpty(this.searchConfig.query)) { + parameters.push({name: '-q', value: this.searchConfig.query}); + } + if (isNotEmpty(this.searchConfig.scope)) { + parameters.push({name: '-s', value: this.searchConfig.scope}); + } + if (isNotEmpty(this.searchConfig.configuration)) { + parameters.push({name: '-c', value: this.searchConfig.configuration}); + } + if (isNotEmpty(this.searchConfig.filters)) { + this.searchConfig.filters.forEach((filter) => { + let operator = 'equals'; + if (hasValue(filter.values)) { + operator = filter.values[0].substring(filter.values[0].indexOf(',') + 1); + } + const filterValue = `${filter.key.substring(2)},${operator}=${filter.values.map((v) => v.substring(0, v.indexOf(','))).join()}`; + parameters.push({name: '-f', value: filterValue}); + }); + } + } + + this.scriptDataService.invoke('metadata-export-search', parameters, []).pipe( + getFirstCompletedRemoteData() + ).subscribe((rd: RemoteData) => { + if (rd.hasSucceeded) { + this.notificationsService.success(this.translateService.get('metadata-export-search.submit.success')); + this.router.navigateByUrl(getProcessDetailRoute(rd.payload.processId)); + } else { + this.notificationsService.error(this.translateService.get('metadata-export-search.submit.error')); + } + }); + } +} diff --git a/src/app/shared/search/search-results/search-results.component.html b/src/app/shared/search/search-results/search-results.component.html index 4e6bca094ed..01c63e9c9e3 100644 --- a/src/app/shared/search/search-results/search-results.component.html +++ b/src/app/shared/search/search-results/search-results.component.html @@ -1,4 +1,7 @@ +

{{ (configuration ? configuration + '.search.results.head' : 'search.results.head') | translate }}

+ +
Date: Thu, 9 Dec 2021 15:09:46 +0100 Subject: [PATCH 0018/2129] 85451: Fixed filter syntax --- .../search-export-csv.component.spec.ts | 7 +++++-- .../search-export-csv.component.ts | 20 +++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts b/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts index f8dc089c6ae..cb0d7e62662 100644 --- a/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.spec.ts @@ -34,7 +34,8 @@ describe('SearchExportCsvComponent', () => { query: 'test-query', filters: [ new SearchFilter('f.filter1', ['filter1value1,equals', 'filter1value2,equals']), - new SearchFilter('f.filter2', ['filter2value1,contains']) + new SearchFilter('f.filter2', ['filter2value1,contains']), + new SearchFilter('f.filter3', ['[2000 TO 2001]'], 'equals') ] }); @@ -134,8 +135,10 @@ describe('SearchExportCsvComponent', () => { {name: '-q', value: searchConfig.query}, {name: '-s', value: searchConfig.scope}, {name: '-c', value: searchConfig.configuration}, - {name: '-f', value: 'filter1,equals=filter1value1,filter1value2'}, + {name: '-f', value: 'filter1,equals=filter1value1'}, + {name: '-f', value: 'filter1,equals=filter1value2'}, {name: '-f', value: 'filter2,contains=filter2value1'}, + {name: '-f', value: 'filter3,equals=[2000 TO 2001]'}, ], []); component.searchConfig = null; diff --git a/src/app/shared/search/search-export-csv/search-export-csv.component.ts b/src/app/shared/search/search-export-csv/search-export-csv.component.ts index a1bdf1c7e17..d499097bd35 100644 --- a/src/app/shared/search/search-export-csv/search-export-csv.component.ts +++ b/src/app/shared/search/search-export-csv/search-export-csv.component.ts @@ -3,7 +3,7 @@ import { PaginatedSearchOptions } from '../paginated-search-options.model'; import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; import { ScriptDataService } from '../../../core/data/processes/script-data.service'; import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; -import { map, tap } from 'rxjs/operators'; +import { map } from 'rxjs/operators'; import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; import { hasValue, isNotEmpty } from '../../empty.util'; @@ -56,7 +56,6 @@ export class SearchExportCsvComponent implements OnInit { const isAuthorized$ = this.authorizationDataService.isAuthorized(FeatureID.AdministratorOf); this.shouldShowButton$ = observableCombineLatest([scriptExists$, isAuthorized$]).pipe( - tap((v) => console.log('showbutton', v)), map(([scriptExists, isAuthorized]: [boolean, boolean]) => scriptExists && isAuthorized) ); } @@ -78,12 +77,21 @@ export class SearchExportCsvComponent implements OnInit { } if (isNotEmpty(this.searchConfig.filters)) { this.searchConfig.filters.forEach((filter) => { - let operator = 'equals'; if (hasValue(filter.values)) { - operator = filter.values[0].substring(filter.values[0].indexOf(',') + 1); + filter.values.forEach((value) => { + let operator; + let filterValue; + if (hasValue(filter.operator)) { + operator = filter.operator; + filterValue = value; + } else { + operator = value.substring(value.indexOf(',') + 1); + filterValue = value.substring(0, value.indexOf(',')); + } + const valueToAdd = `${filter.key.substring(2)},${operator}=${filterValue}`; + parameters.push({name: '-f', value: valueToAdd}); + }); } - const filterValue = `${filter.key.substring(2)},${operator}=${filter.values.map((v) => v.substring(0, v.indexOf(','))).join()}`; - parameters.push({name: '-f', value: filterValue}); }); } } From 7a5381aa0f1893c5f9da331db78246cac83b38b7 Mon Sep 17 00:00:00 2001 From: WolfgangT71 <82097261+WolfgangT71@users.noreply.github.com> Date: Fri, 17 Dec 2021 17:53:47 +0100 Subject: [PATCH 0019/2129] Update de.json5 --- src/assets/i18n/de.json5 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index bb719f202ee..f3a6f7eba4a 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -5323,7 +5323,7 @@ // "workflow-item.send-back.button.confirm": "Send back" // TODO New key - Add a translation - "workflow-item.send-back.button.confirm": "Send back" + "workflow-item.send-back.button.confirm": "Send back", - +"home.search-form.placeholder": "Durchsuche Repositorium" } From 565c4106f9cfa55d01cda77a43980d9ff3715dbf Mon Sep 17 00:00:00 2001 From: Pratik Rajkotiya Date: Fri, 31 Dec 2021 10:26:28 +0530 Subject: [PATCH 0020/2129] [DSC-389] add pagination. --- .../browse-by-metadata-page.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html index 2321da02041..1ec224e6b76 100644 --- a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html +++ b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html @@ -31,7 +31,7 @@ [sortConfig]="(currentSort$ |async)" [type]="startsWithType" [startsWithOptions]="startsWithOptions" - [enableArrows]="true" + [enableArrows]="false" (prev)="goPrev()" (next)="goNext()"> From e4d099df43189d9abb9e6c787918549dd5fb4132 Mon Sep 17 00:00:00 2001 From: Pratik Rajkotiya Date: Wed, 2 Feb 2022 14:05:10 +0530 Subject: [PATCH 0021/2129] [DSC-389] pagination added. --- .../browse-by-metadata-page.component.html | 2 +- .../shared/browse-by/browse-by.component.html | 36 +++---------- .../browse-by/browse-by.component.spec.ts | 8 +-- .../shared/browse-by/browse-by.component.ts | 12 ++--- .../object-collection.component.html | 5 ++ .../object-collection.component.ts | 29 ++++++++++ .../object-detail.component.html | 7 ++- .../object-detail/object-detail.component.ts | 29 ++++++++++ .../object-grid/object-grid.component.html | 8 ++- .../object-grid/object-grid.component.ts | 30 +++++++++++ .../object-list/object-list.component.html | 7 ++- .../object-list/object-list.component.ts | 29 ++++++++++ .../pagination/pagination.component.html | 39 +++++++++----- .../shared/pagination/pagination.component.ts | 53 +++++++++++++++++++ 14 files changed, 239 insertions(+), 55 deletions(-) diff --git a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html index 1ec224e6b76..b38fcb0235a 100644 --- a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html +++ b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html @@ -31,7 +31,7 @@ [sortConfig]="(currentSort$ |async)" [type]="startsWithType" [startsWithOptions]="startsWithOptions" - [enableArrows]="false" + [showPaginator]="true" (prev)="goPrev()" (next)="goNext()"> diff --git a/src/app/shared/browse-by/browse-by.component.html b/src/app/shared/browse-by/browse-by.component.html index 6d1422293db..cc126768e4a 100644 --- a/src/app/shared/browse-by/browse-by.component.html +++ b/src/app/shared/browse-by/browse-by.component.html @@ -2,37 +2,14 @@

{{title | translate}}

-
+ [config]="paginationConfig" + [sortConfig]="sortConfig" + [showPaginator]="showPaginator" + [objects]="objects" + (prev)="goPrev()" + (next)="goNext()"> -
-
-
-
-
- -
- - - - -
-
-
-
-
    -
  • - -
  • -
-
- - -
-
@@ -40,3 +17,4 @@ {{'browse.empty' | translate}}
+ diff --git a/src/app/shared/browse-by/browse-by.component.spec.ts b/src/app/shared/browse-by/browse-by.component.spec.ts index 896537b63a7..a39a207c77b 100644 --- a/src/app/shared/browse-by/browse-by.component.spec.ts +++ b/src/app/shared/browse-by/browse-by.component.spec.ts @@ -129,9 +129,9 @@ describe('BrowseByComponent', () => { expect(fixture.debugElement.query(By.css('ds-viewable-collection'))).toBeDefined(); }); - describe('when enableArrows is true and objects are defined', () => { + describe('when showPaginator is true and objects are defined', () => { beforeEach(() => { - comp.enableArrows = true; + comp.showPaginator = true; comp.objects$ = mockItemsRD$; comp.paginationConfig = paginationConfig; @@ -188,7 +188,7 @@ describe('BrowseByComponent', () => { }); }); - describe('when enableArrows is true and browseEntries are provided', () => { + describe('when showPaginator is true and browseEntries are provided', () => { let browseEntries; beforeEach(() => { @@ -209,7 +209,7 @@ describe('BrowseByComponent', () => { }), ]; - comp.enableArrows = true; + comp.showPaginator = true; comp.objects$ = createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), browseEntries)); comp.paginationConfig = paginationConfig; comp.sortConfig = Object.assign(new SortOptions('dc.title', SortDirection.ASC)); diff --git a/src/app/shared/browse-by/browse-by.component.ts b/src/app/shared/browse-by/browse-by.component.ts index 861e4316353..82458976097 100644 --- a/src/app/shared/browse-by/browse-by.component.ts +++ b/src/app/shared/browse-by/browse-by.component.ts @@ -67,30 +67,30 @@ export class BrowseByComponent implements OnInit { /** * Whether or not the pagination should be rendered as simple previous and next buttons instead of the normal pagination */ - @Input() enableArrows = false; + @Input() showPaginator = true; /** - * If enableArrows is set to true, should it hide the options gear? + * If showPaginator is set to true, should it hide the options gear? */ @Input() hideGear = false; /** - * If enableArrows is set to true, emit when the previous button is clicked + * If showPaginator is set to true, emit when the previous button is clicked */ @Output() prev = new EventEmitter(); /** - * If enableArrows is set to true, emit when the next button is clicked + * If showPaginator is set to true, emit when the next button is clicked */ @Output() next = new EventEmitter(); /** - * If enableArrows is set to true, emit when the page size is changed + * If showPaginator is set to true, emit when the page size is changed */ @Output() pageSizeChange = new EventEmitter(); /** - * If enableArrows is set to true, emit when the sort direction is changed + * If showPaginator is set to true, emit when the sort direction is changed */ @Output() sortDirectionChange = new EventEmitter(); diff --git a/src/app/shared/object-collection/object-collection.component.html b/src/app/shared/object-collection/object-collection.component.html index f2778757efe..999ae9a1205 100644 --- a/src/app/shared/object-collection/object-collection.component.html +++ b/src/app/shared/object-collection/object-collection.component.html @@ -6,6 +6,7 @@ [linkType]="linkType" [context]="context" [hidePaginationDetail]="hidePaginationDetail" + [showPaginator]="showPaginator" (paginationChange)="onPaginationChange($event)" (pageChange)="onPageChange($event)" (pageSizeChange)="onPageSizeChange($event)" @@ -19,6 +20,8 @@ [importConfig]="importConfig" (importObject)="importObject.emit($event)" (contentChange)="contentChange.emit()" + (prev)="goPrev()" + (next)="goNext()" *ngIf="(currentMode$ | async) === viewModeEnum.ListElement"> @@ -29,6 +32,7 @@ [linkType]="linkType" [context]="context" [hidePaginationDetail]="hidePaginationDetail" + [showPaginator]="showPaginator" (paginationChange)="onPaginationChange($event)" (pageChange)="onPageChange($event)" (pageSizeChange)="onPageSizeChange($event)" @@ -44,6 +48,7 @@ [linkType]="linkType" [context]="context" [hidePaginationDetail]="hidePaginationDetail" + [showPaginator]="showPaginator" *ngIf="(currentMode$ | async) === viewModeEnum.DetailedListElement"> diff --git a/src/app/shared/object-collection/object-collection.component.ts b/src/app/shared/object-collection/object-collection.component.ts index 29fdb37ea12..f2706f1a4ca 100644 --- a/src/app/shared/object-collection/object-collection.component.ts +++ b/src/app/shared/object-collection/object-collection.component.ts @@ -88,6 +88,11 @@ export class ObjectCollectionComponent implements OnInit { */ @Input() hidePaginationDetail = false; + /** + * Whether or not the pagination should be rendered as simple previous and next buttons instead of the normal pagination + */ + @Input() showPaginator = true; + /** * the page info of the list */ @@ -122,6 +127,16 @@ export class ObjectCollectionComponent implements OnInit { */ @Output() sortFieldChange: EventEmitter = new EventEmitter(); + /** + * If showPaginator is set to true, emit when the previous button is clicked + */ + @Output() prev = new EventEmitter(); + + /** + * If showPaginator is set to true, emit when the next button is clicked + */ + @Output() next = new EventEmitter(); + /** * Emits the current view mode */ @@ -192,4 +207,18 @@ export class ObjectCollectionComponent implements OnInit { this.paginationChange.emit(event); } + /** + * Go to the previous page + */ + goPrev() { + this.prev.emit(true); + } + + /** + * Go to the next page + */ + goNext() { + this.next.emit(true); + } + } diff --git a/src/app/shared/object-detail/object-detail.component.html b/src/app/shared/object-detail/object-detail.component.html index 7fef7d9689b..32728d92e47 100644 --- a/src/app/shared/object-detail/object-detail.component.html +++ b/src/app/shared/object-detail/object-detail.component.html @@ -3,14 +3,19 @@ [pageInfoState]="objects?.payload" [collectionSize]="objects?.payload?.totalElements" [sortOptions]="sortConfig" + [objects]="objects" [hideGear]="hideGear" [hidePaginationDetail]="hidePaginationDetail" [hidePagerWhenSinglePage]="hidePagerWhenSinglePage" + [showPaginator]="showPaginator" (pageChange)="onPageChange($event)" (pageSizeChange)="onPageSizeChange($event)" (sortDirectionChange)="onSortDirectionChange($event)" (sortFieldChange)="onSortFieldChange($event)" - (paginationChange)="onPaginationChange($event)"> + (paginationChange)="onPaginationChange($event)" + (prev)="goPrev()" + (next)="goNext()" + >
diff --git a/src/app/shared/object-detail/object-detail.component.ts b/src/app/shared/object-detail/object-detail.component.ts index 8b94746fbd8..05d2ca4b5ba 100644 --- a/src/app/shared/object-detail/object-detail.component.ts +++ b/src/app/shared/object-detail/object-detail.component.ts @@ -66,6 +66,21 @@ export class ObjectDetailComponent { */ @Input() context: Context; + /** + * Whether or not the pagination should be rendered as simple previous and next buttons instead of the normal pagination + */ + @Input() showPaginator = true; + + /** + * If showPaginator is set to true, emit when the previous button is clicked + */ + @Output() prev = new EventEmitter(); + + /** + * If showPaginator is set to true, emit when the next button is clicked + */ + @Output() next = new EventEmitter(); + /** * The list of objects to paginate */ @@ -168,4 +183,18 @@ export class ObjectDetailComponent { this.paginationChange.emit(event); } + /** + * Go to the previous page + */ + goPrev() { + this.prev.emit(true); + } + + /** + * Go to the next page + */ + goNext() { + this.next.emit(true); + } + } diff --git a/src/app/shared/object-grid/object-grid.component.html b/src/app/shared/object-grid/object-grid.component.html index 0afd623d868..0961aa29895 100644 --- a/src/app/shared/object-grid/object-grid.component.html +++ b/src/app/shared/object-grid/object-grid.component.html @@ -4,13 +4,18 @@ [collectionSize]="objects?.payload?.totalElements" [sortOptions]="sortConfig" [hideGear]="hideGear" + [objects]="objects" [hidePagerWhenSinglePage]="hidePagerWhenSinglePage" [hidePaginationDetail]="hidePaginationDetail" + [showPaginator]="showPaginator" (pageChange)="onPageChange($event)" (pageSizeChange)="onPageSizeChange($event)" (sortDirectionChange)="onSortDirectionChange($event)" (sortFieldChange)="onSortFieldChange($event)" - (paginationChange)="onPaginationChange($event)"> + (paginationChange)="onPaginationChange($event)" + (prev)="goPrev()" + (next)="goNext()" + >
@@ -22,3 +27,4 @@ + diff --git a/src/app/shared/object-grid/object-grid.component.ts b/src/app/shared/object-grid/object-grid.component.ts index 39c3d56f7fe..1b5ab075e26 100644 --- a/src/app/shared/object-grid/object-grid.component.ts +++ b/src/app/shared/object-grid/object-grid.component.ts @@ -49,6 +49,11 @@ export class ObjectGridComponent implements OnInit { */ @Input() sortConfig: SortOptions; + /** + * Whether or not the pagination should be rendered as simple previous and next buttons instead of the normal pagination + */ + @Input() showPaginator = true; + /** * The whether or not the gear is hidden */ @@ -134,6 +139,17 @@ export class ObjectGridComponent implements OnInit { * Event's payload equals to the newly selected sort field. */ @Output() sortFieldChange: EventEmitter = new EventEmitter(); + + /** + * If showPaginator is set to true, emit when the previous button is clicked + */ + @Output() prev = new EventEmitter(); + + /** + * If showPaginator is set to true, emit when the next button is clicked + */ + @Output() next = new EventEmitter(); + data: any = {}; columns$: Observable; @@ -225,4 +241,18 @@ export class ObjectGridComponent implements OnInit { this.paginationChange.emit(event); } + /** + * Go to the previous page + */ + goPrev() { + this.prev.emit(true); + } + + /** + * Go to the next page + */ + goNext() { + this.next.emit(true); + } + } diff --git a/src/app/shared/object-list/object-list.component.html b/src/app/shared/object-list/object-list.component.html index 331ff1cb288..1c6d01ba116 100644 --- a/src/app/shared/object-list/object-list.component.html +++ b/src/app/shared/object-list/object-list.component.html @@ -2,15 +2,20 @@ [paginationOptions]="config" [pageInfoState]="objects?.payload" [collectionSize]="objects?.payload?.totalElements" + [objects]="objects" [sortOptions]="sortConfig" [hideGear]="hideGear" [hidePagerWhenSinglePage]="hidePagerWhenSinglePage" [hidePaginationDetail]="hidePaginationDetail" + [showPaginator]="showPaginator" (pageChange)="onPageChange($event)" (pageSizeChange)="onPageSizeChange($event)" (sortDirectionChange)="onSortDirectionChange($event)" (sortFieldChange)="onSortFieldChange($event)" - (paginationChange)="onPaginationChange($event)"> + (paginationChange)="onPaginationChange($event)" + (prev)="goPrev()" + (next)="goNext()" + >
  • (); + /** + * If showPaginator is set to true, emit when the previous button is clicked + */ + @Output() prev = new EventEmitter(); + + /** + * If showPaginator is set to true, emit when the next button is clicked + */ + @Output() next = new EventEmitter(); + /** * The current listable objects */ @@ -192,4 +207,18 @@ export class ObjectListComponent { onPaginationChange(event) { this.paginationChange.emit(event); } + + /** + * Go to the previous page + */ + goPrev() { + this.prev.emit(true); + } + + /** + * Go to the next page + */ + goNext() { + this.next.emit(true); + } } diff --git a/src/app/shared/pagination/pagination.component.html b/src/app/shared/pagination/pagination.component.html index 2a9aa1a0624..785d38af968 100644 --- a/src/app/shared/pagination/pagination.component.html +++ b/src/app/shared/pagination/pagination.component.html @@ -1,7 +1,7 @@
    -
    +
    {{ 'pagination.showing.label' | translate }} {{ 'pagination.showing.detail' | translate:(getShowingDetails(collectionSize)|async)}}
    @@ -20,16 +20,31 @@
    - diff --git a/src/app/shared/pagination/pagination.component.ts b/src/app/shared/pagination/pagination.component.ts index 8f1c6bf26fe..21f495956d6 100644 --- a/src/app/shared/pagination/pagination.component.ts +++ b/src/app/shared/pagination/pagination.component.ts @@ -20,6 +20,10 @@ import { hasValue } from '../empty.util'; import { PageInfo } from '../../core/shared/page-info.model'; import { PaginationService } from '../../core/pagination/pagination.service'; import { map } from 'rxjs/operators'; +import { RemoteData } from 'src/app/core/data/remote-data'; +import { PaginatedList } from 'src/app/core/data/paginated-list.model'; +import { ListableObject } from '../object-collection/shared/listable-object.model'; +import { ViewMode } from 'src/app/core/shared/view-mode.model'; /** * The default pagination controls component. @@ -33,6 +37,11 @@ import { map } from 'rxjs/operators'; encapsulation: ViewEncapsulation.Emulated }) export class PaginationComponent implements OnDestroy, OnInit { + /** + * ViewMode that should be passed to {@link ListableObjectComponentLoaderComponent}. + */ + viewMode: ViewMode = ViewMode.ListElement; + /** * Number of items in collection. */ @@ -53,6 +62,26 @@ export class PaginationComponent implements OnDestroy, OnInit { */ @Input() sortOptions: SortOptions; + /** + * Whether or not the pagination should be rendered as simple previous and next buttons instead of the normal pagination + */ + @Input() showPaginator = true; + + /** + * The current pagination configuration + */ + @Input() config?: PaginationComponentOptions; + + /** + * The list of listable objects to render in this component + */ + @Input() objects: RemoteData>; + + /** + * The current sorting configuration + */ + @Input() sortConfig: SortOptions; + /** * An event fired when the page is changed. * Event's payload equals to the newly selected page. @@ -163,6 +192,15 @@ export class PaginationComponent implements OnDestroy, OnInit { */ private subs: Subscription[] = []; + /** + * If showPaginator is set to true, emit when the previous button is clicked + */ + @Output() prev = new EventEmitter(); + + /** + * If showPaginator is set to true, emit when the next button is clicked + */ + @Output() next = new EventEmitter(); /** * Method provided by Angular. Invoked after the constructor. */ @@ -347,4 +385,19 @@ export class PaginationComponent implements OnDestroy, OnInit { map((hasMultiplePages) => hasMultiplePages || !this.hidePagerWhenSinglePage) ); } + + /** + * Go to the previous page + */ + goPrev() { + this.prev.emit(true); + } + + /** + * Go to the next page + */ + goNext() { + this.next.emit(true); + } + } From 57ff37ec7f1b1caeb9860b9b3a87489b5402d542 Mon Sep 17 00:00:00 2001 From: Pratik Rajkotiya Date: Wed, 2 Feb 2022 19:11:06 +0530 Subject: [PATCH 0022/2129] [DSC-389] merged with main branch --- config/config.example.yml | 3 + src/app/app-routing-paths.ts | 6 + .../edit-bitstream-page.component.html | 2 +- .../edit-bitstream-page.component.scss | 4 + .../edit-bitstream-page.component.spec.ts | 517 +- .../edit-bitstream-page.component.ts | 264 +- src/app/core/auth/models/auth.method-type.ts | 3 +- src/app/core/auth/models/auth.method.ts | 5 + ...onfig-accesses-conditions-options.model.ts | 45 + .../models/config-submission-access.model.ts | 42 + .../config-submission-accesses.model.ts | 10 + src/app/core/config/models/config-type.ts | 2 + .../submission-accesses-config.service.ts | 42 + src/app/core/core.module.ts | 14 +- .../data/feature-authorization/feature-id.ts | 1 + .../feedback/feedback-data.service.spec.ts | 88 + .../core/feedback/feedback-data.service.ts | 49 + src/app/core/feedback/feedback.guard.ts | 20 + .../core/feedback/models/feedback.model.ts | 34 + .../feedback/models/feedback.resource-type.ts | 9 + .../models/access-condition.model.ts | 25 + .../submission-accesses.resource-type.ts | 9 + .../submission-item-access-condition.model.ts | 8 + ...sion-upload-file-access-condition.model.ts | 23 +- .../workspaceitem-section-accesses.model.ts | 21 + .../models/workspaceitem-sections.model.ts | 2 + src/app/footer/footer.component.html | 4 + .../feedback-form.component.html | 45 + .../feedback-form.component.scss | 3 + .../feedback-form.component.spec.ts | 97 + .../feedback-form/feedback-form.component.ts | 83 + src/app/info/feedback/feedback.component.html | 3 + src/app/info/feedback/feedback.component.scss | 0 .../info/feedback/feedback.component.spec.ts | 27 + src/app/info/feedback/feedback.component.ts | 12 + .../feedback/themed-feedback.component.ts | 26 + src/app/info/info-routing-paths.ts | 5 + src/app/info/info-routing.module.ts | 14 +- src/app/info/info.module.ts | 15 +- .../item-delete/item-delete.component.spec.ts | 74 +- .../item-delete/item-delete.component.ts | 59 +- ...amic-form-control-container.component.html | 3 +- .../dynamic-form-array.component.html | 4 +- .../dynamic-form-array.component.scss | 10 +- .../methods/oidc/log-in-oidc.component.html | 3 + .../oidc/log-in-oidc.component.spec.ts | 155 + .../methods/oidc/log-in-oidc.component.ts | 110 + .../shared/mocks/mock-native-window-ref.ts | 3 +- .../section-accesses-config.service.mock.ts | 87 + .../mocks/section-accesses.service.mock.ts | 13 + src/app/shared/mocks/submission.mock.ts | 93 +- src/app/shared/shared.module.ts | 3 + src/app/shared/testing/form-event.stub.ts | 100 + src/app/shared/testing/route-service.stub.ts | 5 +- .../form/submission-form.component.ts | 2 +- .../objects/submission-objects.effects.ts | 6 +- .../accesses/section-accesses.component.html | 7 + .../accesses/section-accesses.component.scss | 5 + .../section-accesses.component.spec.ts | 204 + .../accesses/section-accesses.component.ts | 379 + .../accesses/section-accesses.model.ts | 123 + .../accesses/section-accesses.service.ts | 42 + .../container/section-container.component.ts | 6 +- .../form/section-form.component.spec.ts | 16 +- .../sections/form/section-form.component.ts | 2 +- .../sections/models/section.model.ts | 4 +- src/app/submission/sections/sections-type.ts | 3 +- .../edit/section-upload-file-edit.model.ts | 5 +- .../file/section-upload-file.component.ts | 12 +- src/app/submission/selectors.ts | 11 +- src/app/submission/submission.module.ts | 58 +- src/assets/i18n/en.json5 | 84 + src/assets/i18n/gd.json5 | 6076 +++++++++++++++++ src/config/default-app-config.ts | 1 + .../app/info/feedback/feedback.component.html | 0 .../app/info/feedback/feedback.component.scss | 0 .../app/info/feedback/feedback.component.ts | 15 + src/themes/custom/theme.module.ts | 4 +- 78 files changed, 9088 insertions(+), 281 deletions(-) create mode 100644 src/app/core/config/models/config-accesses-conditions-options.model.ts create mode 100644 src/app/core/config/models/config-submission-access.model.ts create mode 100644 src/app/core/config/models/config-submission-accesses.model.ts create mode 100644 src/app/core/config/submission-accesses-config.service.ts create mode 100644 src/app/core/feedback/feedback-data.service.spec.ts create mode 100644 src/app/core/feedback/feedback-data.service.ts create mode 100644 src/app/core/feedback/feedback.guard.ts create mode 100644 src/app/core/feedback/models/feedback.model.ts create mode 100644 src/app/core/feedback/models/feedback.resource-type.ts create mode 100644 src/app/core/submission/models/access-condition.model.ts create mode 100644 src/app/core/submission/models/submission-accesses.resource-type.ts create mode 100644 src/app/core/submission/models/submission-item-access-condition.model.ts create mode 100644 src/app/core/submission/models/workspaceitem-section-accesses.model.ts create mode 100644 src/app/info/feedback/feedback-form/feedback-form.component.html create mode 100644 src/app/info/feedback/feedback-form/feedback-form.component.scss create mode 100644 src/app/info/feedback/feedback-form/feedback-form.component.spec.ts create mode 100644 src/app/info/feedback/feedback-form/feedback-form.component.ts create mode 100644 src/app/info/feedback/feedback.component.html create mode 100644 src/app/info/feedback/feedback.component.scss create mode 100644 src/app/info/feedback/feedback.component.spec.ts create mode 100644 src/app/info/feedback/feedback.component.ts create mode 100644 src/app/info/feedback/themed-feedback.component.ts create mode 100644 src/app/shared/log-in/methods/oidc/log-in-oidc.component.html create mode 100644 src/app/shared/log-in/methods/oidc/log-in-oidc.component.spec.ts create mode 100644 src/app/shared/log-in/methods/oidc/log-in-oidc.component.ts create mode 100644 src/app/shared/mocks/section-accesses-config.service.mock.ts create mode 100644 src/app/shared/mocks/section-accesses.service.mock.ts create mode 100644 src/app/shared/testing/form-event.stub.ts create mode 100644 src/app/submission/sections/accesses/section-accesses.component.html create mode 100644 src/app/submission/sections/accesses/section-accesses.component.scss create mode 100644 src/app/submission/sections/accesses/section-accesses.component.spec.ts create mode 100644 src/app/submission/sections/accesses/section-accesses.component.ts create mode 100644 src/app/submission/sections/accesses/section-accesses.model.ts create mode 100644 src/app/submission/sections/accesses/section-accesses.service.ts create mode 100644 src/assets/i18n/gd.json5 create mode 100644 src/themes/custom/app/info/feedback/feedback.component.html create mode 100644 src/themes/custom/app/info/feedback/feedback.component.scss create mode 100644 src/themes/custom/app/info/feedback/feedback.component.ts diff --git a/config/config.example.yml b/config/config.example.yml index 1e035889a50..ecb2a3cfb93 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -127,6 +127,9 @@ languages: - code: fr label: Français active: true + - code: gd + label: Gàidhlig + active: true - code: lv label: Latviešu active: true diff --git a/src/app/app-routing-paths.ts b/src/app/app-routing-paths.ts index d9c3410931f..57767b6f3e6 100644 --- a/src/app/app-routing-paths.ts +++ b/src/app/app-routing-paths.ts @@ -32,6 +32,12 @@ export function getBitstreamRequestACopyRoute(item, bitstream): { routerLink: st }; } +export const HOME_PAGE_PATH = 'admin'; + +export function getHomePageRoute() { + return `/${HOME_PAGE_PATH}`; +} + export const ADMIN_MODULE_PATH = 'admin'; export function getAdminModuleRoute() { diff --git a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.html b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.html index cbb587cca48..4d3b948a583 100644 --- a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.html +++ b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.html @@ -12,7 +12,7 @@

    {{bitstreamRD?.payload?.name}} ({{bitstreamRD?.payl

    - div > label { + margin-top: 1.75rem; +} + diff --git a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.spec.ts b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.spec.ts index 67f8866e6df..44e48182fd9 100644 --- a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.spec.ts +++ b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.spec.ts @@ -22,6 +22,8 @@ import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } f import { getEntityEditRoute } from '../../item-page/item-page-routing-paths'; import { createPaginatedList } from '../../shared/testing/utils.test'; import { Item } from '../../core/shared/item.model'; +import { MetadataValueFilter } from '../../core/shared/metadata.models'; +import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; const infoNotification: INotification = new Notification('id', NotificationType.Info, 'info'); const warningNotification: INotification = new Notification('id', NotificationType.Warning, 'warning'); @@ -31,24 +33,27 @@ let notificationsService: NotificationsService; let formService: DynamicFormService; let bitstreamService: BitstreamDataService; let bitstreamFormatService: BitstreamFormatDataService; +let dsoNameService: DSONameService; let bitstream: Bitstream; let selectedFormat: BitstreamFormat; let allFormats: BitstreamFormat[]; let router: Router; +let comp: EditBitstreamPageComponent; +let fixture: ComponentFixture; + describe('EditBitstreamPageComponent', () => { - let comp: EditBitstreamPageComponent; - let fixture: ComponentFixture; - beforeEach(waitForAsync(() => { + beforeEach(() => { allFormats = [ Object.assign({ id: '1', shortDescription: 'Unknown', description: 'Unknown format', supportLevel: BitstreamFormatSupportLevel.Unknown, + mimetype: 'application/octet-stream', _links: { - self: { href: 'format-selflink-1' } + self: {href: 'format-selflink-1'} } }), Object.assign({ @@ -56,8 +61,9 @@ describe('EditBitstreamPageComponent', () => { shortDescription: 'PNG', description: 'Portable Network Graphics', supportLevel: BitstreamFormatSupportLevel.Known, + mimetype: 'image/png', _links: { - self: { href: 'format-selflink-2' } + self: {href: 'format-selflink-2'} } }), Object.assign({ @@ -65,19 +71,14 @@ describe('EditBitstreamPageComponent', () => { shortDescription: 'GIF', description: 'Graphics Interchange Format', supportLevel: BitstreamFormatSupportLevel.Known, + mimetype: 'image/gif', _links: { - self: { href: 'format-selflink-3' } + self: {href: 'format-selflink-3'} } }) ] as BitstreamFormat[]; selectedFormat = allFormats[1]; - notificationsService = jasmine.createSpyObj('notificationsService', - { - info: infoNotification, - warning: warningNotification, - success: successNotification - } - ); + formService = Object.assign({ createFormGroup: (fModel: DynamicFormControlModel[]) => { const controls = {}; @@ -90,156 +91,418 @@ describe('EditBitstreamPageComponent', () => { return undefined; } }); - bitstream = Object.assign(new Bitstream(), { - metadata: { - 'dc.description': [ - { - value: 'Bitstream description' - } - ], - 'dc.title': [ - { - value: 'Bitstream title' - } - ] - }, - format: createSuccessfulRemoteDataObject$(selectedFormat), - _links: { - self: 'bitstream-selflink' - }, - bundle: createSuccessfulRemoteDataObject$({ - item: createSuccessfulRemoteDataObject$(Object.assign(new Item(), { - uuid: 'some-uuid' - })) - }) - }); - bitstreamService = jasmine.createSpyObj('bitstreamService', { - findById: createSuccessfulRemoteDataObject$(bitstream), - update: createSuccessfulRemoteDataObject$(bitstream), - updateFormat: createSuccessfulRemoteDataObject$(bitstream), - commitUpdates: {}, - patch: {} - }); + bitstreamFormatService = jasmine.createSpyObj('bitstreamFormatService', { findAll: createSuccessfulRemoteDataObject$(createPaginatedList(allFormats)) }); - TestBed.configureTestingModule({ - imports: [TranslateModule.forRoot(), RouterTestingModule], - declarations: [EditBitstreamPageComponent, FileSizePipe, VarDirective], - providers: [ - { provide: NotificationsService, useValue: notificationsService }, - { provide: DynamicFormService, useValue: formService }, - { provide: ActivatedRoute, useValue: { data: observableOf({ bitstream: createSuccessfulRemoteDataObject(bitstream) }), snapshot: { queryParams: {} } } }, - { provide: BitstreamDataService, useValue: bitstreamService }, - { provide: BitstreamFormatDataService, useValue: bitstreamFormatService }, - ChangeDetectorRef - ], - schemas: [NO_ERRORS_SCHEMA] - }).compileComponents(); - - })); - - beforeEach(() => { - fixture = TestBed.createComponent(EditBitstreamPageComponent); - comp = fixture.componentInstance; - fixture.detectChanges(); - router = TestBed.inject(Router); - spyOn(router, 'navigate'); + notificationsService = jasmine.createSpyObj('notificationsService', + { + info: infoNotification, + warning: warningNotification, + success: successNotification + } + ); }); - describe('on startup', () => { - let rawForm; + describe('EditBitstreamPageComponent no IIIF fields', () => { - beforeEach(() => { - rawForm = comp.formGroup.getRawValue(); - }); + beforeEach(waitForAsync(() => { - it('should fill in the bitstream\'s title', () => { - expect(rawForm.fileNamePrimaryContainer.fileName).toEqual(bitstream.name); - }); + const bundleName = 'ORIGINAL'; - it('should fill in the bitstream\'s description', () => { - expect(rawForm.descriptionContainer.description).toEqual(bitstream.firstMetadataValue('dc.description')); - }); + bitstream = Object.assign(new Bitstream(), { + metadata: { + 'dc.description': [ + { + value: 'Bitstream description' + } + ], + 'dc.title': [ + { + value: 'Bitstream title' + } + ] + }, + format: createSuccessfulRemoteDataObject$(selectedFormat), + _links: { + self: 'bitstream-selflink' + }, + bundle: createSuccessfulRemoteDataObject$({ + item: createSuccessfulRemoteDataObject$(Object.assign(new Item(), { + uuid: 'some-uuid', + firstMetadataValue(keyOrKeys: string | string[], valueFilter?: MetadataValueFilter): string { + return undefined; + }, + })) + }) + }); + bitstreamService = jasmine.createSpyObj('bitstreamService', { + findById: createSuccessfulRemoteDataObject$(bitstream), + update: createSuccessfulRemoteDataObject$(bitstream), + updateFormat: createSuccessfulRemoteDataObject$(bitstream), + commitUpdates: {}, + patch: {} + }); + bitstreamFormatService = jasmine.createSpyObj('bitstreamFormatService', { + findAll: createSuccessfulRemoteDataObject$(createPaginatedList(allFormats)) + }); + dsoNameService = jasmine.createSpyObj('dsoNameService', { + getName: bundleName + }); - it('should select the correct format', () => { - expect(rawForm.formatContainer.selectedFormat).toEqual(selectedFormat.id); - }); + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot(), RouterTestingModule], + declarations: [EditBitstreamPageComponent, FileSizePipe, VarDirective], + providers: [ + {provide: NotificationsService, useValue: notificationsService}, + {provide: DynamicFormService, useValue: formService}, + {provide: ActivatedRoute, + useValue: { + data: observableOf({bitstream: createSuccessfulRemoteDataObject(bitstream)}), + snapshot: {queryParams: {}} + } + }, + {provide: BitstreamDataService, useValue: bitstreamService}, + {provide: DSONameService, useValue: dsoNameService}, + {provide: BitstreamFormatDataService, useValue: bitstreamFormatService}, + ChangeDetectorRef + ], + schemas: [NO_ERRORS_SCHEMA] + }).compileComponents(); - it('should put the \"New Format\" input on invisible', () => { - expect(comp.formLayout.newFormat.grid.host).toContain('invisible'); - }); - }); + })); - describe('when an unknown format is selected', () => { beforeEach(() => { - comp.updateNewFormatLayout(allFormats[0].id); + fixture = TestBed.createComponent(EditBitstreamPageComponent); + comp = fixture.componentInstance; + fixture.detectChanges(); + router = TestBed.inject(Router); + spyOn(router, 'navigate'); }); - it('should remove the invisible class from the \"New Format\" input', () => { - expect(comp.formLayout.newFormat.grid.host).not.toContain('invisible'); - }); - }); + describe('on startup', () => { + let rawForm; - describe('onSubmit', () => { - describe('when selected format hasn\'t changed', () => { beforeEach(() => { - comp.onSubmit(); + rawForm = comp.formGroup.getRawValue(); + }); + + it('should fill in the bitstream\'s title', () => { + expect(rawForm.fileNamePrimaryContainer.fileName).toEqual(bitstream.name); }); - it('should call update', () => { - expect(bitstreamService.update).toHaveBeenCalled(); + it('should fill in the bitstream\'s description', () => { + expect(rawForm.descriptionContainer.description).toEqual(bitstream.firstMetadataValue('dc.description')); }); - it('should commit the updates', () => { - expect(bitstreamService.commitUpdates).toHaveBeenCalled(); + it('should select the correct format', () => { + expect(rawForm.formatContainer.selectedFormat).toEqual(selectedFormat.id); + }); + + it('should put the \"New Format\" input on invisible', () => { + expect(comp.formLayout.newFormat.grid.host).toContain('invisible'); }); }); - describe('when selected format has changed', () => { + describe('when an unknown format is selected', () => { beforeEach(() => { - comp.formGroup.patchValue({ - formatContainer: { - selectedFormat: allFormats[2].id - } - }); - fixture.detectChanges(); - comp.onSubmit(); + comp.updateNewFormatLayout(allFormats[0].id); }); - it('should call update', () => { - expect(bitstreamService.update).toHaveBeenCalled(); + it('should remove the invisible class from the \"New Format\" input', () => { + expect(comp.formLayout.newFormat.grid.host).not.toContain('invisible'); }); + }); + + describe('onSubmit', () => { + describe('when selected format hasn\'t changed', () => { + beforeEach(() => { + comp.onSubmit(); + }); - it('should call updateFormat', () => { - expect(bitstreamService.updateFormat).toHaveBeenCalled(); + it('should call update', () => { + expect(bitstreamService.update).toHaveBeenCalled(); + }); + + it('should commit the updates', () => { + expect(bitstreamService.commitUpdates).toHaveBeenCalled(); + }); }); - it('should commit the updates', () => { - expect(bitstreamService.commitUpdates).toHaveBeenCalled(); + describe('when selected format has changed', () => { + beforeEach(() => { + comp.formGroup.patchValue({ + formatContainer: { + selectedFormat: allFormats[2].id + } + }); + fixture.detectChanges(); + comp.onSubmit(); + }); + + it('should call update', () => { + expect(bitstreamService.update).toHaveBeenCalled(); + }); + + it('should call updateFormat', () => { + expect(bitstreamService.updateFormat).toHaveBeenCalled(); + }); + + it('should commit the updates', () => { + expect(bitstreamService.commitUpdates).toHaveBeenCalled(); + }); }); }); - }); - describe('when the cancel button is clicked', () => { - it('should call navigateToItemEditBitstreams method', () => { - spyOn(comp, 'navigateToItemEditBitstreams'); - comp.onCancel(); - expect(comp.navigateToItemEditBitstreams).toHaveBeenCalled(); + describe('when the cancel button is clicked', () => { + it('should call navigateToItemEditBitstreams method', () => { + spyOn(comp, 'navigateToItemEditBitstreams'); + comp.onCancel(); + expect(comp.navigateToItemEditBitstreams).toHaveBeenCalled(); + }); }); - }); - describe('when navigateToItemEditBitstreams is called, and the component has an itemId', () => { - it('should redirect to the item edit page on the bitstreams tab with the itemId from the component', () => { - comp.itemId = 'some-uuid1'; - comp.navigateToItemEditBitstreams(); - expect(router.navigate).toHaveBeenCalledWith([getEntityEditRoute(null, 'some-uuid1'), 'bitstreams']); + describe('when navigateToItemEditBitstreams is called, and the component has an itemId', () => { + it('should redirect to the item edit page on the bitstreams tab with the itemId from the component', () => { + comp.itemId = 'some-uuid1'; + comp.navigateToItemEditBitstreams(); + expect(router.navigate).toHaveBeenCalledWith([getEntityEditRoute(null, 'some-uuid1'), 'bitstreams']); + }); + }); + describe('when navigateToItemEditBitstreams is called, and the component does not have an itemId', () => { + it('should redirect to the item edit page on the bitstreams tab with the itemId from the bundle links ', () => { + comp.itemId = undefined; + comp.navigateToItemEditBitstreams(); + expect(router.navigate).toHaveBeenCalledWith([getEntityEditRoute(null, 'some-uuid'), 'bitstreams']); + }); }); }); - describe('when navigateToItemEditBitstreams is called, and the component does not have an itemId', () => { - it('should redirect to the item edit page on the bitstreams tab with the itemId from the bundle links ', () => { - comp.itemId = undefined; - comp.navigateToItemEditBitstreams(); - expect(router.navigate).toHaveBeenCalledWith([getEntityEditRoute(null, 'some-uuid'), 'bitstreams']); + + describe('EditBitstreamPageComponent with IIIF fields', () => { + + const bundleName = 'ORIGINAL'; + + beforeEach(waitForAsync(() => { + + bitstream = Object.assign(new Bitstream(), { + metadata: { + 'dc.description': [ + { + value: 'Bitstream description' + } + ], + 'dc.title': [ + { + value: 'Bitstream title' + } + ], + 'iiif.label': [ + { + value: 'chapter one' + } + ], + 'iiif.toc': [ + { + value: 'chapter one' + } + ], + 'iiif.image.width': [ + { + value: '2400' + } + ], + 'iiif.image.height': [ + { + value: '2800' + } + ], + }, + format: createSuccessfulRemoteDataObject$(allFormats[1]), + _links: { + self: 'bitstream-selflink' + }, + bundle: createSuccessfulRemoteDataObject$({ + item: createSuccessfulRemoteDataObject$(Object.assign(new Item(), { + uuid: 'some-uuid', + firstMetadataValue(keyOrKeys: string | string[], valueFilter?: MetadataValueFilter): string { + return 'True'; + } + })) + }) + }); + bitstreamService = jasmine.createSpyObj('bitstreamService', { + findById: createSuccessfulRemoteDataObject$(bitstream), + update: createSuccessfulRemoteDataObject$(bitstream), + updateFormat: createSuccessfulRemoteDataObject$(bitstream), + commitUpdates: {}, + patch: {} + }); + + dsoNameService = jasmine.createSpyObj('dsoNameService', { + getName: bundleName + }); + + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot(), RouterTestingModule], + declarations: [EditBitstreamPageComponent, FileSizePipe, VarDirective], + providers: [ + {provide: NotificationsService, useValue: notificationsService}, + {provide: DynamicFormService, useValue: formService}, + { + provide: ActivatedRoute, + useValue: { + data: observableOf({bitstream: createSuccessfulRemoteDataObject(bitstream)}), + snapshot: {queryParams: {}} + } + }, + {provide: BitstreamDataService, useValue: bitstreamService}, + {provide: DSONameService, useValue: dsoNameService}, + {provide: BitstreamFormatDataService, useValue: bitstreamFormatService}, + ChangeDetectorRef + ], + schemas: [NO_ERRORS_SCHEMA] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EditBitstreamPageComponent); + comp = fixture.componentInstance; + fixture.detectChanges(); + router = TestBed.inject(Router); + spyOn(router, 'navigate'); }); + + + describe('on startup', () => { + let rawForm; + + beforeEach(() => { + rawForm = comp.formGroup.getRawValue(); + }); + it('should set isIIIF to true', () => { + expect(comp.isIIIF).toBeTrue(); + }); + it('should fill in the iiif label', () => { + expect(rawForm.iiifLabelContainer.iiifLabel).toEqual('chapter one'); + }); + it('should fill in the iiif toc', () => { + expect(rawForm.iiifTocContainer.iiifToc).toEqual('chapter one'); + }); + it('should fill in the iiif width', () => { + expect(rawForm.iiifWidthContainer.iiifWidth).toEqual('2400'); + }); + it('should fill in the iiif height', () => { + expect(rawForm.iiifHeightContainer.iiifHeight).toEqual('2800'); + }); + }); + }); + + describe('ignore OTHERCONTENT bundle', () => { + + const bundleName = 'OTHERCONTENT'; + + beforeEach(waitForAsync(() => { + + bitstream = Object.assign(new Bitstream(), { + metadata: { + 'dc.description': [ + { + value: 'Bitstream description' + } + ], + 'dc.title': [ + { + value: 'Bitstream title' + } + ], + 'iiif.label': [ + { + value: 'chapter one' + } + ], + 'iiif.toc': [ + { + value: 'chapter one' + } + ], + 'iiif.image.width': [ + { + value: '2400' + } + ], + 'iiif.image.height': [ + { + value: '2800' + } + ], + }, + format: createSuccessfulRemoteDataObject$(allFormats[2]), + _links: { + self: 'bitstream-selflink' + }, + bundle: createSuccessfulRemoteDataObject$({ + item: createSuccessfulRemoteDataObject$(Object.assign(new Item(), { + uuid: 'some-uuid', + firstMetadataValue(keyOrKeys: string | string[], valueFilter?: MetadataValueFilter): string { + return 'True'; + } + })) + }) + }); + bitstreamService = jasmine.createSpyObj('bitstreamService', { + findById: createSuccessfulRemoteDataObject$(bitstream), + update: createSuccessfulRemoteDataObject$(bitstream), + updateFormat: createSuccessfulRemoteDataObject$(bitstream), + commitUpdates: {}, + patch: {} + }); + + dsoNameService = jasmine.createSpyObj('dsoNameService', { + getName: bundleName + }); + + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot(), RouterTestingModule], + declarations: [EditBitstreamPageComponent, FileSizePipe, VarDirective], + providers: [ + {provide: NotificationsService, useValue: notificationsService}, + {provide: DynamicFormService, useValue: formService}, + {provide: ActivatedRoute, + useValue: { + data: observableOf({bitstream: createSuccessfulRemoteDataObject(bitstream)}), + snapshot: {queryParams: {}} + } + }, + {provide: BitstreamDataService, useValue: bitstreamService}, + {provide: DSONameService, useValue: dsoNameService}, + {provide: BitstreamFormatDataService, useValue: bitstreamFormatService}, + ChangeDetectorRef + ], + schemas: [NO_ERRORS_SCHEMA] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(EditBitstreamPageComponent); + comp = fixture.componentInstance; + fixture.detectChanges(); + router = TestBed.inject(Router); + spyOn(router, 'navigate'); + }); + + describe('EditBitstreamPageComponent with IIIF fields', () => { + let rawForm; + + beforeEach(() => { + rawForm = comp.formGroup.getRawValue(); + }); + + it('should NOT set isIIIF to true', () => { + expect(comp.isIIIF).toBeFalse(); + }); + it('should put the \"IIIF Label\" input not to be shown', () => { + expect(rawForm.iiifLabelContainer).toBeFalsy(); + }); + }); }); + }); diff --git a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts index f6ece7f4fae..9a59df4b95a 100644 --- a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts +++ b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts @@ -1,16 +1,27 @@ -import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; +import { + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + OnDestroy, + OnInit +} from '@angular/core'; import { Bitstream } from '../../core/shared/bitstream.model'; import { ActivatedRoute, Router } from '@angular/router'; import { map, mergeMap, switchMap } from 'rxjs/operators'; -import { combineLatest as observableCombineLatest, Observable, of as observableOf, Subscription } from 'rxjs'; +import { + combineLatest, + combineLatest as observableCombineLatest, + Observable, + of as observableOf, + Subscription +} from 'rxjs'; import { DynamicFormControlModel, DynamicFormGroupModel, DynamicFormLayout, DynamicFormService, DynamicInputModel, - DynamicSelectModel, - DynamicTextAreaModel + DynamicSelectModel } from '@ng-dynamic-forms/core'; import { FormGroup } from '@angular/forms'; import { TranslateService } from '@ngx-translate/core'; @@ -28,13 +39,19 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { BitstreamFormatDataService } from '../../core/data/bitstream-format-data.service'; import { BitstreamFormat } from '../../core/shared/bitstream-format.model'; import { BitstreamFormatSupportLevel } from '../../core/shared/bitstream-format-support-level'; -import { hasValue, isNotEmpty } from '../../shared/empty.util'; +import { hasValue, isNotEmpty, isEmpty } from '../../shared/empty.util'; import { Metadata } from '../../core/shared/metadata.utils'; import { Location } from '@angular/common'; import { RemoteData } from '../../core/data/remote-data'; import { PaginatedList } from '../../core/data/paginated-list.model'; import { getEntityEditRoute, getItemEditRoute } from '../../item-page/item-page-routing-paths'; import { Bundle } from '../../core/shared/bundle.model'; +import { DSONameService } from '../../core/breadcrumbs/dso-name.service'; +import { Item } from '../../core/shared/item.model'; +import { + DsDynamicInputModel +} from '../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-input.model'; +import { DsDynamicTextAreaModel } from '../../shared/form/builder/ds-dynamic-form-ui/models/ds-dynamic-textarea.model'; @Component({ selector: 'ds-edit-bitstream-page', @@ -94,6 +111,26 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { */ NOTIFICATIONS_PREFIX = 'bitstream.edit.notifications.'; + /** + * IIIF image width metadata key + */ + IMAGE_WIDTH_METADATA = 'iiif.image.width'; + + /** + * IIIF image height metadata key + */ + IMAGE_HEIGHT_METADATA = 'iiif.image.height'; + + /** + * IIIF table of contents metadata key + */ + IIIF_TOC_METADATA = 'iiif.toc'; + + /** + * IIIF label metadata key + */ + IIIF_LABEL_METADATA = 'iiif.label'; + /** * Options for fetching all bitstream formats */ @@ -102,7 +139,8 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { /** * The Dynamic Input Model for the file's name */ - fileNameModel = new DynamicInputModel({ + fileNameModel = new DsDynamicInputModel({ + hasSelectableMetadata: false, metadataFields: [], repeatable: false, submissionId: '', id: 'fileName', name: 'fileName', required: true, @@ -118,14 +156,16 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { * The Dynamic Switch Model for the file's name */ primaryBitstreamModel = new DynamicCustomSwitchModel({ - id: 'primaryBitstream', - name: 'primaryBitstream' - }); + id: 'primaryBitstream', + name: 'primaryBitstream' + } + ); /** * The Dynamic TextArea Model for the file's description */ - descriptionModel = new DynamicTextAreaModel({ + descriptionModel = new DsDynamicTextAreaModel({ + hasSelectableMetadata: false, metadataFields: [], repeatable: false, submissionId: '', id: 'description', name: 'description', rows: 10 @@ -147,10 +187,87 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { name: 'newFormat' }); + /** + * The Dynamic Input Model for the iiif label + */ + iiifLabelModel = new DsDynamicInputModel({ + hasSelectableMetadata: false, metadataFields: [], repeatable: false, submissionId: '', + id: 'iiifLabel', + name: 'iiifLabel' + }, + { + grid: { + host: 'col col-lg-6 d-inline-block' + } + }); + iiifLabelContainer = new DynamicFormGroupModel({ + id: 'iiifLabelContainer', + group: [this.iiifLabelModel] + },{ + grid: { + host: 'form-row' + } + }); + + iiifTocModel = new DsDynamicInputModel({ + hasSelectableMetadata: false, metadataFields: [], repeatable: false, submissionId: '', + id: 'iiifToc', + name: 'iiifToc', + },{ + grid: { + host: 'col col-lg-6 d-inline-block' + } + }); + iiifTocContainer = new DynamicFormGroupModel({ + id: 'iiifTocContainer', + group: [this.iiifTocModel] + },{ + grid: { + host: 'form-row' + } + }); + + iiifWidthModel = new DsDynamicInputModel({ + hasSelectableMetadata: false, metadataFields: [], repeatable: false, submissionId: '', + id: 'iiifWidth', + name: 'iiifWidth', + },{ + grid: { + host: 'col col-lg-6 d-inline-block' + } + }); + iiifWidthContainer = new DynamicFormGroupModel({ + id: 'iiifWidthContainer', + group: [this.iiifWidthModel] + },{ + grid: { + host: 'form-row' + } + }); + + iiifHeightModel = new DsDynamicInputModel({ + hasSelectableMetadata: false, metadataFields: [], repeatable: false, submissionId: '', + id: 'iiifHeight', + name: 'iiifHeight' + },{ + grid: { + host: 'col col-lg-6 d-inline-block' + } + }); + iiifHeightContainer = new DynamicFormGroupModel({ + id: 'iiifHeightContainer', + group: [this.iiifHeightModel] + },{ + grid: { + host: 'form-row' + } + }); + /** * All input models in a simple array for easier iterations */ - inputModels = [this.fileNameModel, this.primaryBitstreamModel, this.descriptionModel, this.selectedFormatModel, this.newFormatModel]; + inputModels = [this.fileNameModel, this.primaryBitstreamModel, this.descriptionModel, this.selectedFormatModel, + this.newFormatModel]; /** * The dynamic form fields used for editing the information of a bitstream @@ -163,7 +280,11 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { this.fileNameModel, this.primaryBitstreamModel ] - }), + },{ + grid: { + host: 'form-row' + } + }), new DynamicFormGroupModel({ id: 'descriptionContainer', group: [ @@ -254,18 +375,27 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { */ entityType: string; + /** + * Set to true when the parent item supports IIIF. + */ + isIIIF = false; + + /** * Array to track all subscriptions and unsubscribe them onDestroy * @type {Array} */ protected subs: Subscription[] = []; + constructor(private route: ActivatedRoute, private router: Router, + private changeDetectorRef: ChangeDetectorRef, private location: Location, private formService: DynamicFormService, private translate: TranslateService, private bitstreamService: BitstreamDataService, + private dsoNameService: DSONameService, private notificationsService: NotificationsService, private bitstreamFormatService: BitstreamFormatDataService) { } @@ -277,7 +407,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { * - Translate the form labels and hints */ ngOnInit(): void { - this.formGroup = this.formService.createFormGroup(this.formModel); this.itemId = this.route.snapshot.queryParams.itemId; this.entityType = this.route.snapshot.queryParams.entityType; @@ -301,13 +430,10 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { ).subscribe(([bitstream, allFormats]) => { this.bitstream = bitstream as Bitstream; this.formats = allFormats.page; - this.updateFormatModel(); - this.updateForm(this.bitstream); + this.setIiifStatus(this.bitstream); }) ); - this.updateFieldTranslations(); - this.subs.push( this.translate.onLangChange .subscribe(() => { @@ -316,6 +442,16 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { ); } + /** + * Initializes the form. + */ + setForm() { + this.formGroup = this.formService.createFormGroup(this.formModel); + this.updateFormatModel(); + this.updateForm(this.bitstream); + this.updateFieldTranslations(); + } + /** * Update the current form values with bitstream properties * @param bitstream @@ -333,6 +469,22 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { newFormat: hasValue(bitstream.firstMetadata('dc.format')) ? bitstream.firstMetadata('dc.format').value : undefined } }); + if (this.isIIIF) { + this.formGroup.patchValue({ + iiifLabelContainer: { + iiifLabel: bitstream.firstMetadataValue(this.IIIF_LABEL_METADATA) + }, + iiifTocContainer: { + iiifToc: bitstream.firstMetadataValue(this.IIIF_TOC_METADATA) + }, + iiifWidthContainer: { + iiifWidth: bitstream.firstMetadataValue(this.IMAGE_WIDTH_METADATA) + }, + iiifHeightContainer: { + iiifHeight: bitstream.firstMetadataValue(this.IMAGE_HEIGHT_METADATA) + } + }); + } this.bitstream.format.pipe( getAllSucceededRemoteDataPayload() ).subscribe((format: BitstreamFormat) => { @@ -467,6 +619,32 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { const primary = rawForm.fileNamePrimaryContainer.primaryBitstream; Metadata.setFirstValue(newMetadata, 'dc.title', rawForm.fileNamePrimaryContainer.fileName); Metadata.setFirstValue(newMetadata, 'dc.description', rawForm.descriptionContainer.description); + if (this.isIIIF) { + // It's helpful to remove these metadata elements entirely when the form value is empty. + // This avoids potential issues on the REST side and makes it possible to do things like + // remove an existing "table of contents" entry. + if (isEmpty(rawForm.iiifLabelContainer.iiifLabel)) { + + delete newMetadata[this.IIIF_LABEL_METADATA]; + } else { + Metadata.setFirstValue(newMetadata, this.IIIF_LABEL_METADATA, rawForm.iiifLabelContainer.iiifLabel); + } + if (isEmpty(rawForm.iiifTocContainer.iiifToc)) { + delete newMetadata[this.IIIF_TOC_METADATA]; + } else { + Metadata.setFirstValue(newMetadata, this.IIIF_TOC_METADATA, rawForm.iiifTocContainer.iiifToc); + } + if (isEmpty(rawForm.iiifWidthContainer.iiifWidth)) { + delete newMetadata[this.IMAGE_WIDTH_METADATA]; + } else { + Metadata.setFirstValue(newMetadata, this.IMAGE_WIDTH_METADATA, rawForm.iiifWidthContainer.iiifWidth); + } + if (isEmpty(rawForm.iiifHeightContainer.iiifHeight)) { + delete newMetadata[this.IMAGE_HEIGHT_METADATA]; + } else { + Metadata.setFirstValue(newMetadata, this.IMAGE_HEIGHT_METADATA, rawForm.iiifHeightContainer.iiifHeight); + } + } if (isNotEmpty(rawForm.formatContainer.newFormat)) { Metadata.setFirstValue(newMetadata, 'dc.format', rawForm.formatContainer.newFormat); } @@ -497,6 +675,58 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { } } + /** + * Verifies that the parent item is iiif-enabled. Checks bitstream mimetype to be + * sure it's an image, excluding bitstreams in the THUMBNAIL or OTHERCONTENT bundles. + * @param bitstream + */ + setIiifStatus(bitstream: Bitstream) { + + const regexExcludeBundles = /OTHERCONTENT|THUMBNAIL|LICENSE/; + const regexIIIFItem = /true|yes/i; + + const isImage$ = this.bitstream.format.pipe( + getFirstSucceededRemoteData(), + map((format: RemoteData) => format.payload.mimetype.includes('image/'))); + + const isIIIFBundle$ = this.bitstream.bundle.pipe( + getFirstSucceededRemoteData(), + map((bundle: RemoteData) => + this.dsoNameService.getName(bundle.payload).match(regexExcludeBundles) == null)); + + const isEnabled$ = this.bitstream.bundle.pipe( + getFirstSucceededRemoteData(), + map((bundle: RemoteData) => bundle.payload.item.pipe( + getFirstSucceededRemoteData(), + map((item: RemoteData) => + (item.payload.firstMetadataValue('dspace.iiif.enabled') && + item.payload.firstMetadataValue('dspace.iiif.enabled').match(regexIIIFItem) !== null) + )))); + + const iiifSub = combineLatest( + isImage$, + isIIIFBundle$, + isEnabled$ + ).subscribe(([isImage, isIIIFBundle, isEnabled]) => { + if (isImage && isIIIFBundle && isEnabled) { + this.isIIIF = true; + this.inputModels.push(this.iiifLabelModel); + this.formModel.push(this.iiifLabelContainer); + this.inputModels.push(this.iiifTocModel); + this.formModel.push(this.iiifTocContainer); + this.inputModels.push(this.iiifWidthModel); + this.formModel.push(this.iiifWidthContainer); + this.inputModels.push(this.iiifHeightModel); + this.formModel.push(this.iiifHeightContainer); + } + this.setForm(); + this.changeDetectorRef.detectChanges(); + }); + + this.subs.push(iiifSub); + + } + /** * Unsubscribe from open subscriptions */ diff --git a/src/app/core/auth/models/auth.method-type.ts b/src/app/core/auth/models/auth.method-type.ts index f0535150651..9d999c4c3fe 100644 --- a/src/app/core/auth/models/auth.method-type.ts +++ b/src/app/core/auth/models/auth.method-type.ts @@ -3,5 +3,6 @@ export enum AuthMethodType { Shibboleth = 'shibboleth', Ldap = 'ldap', Ip = 'ip', - X509 = 'x509' + X509 = 'x509', + Oidc = 'oidc' } diff --git a/src/app/core/auth/models/auth.method.ts b/src/app/core/auth/models/auth.method.ts index 617154080b4..5a362e86060 100644 --- a/src/app/core/auth/models/auth.method.ts +++ b/src/app/core/auth/models/auth.method.ts @@ -29,6 +29,11 @@ export class AuthMethod { this.authMethodType = AuthMethodType.Password; break; } + case 'oidc': { + this.authMethodType = AuthMethodType.Oidc; + this.location = location; + break; + } default: { break; diff --git a/src/app/core/config/models/config-accesses-conditions-options.model.ts b/src/app/core/config/models/config-accesses-conditions-options.model.ts new file mode 100644 index 00000000000..244b5019086 --- /dev/null +++ b/src/app/core/config/models/config-accesses-conditions-options.model.ts @@ -0,0 +1,45 @@ +/** + * Model class for an Item Access Condition + */ +export class AccessesConditionOption { + + /** + * The name for this Access Condition + */ + name: string; + + /** + * The groupName for this Access Condition + */ + groupName: string; + + /** + * A boolean representing if this Access Condition has a start date + */ + hasStartDate: boolean; + + /** + * A boolean representing if this Access Condition has an end date + */ + hasEndDate: boolean; + + /** + * Maximum value of the start date + */ + endDateLimit?: string; + + /** + * Maximum value of the end date + */ + startDateLimit?: string; + + /** + * Maximum value of the start date + */ + maxStartDate?: string; + + /** + * Maximum value of the end date + */ + maxEndDate?: string; +} diff --git a/src/app/core/config/models/config-submission-access.model.ts b/src/app/core/config/models/config-submission-access.model.ts new file mode 100644 index 00000000000..7db96acf2bd --- /dev/null +++ b/src/app/core/config/models/config-submission-access.model.ts @@ -0,0 +1,42 @@ +import { autoserialize, deserialize, inheritSerialization } from 'cerialize'; +import { typedObject } from '../../cache/builders/build-decorators'; +import { ConfigObject } from './config.model'; +import { AccessesConditionOption } from './config-accesses-conditions-options.model'; +import { SUBMISSION_ACCESSES_TYPE } from './config-type'; +import { HALLink } from '../../shared/hal-link.model'; + +/** + * Class for the configuration describing the item accesses condition + */ +@typedObject +@inheritSerialization(ConfigObject) +export class SubmissionAccessModel extends ConfigObject { + static type = SUBMISSION_ACCESSES_TYPE; + + /** + * A list of available item access conditions + */ + @autoserialize + accessConditionOptions: AccessesConditionOption[]; + + /** + * Boolean that indicates whether the current item must be findable via search or browse. + */ + @autoserialize + discoverable: boolean; + + /** + * Boolean that indicates whether or not the user can change the discoverable flag. + */ + @autoserialize + canChangeDiscoverable: boolean; + + /** + * The links to all related resources returned by the rest api. + */ + @deserialize + _links: { + self: HALLink + }; + +} diff --git a/src/app/core/config/models/config-submission-accesses.model.ts b/src/app/core/config/models/config-submission-accesses.model.ts new file mode 100644 index 00000000000..3f8004928db --- /dev/null +++ b/src/app/core/config/models/config-submission-accesses.model.ts @@ -0,0 +1,10 @@ +import { inheritSerialization } from 'cerialize'; +import { typedObject } from '../../cache/builders/build-decorators'; +import { SUBMISSION_ACCESSES_TYPE } from './config-type'; +import { SubmissionAccessModel } from './config-submission-access.model'; + +@typedObject +@inheritSerialization(SubmissionAccessModel) +export class SubmissionAccessesModel extends SubmissionAccessModel { + static type = SUBMISSION_ACCESSES_TYPE; +} diff --git a/src/app/core/config/models/config-type.ts b/src/app/core/config/models/config-type.ts index 858ff19c91d..19864536f06 100644 --- a/src/app/core/config/models/config-type.ts +++ b/src/app/core/config/models/config-type.ts @@ -15,3 +15,5 @@ export const SUBMISSION_SECTION_TYPE = new ResourceType('submissionsection'); export const SUBMISSION_UPLOADS_TYPE = new ResourceType('submissionuploads'); export const SUBMISSION_UPLOAD_TYPE = new ResourceType('submissionupload'); + +export const SUBMISSION_ACCESSES_TYPE = new ResourceType('submissionaccessoption'); diff --git a/src/app/core/config/submission-accesses-config.service.ts b/src/app/core/config/submission-accesses-config.service.ts new file mode 100644 index 00000000000..de9afc66eab --- /dev/null +++ b/src/app/core/config/submission-accesses-config.service.ts @@ -0,0 +1,42 @@ +import { Injectable } from '@angular/core'; +import { ConfigService } from './config.service'; +import { RequestService } from '../data/request.service'; +import { HALEndpointService } from '../shared/hal-endpoint.service'; +import { ObjectCacheService } from '../cache/object-cache.service'; +import { dataService } from '../cache/builders/build-decorators'; +import { SUBMISSION_ACCESSES_TYPE } from './models/config-type'; +import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { Store } from '@ngrx/store'; +import { CoreState } from '../core.reducers'; +import { NotificationsService } from '../../shared/notifications/notifications.service'; +import { HttpClient } from '@angular/common/http'; +import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service'; +import { ConfigObject } from './models/config.model'; +import { SubmissionAccessesModel } from './models/config-submission-accesses.model'; +import { RemoteData } from '../data/remote-data'; +import { Observable } from 'rxjs'; +import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; + +/** + * Provides methods to retrieve, from REST server, bitstream access conditions configurations applicable during the submission process. + */ +@Injectable() +@dataService(SUBMISSION_ACCESSES_TYPE) +export class SubmissionAccessesConfigService extends ConfigService { + constructor( + protected requestService: RequestService, + protected rdbService: RemoteDataBuildService, + protected store: Store, + protected objectCache: ObjectCacheService, + protected halService: HALEndpointService, + protected notificationsService: NotificationsService, + protected http: HttpClient, + protected comparator: DefaultChangeAnalyzer + ) { + super(requestService, rdbService, null, objectCache, halService, notificationsService, http, comparator, 'submissionaccessoptions'); + } + + findByHref(href: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow): Observable> { + return super.findByHref(href, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow as FollowLinkConfig[]) as Observable>; + } +} diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 2c9a24cb807..8d8a614a899 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -2,11 +2,7 @@ import { CommonModule } from '@angular/common'; import { HttpClient } from '@angular/common/http'; import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core'; -import { - DynamicFormLayoutService, - DynamicFormService, - DynamicFormValidationService -} from '@ng-dynamic-forms/core'; +import { DynamicFormLayoutService, DynamicFormService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; import { EffectsModule } from '@ngrx/effects'; import { Action, StoreConfig, StoreModule } from '@ngrx/store'; @@ -77,6 +73,7 @@ import { MetadataSchema } from './metadata/metadata-schema.model'; import { MetadataService } from './metadata/metadata.service'; import { RegistryService } from './registry/registry.service'; import { RoleService } from './roles/role.service'; +import { FeedbackDataService } from './feedback/feedback-data.service'; import { ApiService } from './services/api.service'; import { ServerResponseService } from './services/server-response.service'; @@ -164,6 +161,7 @@ import { Root } from './data/root.model'; import { SearchConfig } from './shared/search/search-filters/search-config.model'; import { SequenceService } from './shared/sequence.service'; import { GroupDataService } from './eperson/group-data.service'; +import { SubmissionAccessesModel } from './config/models/config-submission-accesses.model'; /** * When not in production, endpoint responses can be mocked for testing purposes @@ -286,7 +284,8 @@ const PROVIDERS = [ VocabularyService, VocabularyTreeviewService, SequenceService, - GroupDataService + GroupDataService, + FeedbackDataService, ]; /** @@ -345,7 +344,8 @@ export const models = Registration, UsageReport, Root, - SearchConfig + SearchConfig, + SubmissionAccessesModel ]; @NgModule({ diff --git a/src/app/core/data/feature-authorization/feature-id.ts b/src/app/core/data/feature-authorization/feature-id.ts index 01a482dc79c..029c75d9cbc 100644 --- a/src/app/core/data/feature-authorization/feature-id.ts +++ b/src/app/core/data/feature-authorization/feature-id.ts @@ -27,4 +27,5 @@ export enum FeatureID { CanDeleteVersion = 'canDeleteVersion', CanCreateVersion = 'canCreateVersion', CanViewUsageStatistics = 'canViewUsageStatistics', + CanSendFeedback = 'canSendFeedback', } diff --git a/src/app/core/feedback/feedback-data.service.spec.ts b/src/app/core/feedback/feedback-data.service.spec.ts new file mode 100644 index 00000000000..4bb5e642c20 --- /dev/null +++ b/src/app/core/feedback/feedback-data.service.spec.ts @@ -0,0 +1,88 @@ +import { FeedbackDataService } from './feedback-data.service'; +import { HALLink } from '../shared/hal-link.model'; +import { Item } from '../shared/item.model'; +import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; +import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { getMockRequestService } from '../../shared/mocks/request.service.mock'; +import { NotificationsService } from '../../shared/notifications/notifications.service'; +import { HttpClient } from '@angular/common/http'; +import { Store } from '@ngrx/store'; +import { CoreState } from '../core.reducers'; +import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; +import { Feedback } from './models/feedback.model'; + +describe('FeedbackDataService', () => { + let service: FeedbackDataService; + let requestService; + let halService; + let rdbService; + let notificationsService; + let http; + let comparator; + let objectCache; + let store; + let item; + let bundleLink; + let bundleHALLink; + + const feedbackPayload = Object.assign(new Feedback(), { + email: 'test@email.com', + message: 'message', + page: '/home' + }); + + + function initTestService(): FeedbackDataService { + bundleLink = '/items/0fdc0cd7-ff8c-433d-b33c-9b56108abc07/bundles'; + bundleHALLink = new HALLink(); + bundleHALLink.href = bundleLink; + item = new Item(); + item._links = { + bundles: bundleHALLink + }; + requestService = getMockRequestService(); + halService = new HALEndpointServiceStub('url') as any; + rdbService = {} as RemoteDataBuildService; + notificationsService = {} as NotificationsService; + http = {} as HttpClient; + comparator = new DSOChangeAnalyzer() as any; + objectCache = { + + addPatch: () => { + /* empty */ + }, + getObjectBySelfLink: () => { + /* empty */ + } + } as any; + store = {} as Store; + return new FeedbackDataService( + requestService, + rdbService, + store, + objectCache, + halService, + notificationsService, + http, + comparator, + ); + } + + + beforeEach(() => { + service = initTestService(); + }); + + + describe('getFeedback', () => { + beforeEach(() => { + spyOn(service, 'getFeedback'); + service.getFeedback('3'); + }); + + it('should call getFeedback with the feedback link', () => { + expect(service.getFeedback).toHaveBeenCalledWith('3'); + }); + }); + +}); diff --git a/src/app/core/feedback/feedback-data.service.ts b/src/app/core/feedback/feedback-data.service.ts new file mode 100644 index 00000000000..8f6d4e3ecf5 --- /dev/null +++ b/src/app/core/feedback/feedback-data.service.ts @@ -0,0 +1,49 @@ +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { DataService } from '../data/data.service'; +import { Feedback } from './models/feedback.model'; +import { FEEDBACK } from './models/feedback.resource-type'; +import { dataService } from '../cache/builders/build-decorators'; +import { RequestService } from '../data/request.service'; +import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { Store } from '@ngrx/store'; +import { ObjectCacheService } from '../cache/object-cache.service'; +import { HALEndpointService } from '../shared/hal-endpoint.service'; +import { NotificationsService } from '../../shared/notifications/notifications.service'; +import { HttpClient } from '@angular/common/http'; +import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; +import { getFirstSucceededRemoteData, getRemoteDataPayload } from '../shared/operators'; + +/** + * Service for checking and managing the feedback + */ +@Injectable() +@dataService(FEEDBACK) +export class FeedbackDataService extends DataService { + protected linkPath = 'feedbacks'; + + constructor( + protected requestService: RequestService, + protected rdbService: RemoteDataBuildService, + protected store: Store, + protected objectCache: ObjectCacheService, + protected halService: HALEndpointService, + protected notificationsService: NotificationsService, + protected http: HttpClient, + protected comparator: DSOChangeAnalyzer, + ) { + super(); + } + + /** + * Get feedback from its id + * @param uuid string the id of the feedback + */ + getFeedback(uuid: string): Observable { + return this.findById(uuid).pipe( + getFirstSucceededRemoteData(), + getRemoteDataPayload(), + ); + } + +} diff --git a/src/app/core/feedback/feedback.guard.ts b/src/app/core/feedback/feedback.guard.ts new file mode 100644 index 00000000000..63353a60ffe --- /dev/null +++ b/src/app/core/feedback/feedback.guard.ts @@ -0,0 +1,20 @@ +import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, UrlTree } from '@angular/router'; +import { Observable } from 'rxjs'; +import { AuthorizationDataService } from '../data/feature-authorization/authorization-data.service'; +import { FeatureID } from '../data/feature-authorization/feature-id'; +import { Injectable } from '@angular/core'; + +/** + * An guard for redirecting users to the feedback page if user is authorized + */ +@Injectable() +export class FeedbackGuard implements CanActivate { + + constructor(private authorizationService: AuthorizationDataService) { + } + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { + return this.authorizationService.isAuthorized(FeatureID.CanSendFeedback); + } + +} diff --git a/src/app/core/feedback/models/feedback.model.ts b/src/app/core/feedback/models/feedback.model.ts new file mode 100644 index 00000000000..fd98affba9b --- /dev/null +++ b/src/app/core/feedback/models/feedback.model.ts @@ -0,0 +1,34 @@ +import { autoserialize, inheritSerialization } from 'cerialize'; +import { typedObject } from '../../cache/builders/build-decorators'; + +import { DSpaceObject } from '../../shared/dspace-object.model'; +import { HALLink } from '../../shared/hal-link.model'; +import { FEEDBACK } from './feedback.resource-type'; + +@typedObject +@inheritSerialization(DSpaceObject) +export class Feedback extends DSpaceObject { + static type = FEEDBACK; + + /** + * The email address + */ + @autoserialize + public email: string; + + /** + * A string representing message the user inserted + */ + @autoserialize + public message: string; + /** + * A string representing the page from which the user came from + */ + @autoserialize + public page: string; + + _links: { + self: HALLink; + }; + +} diff --git a/src/app/core/feedback/models/feedback.resource-type.ts b/src/app/core/feedback/models/feedback.resource-type.ts new file mode 100644 index 00000000000..89b28c6cb04 --- /dev/null +++ b/src/app/core/feedback/models/feedback.resource-type.ts @@ -0,0 +1,9 @@ +import { ResourceType } from '../../shared/resource-type'; + +/** + * The resource type for Feedback + * + * Needs to be in a separate file to prevent circular + * dependencies in webpack. + */ +export const FEEDBACK = new ResourceType('feedback'); diff --git a/src/app/core/submission/models/access-condition.model.ts b/src/app/core/submission/models/access-condition.model.ts new file mode 100644 index 00000000000..5ec5c2c4340 --- /dev/null +++ b/src/app/core/submission/models/access-condition.model.ts @@ -0,0 +1,25 @@ +/** + * An interface to represent an access condition. + */ +export class AccessConditionObject { + + /** + * The access condition id + */ + id: string; + + /** + * The access condition name + */ + name: string; + + /** + * Possible start date of the access condition + */ + startDate: string; + + /** + * Possible end date of the access condition + */ + endDate: string; +} diff --git a/src/app/core/submission/models/submission-accesses.resource-type.ts b/src/app/core/submission/models/submission-accesses.resource-type.ts new file mode 100644 index 00000000000..0634a633373 --- /dev/null +++ b/src/app/core/submission/models/submission-accesses.resource-type.ts @@ -0,0 +1,9 @@ +import { ResourceType } from '../../shared/resource-type'; + +/** + * The resource type for Accesses section + * + * Needs to be in a separate file to prevent circular + * dependencies in webpack. + */ +export const SUBMISSION_ACCESSES = new ResourceType('submissionaccesses'); diff --git a/src/app/core/submission/models/submission-item-access-condition.model.ts b/src/app/core/submission/models/submission-item-access-condition.model.ts new file mode 100644 index 00000000000..60e749b7865 --- /dev/null +++ b/src/app/core/submission/models/submission-item-access-condition.model.ts @@ -0,0 +1,8 @@ +import { AccessConditionObject } from './access-condition.model'; + +/** + * An interface to represent item's access condition. + */ +export class SubmissionItemAccessConditionObject extends AccessConditionObject { + +} diff --git a/src/app/core/submission/models/submission-upload-file-access-condition.model.ts b/src/app/core/submission/models/submission-upload-file-access-condition.model.ts index fa4d9b90620..7be9d6f1f72 100644 --- a/src/app/core/submission/models/submission-upload-file-access-condition.model.ts +++ b/src/app/core/submission/models/submission-upload-file-access-condition.model.ts @@ -1,25 +1,8 @@ +import { AccessConditionObject } from './access-condition.model'; + /** * An interface to represent bitstream's access condition. */ -export class SubmissionUploadFileAccessConditionObject { - - /** - * The access condition id - */ - id: string; - - /** - * The access condition name - */ - name: string; - - /** - * Possible start date of the access condition - */ - startDate: string; +export class SubmissionUploadFileAccessConditionObject extends AccessConditionObject { - /** - * Possible end date of the access condition - */ - endDate: string; } diff --git a/src/app/core/submission/models/workspaceitem-section-accesses.model.ts b/src/app/core/submission/models/workspaceitem-section-accesses.model.ts new file mode 100644 index 00000000000..2d571f67f8e --- /dev/null +++ b/src/app/core/submission/models/workspaceitem-section-accesses.model.ts @@ -0,0 +1,21 @@ +import { SubmissionItemAccessConditionObject } from './submission-item-access-condition.model'; + +/** + * An interface to represent the submission's item accesses condition. + */ +export interface WorkspaceitemSectionAccessesObject { + /** + * The access condition id + */ + id: string; + + /** + * Boolean that indicates whether the current item must be findable via search or browse. + */ + discoverable: boolean; + + /** + * A list of available item access conditions + */ + accessConditions: SubmissionItemAccessConditionObject[]; +} diff --git a/src/app/core/submission/models/workspaceitem-sections.model.ts b/src/app/core/submission/models/workspaceitem-sections.model.ts index 6ff756a3236..084da3f0888 100644 --- a/src/app/core/submission/models/workspaceitem-sections.model.ts +++ b/src/app/core/submission/models/workspaceitem-sections.model.ts @@ -1,3 +1,4 @@ +import { WorkspaceitemSectionAccessesObject } from './workspaceitem-section-accesses.model'; import { WorkspaceitemSectionFormObject } from './workspaceitem-section-form.model'; import { WorkspaceitemSectionLicenseObject } from './workspaceitem-section-license.model'; import { WorkspaceitemSectionUploadObject } from './workspaceitem-section-upload.model'; @@ -19,4 +20,5 @@ export type WorkspaceitemSectionDataType | WorkspaceitemSectionFormObject | WorkspaceitemSectionLicenseObject | WorkspaceitemSectionCcLicenseObject + | WorkspaceitemSectionAccessesObject | string; diff --git a/src/app/footer/footer.component.html b/src/app/footer/footer.component.html index c8ee8a2f5b9..2c1a34ccaef 100644 --- a/src/app/footer/footer.component.html +++ b/src/app/footer/footer.component.html @@ -75,6 +75,10 @@
    Footer Content
    {{ 'footer.link.end-user-agreement' | translate}}
  • +
  • + {{ 'footer.link.feedback' | translate}} +
diff --git a/src/app/info/feedback/feedback-form/feedback-form.component.html b/src/app/info/feedback/feedback-form/feedback-form.component.html new file mode 100644 index 00000000000..02745f2580d --- /dev/null +++ b/src/app/info/feedback/feedback-form/feedback-form.component.html @@ -0,0 +1,45 @@ +
+
+
+

{{ 'info.feedback.head' | translate }}

+

{{ 'info.feedback.info' | translate }}

+
+
+
+ + + {{ 'info.feedback.email_help' | translate }} +
+
+ + + + + +
+
+ + +
+
+ + + +
+
+ + + {{ 'info.feedback.page_help' | translate }} +
+
+
+
+ +
+
+
+
+
+
diff --git a/src/app/info/feedback/feedback-form/feedback-form.component.scss b/src/app/info/feedback/feedback-form/feedback-form.component.scss new file mode 100644 index 00000000000..41d439e5916 --- /dev/null +++ b/src/app/info/feedback/feedback-form/feedback-form.component.scss @@ -0,0 +1,3 @@ +ds-error{ + color:red; +} \ No newline at end of file diff --git a/src/app/info/feedback/feedback-form/feedback-form.component.spec.ts b/src/app/info/feedback/feedback-form/feedback-form.component.spec.ts new file mode 100644 index 00000000000..d6bedc46cf6 --- /dev/null +++ b/src/app/info/feedback/feedback-form/feedback-form.component.spec.ts @@ -0,0 +1,97 @@ +import { EPersonMock } from '../../../shared/testing/eperson.mock'; +import { FeedbackDataService } from '../../../core/feedback/feedback-data.service'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { FeedbackFormComponent } from './feedback-form.component'; +import { TranslateModule } from '@ngx-translate/core'; +import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core'; +import { By } from '@angular/platform-browser'; +import { RouteService } from '../../../core/services/route.service'; +import { routeServiceStub } from '../../../shared/testing/route-service.stub'; +import { FormBuilder } from '@angular/forms'; +import { NotificationsService } from '../../../shared/notifications/notifications.service'; +import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub'; +import { AuthService } from '../../../core/auth/auth.service'; +import { AuthServiceStub } from '../../../shared/testing/auth-service.stub'; +import { of } from 'rxjs'; +import { Feedback } from '../../../core/feedback/models/feedback.model'; +import { Router } from '@angular/router'; +import { RouterMock } from '../../../shared/mocks/router.mock'; +import { NativeWindowService } from '../../../core/services/window.service'; +import { NativeWindowMockFactory } from '../../../shared/mocks/mock-native-window-ref'; + + +describe('FeedbackFormComponent', () => { + let component: FeedbackFormComponent; + let fixture: ComponentFixture; + let de: DebugElement; + const notificationService = new NotificationsServiceStub(); + const feedbackDataServiceStub = jasmine.createSpyObj('feedbackDataService', { + create: of(new Feedback()) + }); + const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { + getAuthenticatedUserFromStore: () => { + return of(EPersonMock); + } + }); + const routerStub = new RouterMock(); + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot()], + declarations: [FeedbackFormComponent], + providers: [ + { provide: RouteService, useValue: routeServiceStub }, + { provide: FormBuilder, useValue: new FormBuilder() }, + { provide: NotificationsService, useValue: notificationService }, + { provide: FeedbackDataService, useValue: feedbackDataServiceStub }, + { provide: AuthService, useValue: authService }, + { provide: NativeWindowService, useFactory: NativeWindowMockFactory }, + { provide: Router, useValue: routerStub }, + ], + schemas: [NO_ERRORS_SCHEMA] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FeedbackFormComponent); + component = fixture.componentInstance; + de = fixture.debugElement; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should have page value', () => { + expect(component.feedbackForm.controls.page.value).toEqual('http://localhost/home'); + }); + + it('should have email if ePerson', () => { + expect(component.feedbackForm.controls.email.value).toEqual('test@test.com'); + }); + + it('should have disabled button', () => { + expect(de.query(By.css('button')).nativeElement.disabled).toBeTrue(); + }); + + describe('when message is inserted', () => { + + beforeEach(() => { + component.feedbackForm.patchValue({ message: 'new feedback' }); + fixture.detectChanges(); + }); + + it('should not have disabled button', () => { + expect(de.query(By.css('button')).nativeElement.disabled).toBeFalse(); + }); + + it('on submit should call createFeedback of feedbackDataServiceStub service', () => { + component.createFeedback(); + fixture.detectChanges(); + expect(feedbackDataServiceStub.create).toHaveBeenCalled(); + }); + }); + + +}); diff --git a/src/app/info/feedback/feedback-form/feedback-form.component.ts b/src/app/info/feedback/feedback-form/feedback-form.component.ts new file mode 100644 index 00000000000..35cdd69cfcd --- /dev/null +++ b/src/app/info/feedback/feedback-form/feedback-form.component.ts @@ -0,0 +1,83 @@ +import { RemoteData } from '../../../core/data/remote-data'; +import { NoContent } from '../../../core/shared/NoContent.model'; +import { FeedbackDataService } from '../../../core/feedback/feedback-data.service'; +import { Component, Inject, OnInit } from '@angular/core'; +import { RouteService } from '../../../core/services/route.service'; +import { FormBuilder, Validators } from '@angular/forms'; +import { NotificationsService } from '../../../shared/notifications/notifications.service'; +import { TranslateService } from '@ngx-translate/core'; +import { AuthService } from '../../../core/auth/auth.service'; +import { EPerson } from '../../../core/eperson/models/eperson.model'; +import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; +import { Router } from '@angular/router'; +import { getHomePageRoute } from '../../../app-routing-paths'; +import { take } from 'rxjs/operators'; +import { NativeWindowRef, NativeWindowService } from '../../../core/services/window.service'; +import { URLCombiner } from '../../../core/url-combiner/url-combiner'; + +@Component({ + selector: 'ds-feedback-form', + templateUrl: './feedback-form.component.html', + styleUrls: ['./feedback-form.component.scss'] +}) +/** + * Component displaying the contents of the Feedback Statement + */ +export class FeedbackFormComponent implements OnInit { + + /** + * Form builder created used from the feedback from + */ + feedbackForm = this.fb.group({ + email: ['', [Validators.required, Validators.pattern('^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$')]], + message: ['', Validators.required], + page: [''], + }); + + constructor( + @Inject(NativeWindowService) protected _window: NativeWindowRef, + public routeService: RouteService, + private fb: FormBuilder, + protected notificationsService: NotificationsService, + protected translate: TranslateService, + private feedbackDataService: FeedbackDataService, + private authService: AuthService, + private router: Router) { + } + + /** + * On init check if user is logged in and use its email if so + */ + ngOnInit() { + + this.authService.getAuthenticatedUserFromStore().pipe(take(1)).subscribe((user: EPerson) => { + if (!!user) { + this.feedbackForm.patchValue({ email: user.email }); + } + }); + + this.routeService.getPreviousUrl().pipe(take(1)).subscribe((url: string) => { + if (!url) { + url = getHomePageRoute(); + } + const relatedUrl = new URLCombiner(this._window.nativeWindow.origin, url).toString(); + this.feedbackForm.patchValue({ page: relatedUrl }); + }); + + } + + /** + * Function to create the feedback from form values + */ + createFeedback(): void { + const url = this.feedbackForm.value.page.replace(this._window.nativeWindow.origin, ''); + this.feedbackDataService.create(this.feedbackForm.value).pipe(getFirstCompletedRemoteData()).subscribe((response: RemoteData) => { + if (response.isSuccess) { + this.notificationsService.success(this.translate.instant('info.feedback.create.success')); + this.feedbackForm.reset(); + this.router.navigateByUrl(url); + } + }); + } + +} diff --git a/src/app/info/feedback/feedback.component.html b/src/app/info/feedback/feedback.component.html new file mode 100644 index 00000000000..210bdcf1d7c --- /dev/null +++ b/src/app/info/feedback/feedback.component.html @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/src/app/info/feedback/feedback.component.scss b/src/app/info/feedback/feedback.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/info/feedback/feedback.component.spec.ts b/src/app/info/feedback/feedback.component.spec.ts new file mode 100644 index 00000000000..810c3b703fc --- /dev/null +++ b/src/app/info/feedback/feedback.component.spec.ts @@ -0,0 +1,27 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { FeedbackComponent } from './feedback.component'; +import { TranslateModule } from '@ngx-translate/core'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; + +describe('FeedbackComponent', () => { + let component: FeedbackComponent; + let fixture: ComponentFixture; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot()], + declarations: [FeedbackComponent], + schemas: [NO_ERRORS_SCHEMA] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FeedbackComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/info/feedback/feedback.component.ts b/src/app/info/feedback/feedback.component.ts new file mode 100644 index 00000000000..3c0924b4de5 --- /dev/null +++ b/src/app/info/feedback/feedback.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'ds-feedback', + templateUrl: './feedback.component.html', + styleUrls: ['./feedback.component.scss'] +}) +/** + * Component displaying the Feedback Statement + */ +export class FeedbackComponent { +} diff --git a/src/app/info/feedback/themed-feedback.component.ts b/src/app/info/feedback/themed-feedback.component.ts new file mode 100644 index 00000000000..68581c32fd7 --- /dev/null +++ b/src/app/info/feedback/themed-feedback.component.ts @@ -0,0 +1,26 @@ +import { Component } from '@angular/core'; +import { ThemedComponent } from '../../shared/theme-support/themed.component'; +import { FeedbackComponent } from './feedback.component'; + +/** + * Themed wrapper for FeedbackComponent + */ +@Component({ + selector: 'ds-themed-feedback', + styleUrls: [], + templateUrl: '../../shared/theme-support/themed.component.html', +}) +export class ThemedFeedbackComponent extends ThemedComponent { + protected getComponentName(): string { + return 'FeedbackComponent'; + } + + protected importThemedComponent(themeName: string): Promise { + return import(`../../../themes/${themeName}/app/info/feedback/feedback.component`); + } + + protected importUnthemedComponent(): Promise { + return import(`./feedback.component`); + } + +} diff --git a/src/app/info/info-routing-paths.ts b/src/app/info/info-routing-paths.ts index 8ec6dbcb8de..a18de2c6111 100644 --- a/src/app/info/info-routing-paths.ts +++ b/src/app/info/info-routing-paths.ts @@ -2,6 +2,7 @@ import { getInfoModulePath } from '../app-routing-paths'; export const END_USER_AGREEMENT_PATH = 'end-user-agreement'; export const PRIVACY_PATH = 'privacy'; +export const FEEDBACK_PATH = 'feedback'; export function getEndUserAgreementPath() { return getSubPath(END_USER_AGREEMENT_PATH); @@ -11,6 +12,10 @@ export function getPrivacyPath() { return getSubPath(PRIVACY_PATH); } +export function getFeedbackPath() { + return getSubPath(FEEDBACK_PATH); +} + function getSubPath(path: string) { return `${getInfoModulePath()}/${path}`; } diff --git a/src/app/info/info-routing.module.ts b/src/app/info/info-routing.module.ts index f76fb47ff01..c746bebaaad 100644 --- a/src/app/info/info-routing.module.ts +++ b/src/app/info/info-routing.module.ts @@ -1,9 +1,12 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver'; -import { PRIVACY_PATH, END_USER_AGREEMENT_PATH } from './info-routing-paths'; +import { PRIVACY_PATH, END_USER_AGREEMENT_PATH, FEEDBACK_PATH } from './info-routing-paths'; import { ThemedEndUserAgreementComponent } from './end-user-agreement/themed-end-user-agreement.component'; import { ThemedPrivacyComponent } from './privacy/themed-privacy.component'; +import { ThemedFeedbackComponent } from './feedback/themed-feedback.component'; +import { FeedbackGuard } from '../core/feedback/feedback.guard'; + @NgModule({ imports: [ @@ -22,6 +25,15 @@ import { ThemedPrivacyComponent } from './privacy/themed-privacy.component'; resolve: { breadcrumb: I18nBreadcrumbResolver }, data: { title: 'info.privacy.title', breadcrumbKey: 'info.privacy' } } + ]), + RouterModule.forChild([ + { + path: FEEDBACK_PATH, + component: ThemedFeedbackComponent, + resolve: { breadcrumb: I18nBreadcrumbResolver }, + data: { title: 'info.feedback.title', breadcrumbKey: 'info.feedback' }, + canActivate: [FeedbackGuard] + } ]) ] }) diff --git a/src/app/info/info.module.ts b/src/app/info/info.module.ts index 84ba5a62dbc..61eee71f3a1 100644 --- a/src/app/info/info.module.ts +++ b/src/app/info/info.module.ts @@ -8,6 +8,11 @@ import { PrivacyComponent } from './privacy/privacy.component'; import { PrivacyContentComponent } from './privacy/privacy-content/privacy-content.component'; import { ThemedEndUserAgreementComponent } from './end-user-agreement/themed-end-user-agreement.component'; import { ThemedPrivacyComponent } from './privacy/themed-privacy.component'; +import { FeedbackComponent } from './feedback/feedback.component'; +import { FeedbackFormComponent } from './feedback/feedback-form/feedback-form.component'; +import { ThemedFeedbackComponent } from './feedback/themed-feedback.component'; +import { FeedbackGuard } from '../core/feedback/feedback.guard'; + const DECLARATIONS = [ EndUserAgreementComponent, @@ -15,21 +20,25 @@ const DECLARATIONS = [ EndUserAgreementContentComponent, PrivacyComponent, PrivacyContentComponent, - ThemedPrivacyComponent + ThemedPrivacyComponent, + FeedbackComponent, + FeedbackFormComponent, + ThemedFeedbackComponent ]; @NgModule({ imports: [ CommonModule, SharedModule, - InfoRoutingModule + InfoRoutingModule, ], declarations: [ ...DECLARATIONS ], exports: [ ...DECLARATIONS - ] + ], + providers: [FeedbackGuard] }) export class InfoModule { } diff --git a/src/app/item-page/edit-item-page/item-delete/item-delete.component.spec.ts b/src/app/item-page/edit-item-page/item-delete/item-delete.component.spec.ts index ea78767df55..2533de32b20 100644 --- a/src/app/item-page/edit-item-page/item-delete/item-delete.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-delete/item-delete.component.spec.ts @@ -3,7 +3,7 @@ import { ItemType } from '../../../core/shared/item-relationships/item-type.mode import { Relationship } from '../../../core/shared/item-relationships/relationship.model'; import { Item } from '../../../core/shared/item.model'; import { RouterStub } from '../../../shared/testing/router.stub'; -import { of as observableOf } from 'rxjs'; +import { of as observableOf, EMPTY } from 'rxjs'; import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; @@ -24,6 +24,8 @@ import { RelationshipType } from '../../../core/shared/item-relationships/relati import { EntityTypeService } from '../../../core/data/entity-type.service'; import { getItemEditRoute } from '../../item-page-routing-paths'; import { createPaginatedList } from '../../../shared/testing/utils.test'; +import { RelationshipTypeService } from '../../../core/data/relationship-type.service'; +import { LinkService } from '../../../core/cache/builders/link.service'; let comp: ItemDeleteComponent; let fixture: ComponentFixture; @@ -40,6 +42,7 @@ let mockItemDataService: ItemDataService; let routeStub; let objectUpdatesServiceStub; let relationshipService; +let linkService; let entityTypeService; let notificationsServiceStub; let typesSelection; @@ -52,7 +55,12 @@ describe('ItemDeleteComponent', () => { uuid: 'fake-uuid', handle: 'fake/handle', lastModified: '2018', - isWithdrawn: true + isWithdrawn: true, + metadata: { + 'dspace.entity.type': [ + { value: 'Person' } + ] + } }); itemType = Object.assign(new ItemType(), { @@ -129,6 +137,12 @@ describe('ItemDeleteComponent', () => { } ); + linkService = jasmine.createSpyObj('linkService', + { + resolveLinks: relationships[0], + } + ); + notificationsServiceStub = new NotificationsServiceStub(); TestBed.configureTestingModule({ @@ -142,6 +156,8 @@ describe('ItemDeleteComponent', () => { { provide: ObjectUpdatesService, useValue: objectUpdatesServiceStub }, { provide: RelationshipService, useValue: relationshipService }, { provide: EntityTypeService, useValue: entityTypeService }, + { provide: RelationshipTypeService, useValue: {} }, + { provide: LinkService, useValue: linkService }, ], schemas: [ CUSTOM_ELEMENTS_SCHEMA ] @@ -166,25 +182,45 @@ describe('ItemDeleteComponent', () => { }); describe('performAction', () => { - it('should call delete function from the ItemDataService', () => { - spyOn(comp, 'notify'); - comp.performAction(); - expect(mockItemDataService.delete) - .toHaveBeenCalledWith(mockItem.id, types.filter((type) => typesSelection[type]).map((type) => type.id)); - expect(comp.notify).toHaveBeenCalled(); + describe(`when there are entitytypes`, () => { + it('should call delete function from the ItemDataService', () => { + spyOn(comp, 'notify'); + comp.performAction(); + expect(mockItemDataService.delete) + .toHaveBeenCalledWith(mockItem.id, types.filter((type) => typesSelection[type]).map((type) => type.id)); + expect(comp.notify).toHaveBeenCalled(); + }); + + it('should call delete function from the ItemDataService with empty types', () => { + + spyOn(comp, 'notify'); + jasmine.getEnv().allowRespy(true); + spyOn(entityTypeService, 'getEntityTypeRelationships').and.returnValue([]); + comp.ngOnInit(); + + comp.performAction(); + + expect(mockItemDataService.delete).toHaveBeenCalledWith(mockItem.id, []); + expect(comp.notify).toHaveBeenCalled(); + }); }); - it('should call delete function from the ItemDataService with empty types', () => { - - spyOn(comp, 'notify'); - jasmine.getEnv().allowRespy(true); - spyOn(entityTypeService, 'getEntityTypeRelationships').and.returnValue([]); - comp.ngOnInit(); - - comp.performAction(); - - expect(mockItemDataService.delete).toHaveBeenCalledWith(mockItem.id, []); - expect(comp.notify).toHaveBeenCalled(); + describe(`when there are no entity types`, () => { + beforeEach(() => { + (comp as any).entityTypeService = jasmine.createSpyObj('entityTypeService', + { + getEntityTypeByLabel: EMPTY, + } + ); + }); + + it('should call delete function from the ItemDataService', () => { + spyOn(comp, 'notify'); + comp.performAction(); + expect(mockItemDataService.delete) + .toHaveBeenCalledWith(mockItem.id, types.filter((type) => typesSelection[type]).map((type) => type.id)); + expect(comp.notify).toHaveBeenCalled(); + }); }); }); describe('notify', () => { diff --git a/src/app/item-page/edit-item-page/item-delete/item-delete.component.ts b/src/app/item-page/edit-item-page/item-delete/item-delete.component.ts index 0249422c8e0..7735fae0eae 100644 --- a/src/app/item-page/edit-item-page/item-delete/item-delete.component.ts +++ b/src/app/item-page/edit-item-page/item-delete/item-delete.component.ts @@ -1,12 +1,14 @@ -import { Component, Input, OnInit } from '@angular/core'; -import {defaultIfEmpty, filter, map, switchMap, take} from 'rxjs/operators'; -import { AbstractSimpleItemActionComponent } from '../simple-item-action/abstract-simple-item-action.component'; +import { Component, Input, OnInit, OnDestroy } from '@angular/core'; +import { defaultIfEmpty, filter, map, switchMap, take } from 'rxjs/operators'; +import { + AbstractSimpleItemActionComponent +} from '../simple-item-action/abstract-simple-item-action.component'; import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { combineLatest as observableCombineLatest, combineLatest, Observable, - of as observableOf + of as observableOf, Subscription } from 'rxjs'; import { RelationshipType } from '../../../core/shared/item-relationships/relationship-type.model'; import { VirtualMetadata } from '../virtual-metadata/virtual-metadata.component'; @@ -32,6 +34,7 @@ import { followLink } from '../../../shared/utils/follow-link-config.model'; import { getItemEditRoute } from '../../item-page-routing-paths'; import { RemoteData } from '../../../core/data/remote-data'; import { NoContent } from '../../../core/shared/NoContent.model'; +import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; @Component({ selector: 'ds-item-delete', @@ -42,7 +45,7 @@ import { NoContent } from '../../../core/shared/NoContent.model'; */ export class ItemDeleteComponent extends AbstractSimpleItemActionComponent - implements OnInit { + implements OnInit, OnDestroy { /** * The current url of this page @@ -60,7 +63,7 @@ export class ItemDeleteComponent * A list of the relationship types for which this item has relations as an observable. * The list doesn't contain duplicates. */ - types$: Observable; + types$: BehaviorSubject = new BehaviorSubject([]); /** * A map which stores the relationships of this item for each type as observable lists @@ -84,6 +87,11 @@ export class ItemDeleteComponent */ public modalRef: NgbModalRef; + /** + * Array to track all subscriptions and unsubscribe them onDestroy + */ + private subs: Subscription[] = []; + constructor(protected route: ActivatedRoute, protected router: Router, protected notificationsService: NotificationsService, @@ -113,8 +121,8 @@ export class ItemDeleteComponent this.url = this.router.url; const label = this.item.firstMetadataValue('dspace.entity.type'); - if (label !== undefined) { - this.types$ = this.entityTypeService.getEntityTypeByLabel(label).pipe( + if (isNotEmpty(label)) { + this.subs.push(this.entityTypeService.getEntityTypeByLabel(label).pipe( getFirstSucceededRemoteData(), getRemoteDataPayload(), switchMap((entityType) => this.entityTypeService.getEntityTypeRelationships(entityType.id)), @@ -138,16 +146,14 @@ export class ItemDeleteComponent ), ); }) - ); - } else { - this.types$ = observableOf([]); + ).subscribe((types: RelationshipType[]) => this.types$.next(types))); } - this.types$.pipe( + this.subs.push(this.types$.pipe( take(1), ).subscribe((types) => this.objectUpdatesService.initialize(this.url, types, this.item.lastModified) - ); + )); } /** @@ -327,7 +333,7 @@ export class ItemDeleteComponent */ performAction() { - this.types$.pipe( + this.subs.push(this.types$.pipe( switchMap((types) => combineLatest( types.map((type) => this.isSelected(type)) @@ -339,13 +345,14 @@ export class ItemDeleteComponent map((selectedTypes) => selectedTypes.map((type) => type.id)), ) ), - ).subscribe((types) => { - this.itemDataService.delete(this.item.id, types).pipe(getFirstCompletedRemoteData()).subscribe( - (rd: RemoteData) => { - this.notify(rd.hasSucceeded); - } - ); - }); + switchMap((types) => + this.itemDataService.delete(this.item.id, types).pipe(getFirstCompletedRemoteData()) + ) + ).subscribe( + (rd: RemoteData) => { + this.notify(rd.hasSucceeded); + } + )); } /** @@ -361,4 +368,14 @@ export class ItemDeleteComponent this.router.navigate([getItemEditRoute(this.item)]); } } + + /** + * Unsubscribe from all subscriptions + */ + ngOnDestroy(): void { + this.subs + .filter((sub) => hasValue(sub)) + .forEach((sub) => sub.unsubscribe()); + } + } diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html index fc115e043a9..55e354ea7ab 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html @@ -14,7 +14,8 @@
-
-
- +
+
+ class="card-img-top full-width" [attr.title]="'search.results.view-result' | translate">
@@ -37,7 +37,7 @@

View + class="lead btn btn-primary viewButton">{{ 'search.results.view-result' | translate}}
diff --git a/src/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.spec.ts b/src/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.spec.ts index ca6614efbc9..57b863a1b15 100644 --- a/src/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.spec.ts +++ b/src/app/shared/object-grid/search-result-grid-element/item-search-result/item/item-search-result-grid-element.component.spec.ts @@ -4,6 +4,7 @@ import { TestBed, waitForAsync } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { Store } from '@ngrx/store'; +import { TranslateModule } from '@ngx-translate/core'; import { Observable, of as observableOf } from 'rxjs'; import { RemoteDataBuildService } from '../../../../../core/cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../../../../../core/cache/object-cache.service'; @@ -99,7 +100,10 @@ export function getEntityGridElementTestComponent(component, searchResultWithMet beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - imports: [NoopAnimationsModule], + imports: [ + NoopAnimationsModule, + TranslateModule.forRoot() + ], declarations: [component, TruncatePipe], providers: [ { provide: TruncatableService, useValue: truncatableServiceStub }, diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index f33a195cfed..2af9d16b0c3 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3408,6 +3408,8 @@ "search.results.empty": "Your search returned no results.", + "search.results.view-result": "View", + "default.search.results.head": "Search Results", From ba40cfe75ae971428890d96c0ac0f484ff39a4fb Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 4 Feb 2022 14:46:31 -0600 Subject: [PATCH 0064/2129] Enhance Search results tests (stabilize). Add more MyDSpace tests, including starting a submission --- cypress.json | 4 +- cypress/integration/my-dspace.spec.ts | 85 ++++++++++++++++++++--- cypress/integration/search-navbar.spec.ts | 4 +- cypress/integration/search-page.spec.ts | 10 ++- cypress/support/index.ts | 2 + 5 files changed, 93 insertions(+), 12 deletions(-) diff --git a/cypress.json b/cypress.json index 549485eb9ef..725f02fcb77 100644 --- a/cypress.json +++ b/cypress.json @@ -16,6 +16,8 @@ "DSPACE_TEST_ADMIN_PASSWORD": "dspace", "DSPACE_TEST_COMMUNITY": "0958c910-2037-42a9-81c7-dca80e3892b4", "DSPACE_TEST_COLLECTION": "282164f5-d325-4740-8dd1-fa4d6d3e7200", - "DSPACE_TEST_ENTITY_PUBLICATION": "e98b0f27-5c19-49a0-960d-eb6ad5287067" + "DSPACE_TEST_COLLECTION_NAME": "Sample Collection", + "DSPACE_TEST_ENTITY_PUBLICATION": "e98b0f27-5c19-49a0-960d-eb6ad5287067", + "DSPACE_TEST_SEARCH_TERM": "test" } } \ No newline at end of file diff --git a/cypress/integration/my-dspace.spec.ts b/cypress/integration/my-dspace.spec.ts index 6348185065d..970255dd5a4 100644 --- a/cypress/integration/my-dspace.spec.ts +++ b/cypress/integration/my-dspace.spec.ts @@ -1,29 +1,52 @@ import { Options } from 'cypress-axe'; -import { TEST_ADMIN_USER, TEST_ADMIN_PASSWORD } from 'cypress/support'; +import { TEST_ADMIN_USER, TEST_ADMIN_PASSWORD, TEST_COLLECTION_NAME } from 'cypress/support'; import { testA11y } from 'cypress/support/utils'; describe('My DSpace page', () => { - it('should display recent submissions', () => { + it('should display recent submissions and pass accessibility tests', () => { cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); - // This is the GET command that will automatically search for recent submissions - cy.intercept('GET', '/server/api/discover/search/objects*').as('search-results'); - cy.visit('/mydspace'); - // Wait for search results to come back from the above GET command - cy.wait('@search-results'); + cy.get('ds-my-dspace-page').should('exist'); // At least one recent submission should be displayed cy.get('ds-item-search-result-list-element-submission').should('be.visible'); + + // Click each filter toggle to open *every* filter + // (As we want to scan filter section for accessibility issues as well) + cy.get('.filter-toggle').click({ multiple: true }); + + // Analyze for accessibility issues + testA11y( + { + include: ['ds-my-dspace-page'], + exclude: [ + ['nouislider'] // Date filter slider is missing ARIA labels. Will be fixed by #1175 + ], + }, + { + rules: { + // Search filters fail these two "moderate" impact rules + 'heading-order': { enabled: false }, + 'landmark-unique': { enabled: false } + } + } as Options + ); }); - it('should pass accessibility tests', () => { + it('should have a working detailed view that passes accessibility tests', () => { cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); + cy.visit('/mydspace'); cy.get('ds-my-dspace-page').should('exist'); + // Click button in sidebar to display detailed view + cy.get('ds-search-sidebar [data-e2e="detail-view"]').click(); + + cy.get('ds-object-detail').should('exist'); + // Analyze for accessibility issues testA11y('ds-my-dspace-page', { @@ -35,4 +58,50 @@ describe('My DSpace page', () => { } as Options ); }); + + + it('should let you start a new submission', () => { + cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); + cy.visit('/mydspace'); + + // Open the New Submission dropdown + cy.get('#dropdownSubmission').click(); + // Click on the "Item" type in that dropdown + cy.get('#entityControlsDropdownMenu button[title="none"]').click(); + + // This should display the (popup window) + cy.get('ds-create-item-parent-selector').should('be.visible'); + + // Type in a known Collection name in the search box + cy.get('ds-authorized-collection-selector input[type="search"]').type(TEST_COLLECTION_NAME); + + // Click on the button matching that known Collection name + cy.get('ds-authorized-collection-selector button[title="' + TEST_COLLECTION_NAME + '"]').click(); + + // New URL should include /workspaceitems, as we've started a new submission + cy.url().should('include', '/workspaceitems'); + + // The Submission edit form tag should be visible + cy.get('ds-submission-edit').should('be.visible'); + + // A Collection menu button should exist & it's value should be the selected collection + cy.get('#collectionControlsMenuButton span').should('have.text', TEST_COLLECTION_NAME); + }); + + it('should let you import from external sources', () => { + cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); + cy.visit('/mydspace'); + + // Open the New Import dropdown + cy.get('#dropdownImport').click(); + // Click on the "Item" type in that dropdown + cy.get('#importControlsDropdownMenu button[title="none"]').click(); + + // New URL should include /import-external, as we've moved to the import page + cy.url().should('include', '/import-external'); + + // The external import searchbox should be visible + cy.get('ds-submission-import-external-searchbar').should('be.visible'); + }); + }); diff --git a/cypress/integration/search-navbar.spec.ts b/cypress/integration/search-navbar.spec.ts index 53e713412e8..3aa8e7248df 100644 --- a/cypress/integration/search-navbar.spec.ts +++ b/cypress/integration/search-navbar.spec.ts @@ -1,3 +1,5 @@ +import { TEST_SEARCH_TERM } from 'cypress/support'; + const page = { fillOutQueryInNavBar(query) { // Click the magnifying glass @@ -15,7 +17,7 @@ const page = { describe('Search from Navigation Bar', () => { // NOTE: these tests currently assume this query will return results! - const query = 'test'; + const query = TEST_SEARCH_TERM; it('should go to search page with correct query if submitted (from home)', () => { cy.visit('/'); diff --git a/cypress/integration/search-page.spec.ts b/cypress/integration/search-page.spec.ts index 07658849526..cbd518b97c8 100644 --- a/cypress/integration/search-page.spec.ts +++ b/cypress/integration/search-page.spec.ts @@ -17,12 +17,15 @@ describe('Search Page', () => { cy.url().should('include', 'query=' + encodeURI(queryString)); }); - it('should pass accessibility tests', () => { + it('should load results and pass accessibility tests', () => { cy.visit('/search'); // tag must be loaded cy.get('ds-search-page').should('exist'); + // At least one search result should be displayed + cy.get('ds-item-search-result-list-element').should('be.visible'); + // Click each filter toggle to open *every* filter // (As we want to scan filter section for accessibility issues as well) cy.get('.filter-toggle').click({ multiple: true }); @@ -45,7 +48,7 @@ describe('Search Page', () => { ); }); - it('should pass accessibility tests in Grid view', () => { + it('should have a working grid view that passes accessibility tests', () => { cy.visit('/search'); // Click button in sidebar to display grid view @@ -54,6 +57,9 @@ describe('Search Page', () => { // tag must be loaded cy.get('ds-search-page').should('exist'); + // At least one grid element (card) should be displayed + cy.get('ds-item-search-result-grid-element').should('be.visible'); + // Analyze for accessibility issues testA11y('ds-search-page', { diff --git a/cypress/support/index.ts b/cypress/support/index.ts index 442f00b9fe8..0213cfe55ba 100644 --- a/cypress/support/index.ts +++ b/cypress/support/index.ts @@ -37,5 +37,7 @@ export const TEST_REST_BASE_URL = Cypress.env('DSPACE_TEST_REST_BASE_URL') || 'h export const TEST_ADMIN_USER = Cypress.env('DSPACE_TEST_ADMIN_USER') || 'dspacedemo+admin@gmail.com'; export const TEST_ADMIN_PASSWORD = Cypress.env('DSPACE_TEST_ADMIN_PASSWORD') || 'dspace'; export const TEST_COLLECTION = Cypress.env('DSPACE_TEST_COLLECTION') || '282164f5-d325-4740-8dd1-fa4d6d3e7200'; +export const TEST_COLLECTION_NAME = Cypress.env('DSPACE_TEST_COLLECTION_NAME') || 'Sample Collection'; export const TEST_COMMUNITY = Cypress.env('DSPACE_TEST_COMMUNITY') || '0958c910-2037-42a9-81c7-dca80e3892b4'; export const TEST_ENTITY_PUBLICATION = Cypress.env('DSPACE_TEST_ENTITY_PUBLICATION') || 'e98b0f27-5c19-49a0-960d-eb6ad5287067'; +export const TEST_SEARCH_TERM = Cypress.env('DSPACE_TEST_SEARCH_TERM') || 'test'; From 106a73f0d3c5bda2c1472591ed7fdd84cf325d2a Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Mon, 7 Feb 2022 17:05:14 -0600 Subject: [PATCH 0065/2129] Improve stability/consistency of e2e tests by visiting blank page between each test --- cypress/support/index.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/cypress/support/index.ts b/cypress/support/index.ts index 0213cfe55ba..cf93b1fefba 100644 --- a/cypress/support/index.ts +++ b/cypress/support/index.ts @@ -27,17 +27,30 @@ before(() => { cy.setCookie('klaro-anonymous', '{%22authentication%22:true%2C%22preferences%22:true%2C%22acknowledgement%22:true%2C%22google-analytics%22:true}'); }); +// For better stability between tests, we visit "about:blank" (i.e. blank page) after each test. +// This ensures any remaining/outstanding XHR requests are killed, so they don't affect the next test. +// Borrowed from: https://glebbahmutov.com/blog/visit-blank-page-between-tests/ +afterEach(() => { + cy.window().then((win) => { + win.location.href = 'about:blank' + }) +}); + // Global constants used in tests // May be overridden in our cypress.json config file using specified environment variables. -// Default UUIDs listed here are all in the Demo Entities Data set available at +// Default values listed here are all valid for the Demo Entities Data set available at // https://github.com/DSpace-Labs/AIP-Files/releases/tag/demo-entities-data // (This is the data set used in our CI environment) export const TEST_REST_BASE_URL = Cypress.env('DSPACE_TEST_REST_BASE_URL') || 'http://localhost:8080'; export const TEST_ADMIN_USER = Cypress.env('DSPACE_TEST_ADMIN_USER') || 'dspacedemo+admin@gmail.com'; export const TEST_ADMIN_PASSWORD = Cypress.env('DSPACE_TEST_ADMIN_PASSWORD') || 'dspace'; +// Community/collection/publication used for view/edit tests export const TEST_COLLECTION = Cypress.env('DSPACE_TEST_COLLECTION') || '282164f5-d325-4740-8dd1-fa4d6d3e7200'; -export const TEST_COLLECTION_NAME = Cypress.env('DSPACE_TEST_COLLECTION_NAME') || 'Sample Collection'; export const TEST_COMMUNITY = Cypress.env('DSPACE_TEST_COMMUNITY') || '0958c910-2037-42a9-81c7-dca80e3892b4'; export const TEST_ENTITY_PUBLICATION = Cypress.env('DSPACE_TEST_ENTITY_PUBLICATION') || 'e98b0f27-5c19-49a0-960d-eb6ad5287067'; +// Search term (should return results) used in search tests export const TEST_SEARCH_TERM = Cypress.env('DSPACE_TEST_SEARCH_TERM') || 'test'; +// Collection used for submission tests +export const TEST_SUBMIT_COLLECTION_NAME = Cypress.env('DSPACE_TEST_SUBMIT_COLLECTION_NAME') || 'Sample Collection'; +export const TEST_SUBMIT_COLLECTION_UUID = Cypress.env('DSPACE_TEST_SUBMIT_COLLECTION_UUID') || '9d8334e9-25d3-4a67-9cea-3dffdef80144'; \ No newline at end of file From 9906d5fec02da8996a654795b2fad2a6c4f14e9e Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Thu, 3 Mar 2022 11:10:35 +0100 Subject: [PATCH 0066/2129] 88082: Revert navigateAction on redirectOn4xx --- src/app/core/shared/operators.ts | 14 +++----------- src/app/register-page/registration.guard.spec.ts | 4 +--- src/app/register-page/registration.guard.ts | 8 ++------ 3 files changed, 6 insertions(+), 20 deletions(-) diff --git a/src/app/core/shared/operators.ts b/src/app/core/shared/operators.ts index c53ca20b1d9..3be04447ab8 100644 --- a/src/app/core/shared/operators.ts +++ b/src/app/core/shared/operators.ts @@ -197,27 +197,19 @@ export const getAllSucceededRemoteListPayload = () => * * @param router The router used to navigate to a new page * @param authService Service to check if the user is authenticated - * @param navigateAction Optional action to take with the Promise returned by navigateByUrl */ -// tslint:disable-next-line:no-empty -export const redirectOn4xx = (router: Router, authService: AuthService, navigateAction?: (nav: boolean) => void) => +export const redirectOn4xx = (router: Router, authService: AuthService) => (source: Observable>): Observable> => source.pipe( withLatestFrom(authService.isAuthenticated()), filter(([rd, isAuthenticated]: [RemoteData, boolean]) => { if (rd.hasFailed) { if (rd.statusCode === 404 || rd.statusCode === 422) { - const promise = router.navigateByUrl(getPageNotFoundRoute(), { skipLocationChange: true }); - if (hasValue(navigateAction)) { - promise.then(navigateAction); - } + router.navigateByUrl(getPageNotFoundRoute(), { skipLocationChange: true }); return false; } else if (rd.statusCode === 403 || rd.statusCode === 401) { if (isAuthenticated) { - const promise = router.navigateByUrl(getForbiddenRoute(), { skipLocationChange: true }); - if (hasValue(navigateAction)) { - promise.then(navigateAction); - } + router.navigateByUrl(getForbiddenRoute(), { skipLocationChange: true }); return false; } else { authService.setRedirectUrl(router.url); diff --git a/src/app/register-page/registration.guard.spec.ts b/src/app/register-page/registration.guard.spec.ts index 0dfa57c7bf0..89eaff7a028 100644 --- a/src/app/register-page/registration.guard.spec.ts +++ b/src/app/register-page/registration.guard.spec.ts @@ -17,7 +17,6 @@ describe('RegistrationGuard', () => { let epersonRegistrationService: EpersonRegistrationService; let router: Router; let authService: AuthService; - let location: Location; let registration: Registration; let registrationRD: RemoteData; @@ -61,9 +60,8 @@ describe('RegistrationGuard', () => { isAuthenticated: observableOf(false), setRedirectUrl: {}, }); - location = jasmine.createSpyObj('location', ['replaceState']); - guard = new RegistrationGuard(epersonRegistrationService, router, authService, location); + guard = new RegistrationGuard(epersonRegistrationService, router, authService); }); describe('canActivate', () => { diff --git a/src/app/register-page/registration.guard.ts b/src/app/register-page/registration.guard.ts index 2be3f3fe530..36bbfa42520 100644 --- a/src/app/register-page/registration.guard.ts +++ b/src/app/register-page/registration.guard.ts @@ -18,8 +18,7 @@ import { Location } from '@angular/common'; export class RegistrationGuard implements CanActivate { constructor(private epersonRegistrationService: EpersonRegistrationService, private router: Router, - private authService: AuthService, - private location: Location) { + private authService: AuthService) { } /** @@ -33,10 +32,7 @@ export class RegistrationGuard implements CanActivate { const token = route.params.token; return this.epersonRegistrationService.searchByToken(token).pipe( getFirstCompletedRemoteData(), - // The replaceState call is an action taken by the Promise returned by navigateByUrl within redirectOn4xx - // It ensures the user stays on the correct URL when redirected to a 4xx page - // See this related issue's comment: https://github.com/angular/angular/issues/16981#issuecomment-549330207 - redirectOn4xx(this.router, this.authService, () => this.location.replaceState(state.url)), + redirectOn4xx(this.router, this.authService), map((rd) => { route.data = { ...route.data, registration: rd }; return rd.hasSucceeded; From 1f808f009685797ab107d51cb40a3733834b27c4 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Fri, 4 Mar 2022 10:19:09 +0100 Subject: [PATCH 0067/2129] 87242: Fix workspace/workflow confusion in spec names --- .../submission/sections/form/section-form.component.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/submission/sections/form/section-form.component.spec.ts b/src/app/submission/sections/form/section-form.component.spec.ts index 09fd6fa991e..7dea922b6b3 100644 --- a/src/app/submission/sections/form/section-form.component.spec.ts +++ b/src/app/submission/sections/form/section-form.component.spec.ts @@ -364,11 +364,11 @@ describe('SubmissionSectionFormComponent test suite', () => { expect((comp as any).inCurrentSubmissionScope('dc.title')).toBe(true); }); - it('should return true for fields scoped to workflow', () => { + it('should return true for fields scoped to workspace', () => { expect((comp as any).inCurrentSubmissionScope('scoped.workspace')).toBe(true); }); - it('should return false for fields scoped to workspace', () => { + it('should return false for fields scoped to workflow', () => { expect((comp as any).inCurrentSubmissionScope('scoped.workflow')).toBe(false); }); }); From fe0e414343aa7c16dc9599ae051d6f0b550908f6 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 8 Feb 2022 15:13:19 -0600 Subject: [PATCH 0068/2129] Upgrade Cypress --- package.json | 2 +- yarn.lock | 46 ++++++++++++++++++++-------------------------- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index 99ab1d2e079..5e98af53dd6 100644 --- a/package.json +++ b/package.json @@ -147,7 +147,7 @@ "cross-env": "^7.0.3", "css-loader": "3.4.0", "cssnano": "^4.1.10", - "cypress": "8.6.0", + "cypress": "9.5.1", "cypress-axe": "^0.13.0", "debug-loader": "^0.0.1", "deep-freeze": "0.0.1", diff --git a/yarn.lock b/yarn.lock index 420ff76478c..c1903163dd1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1451,7 +1451,7 @@ resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== -"@cypress/request@^2.88.6": +"@cypress/request@^2.88.10": version "2.88.10" resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.10.tgz#b66d76b07f860d3a4b8d7a0604d020c662752cce" integrity sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg== @@ -2190,10 +2190,10 @@ "@types/mime" "^1" "@types/node" "*" -"@types/sinonjs__fake-timers@^6.0.2": - version "6.0.4" - resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.4.tgz#0ecc1b9259b76598ef01942f547904ce61a6a77d" - integrity sha512-IFQTJARgMUBF+xVd2b+hIgXWrZEjND3vJtRCvIelcFB5SIXfjV4bOHbHJ0eXKh+0COrBRc8MqteKAz/j88rE0A== +"@types/sinonjs__fake-timers@8.1.1": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" + integrity sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g== "@types/sizzle@^2.3.2": version "2.3.3" @@ -3456,7 +3456,7 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.5.0: +buffer@^5.5.0, buffer@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -3883,15 +3883,14 @@ cli-spinners@^2.5.0: resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== -cli-table3@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.0.tgz#b7b1bc65ca8e7b5cef9124e13dc2b21e2ce4faee" - integrity sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ== +cli-table3@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.1.tgz#36ce9b7af4847f288d3cdd081fbd09bf7bd237b8" + integrity sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA== dependencies: - object-assign "^4.1.0" string-width "^4.2.0" optionalDependencies: - colors "^1.1.2" + colors "1.4.0" cli-truncate@^2.1.0: version "2.1.0" @@ -4951,24 +4950,25 @@ cypress-axe@^0.13.0: resolved "https://registry.yarnpkg.com/cypress-axe/-/cypress-axe-0.13.0.tgz#3234e1a79a27701f2451fcf2f333eb74204c7966" integrity sha512-fCIy7RiDCm7t30U3C99gGwQrUO307EYE1QqXNaf9ToK4DVqW8y5on+0a/kUHMrHdlls2rENF6TN9ZPpPpwLrnw== -cypress@8.6.0: - version "8.6.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-8.6.0.tgz#8d02fa58878b37cfc45bbfce393aa974fa8a8e22" - integrity sha512-F7qEK/6Go5FsqTueR+0wEw2vOVKNgk5847Mys8vsWkzPoEKdxs+7N9Y1dit+zhaZCLtMPyrMwjfA53ZFy+lSww== +cypress@9.5.1: + version "9.5.1" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.5.1.tgz#51162f3688cedf5ffce311b914ef49a7c1ece076" + integrity sha512-H7lUWB3Svr44gz1rNnj941xmdsCljXoJa2cDneAltjI9leKLMQLm30x6jLlpQ730tiVtIbW5HdUmBzPzwzfUQg== dependencies: - "@cypress/request" "^2.88.6" + "@cypress/request" "^2.88.10" "@cypress/xvfb" "^1.2.4" "@types/node" "^14.14.31" - "@types/sinonjs__fake-timers" "^6.0.2" + "@types/sinonjs__fake-timers" "8.1.1" "@types/sizzle" "^2.3.2" arch "^2.2.0" blob-util "^2.0.2" bluebird "^3.7.2" + buffer "^5.6.0" cachedir "^2.3.0" chalk "^4.1.0" check-more-types "^2.24.0" cli-cursor "^3.1.0" - cli-table3 "~0.6.0" + cli-table3 "~0.6.1" commander "^5.1.0" common-tags "^1.8.0" dayjs "^1.10.4" @@ -4991,12 +4991,11 @@ cypress@8.6.0: ospath "^1.2.2" pretty-bytes "^5.6.0" proxy-from-env "1.0.0" - ramda "~0.27.1" request-progress "^3.0.0" + semver "^7.3.2" supports-color "^8.1.1" tmp "~0.2.1" untildify "^4.0.0" - url "^0.11.0" yauzl "^2.10.0" d@1, d@^1.0.1: @@ -11611,11 +11610,6 @@ raf-schd@^4.0.2: resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.3.tgz#5d6c34ef46f8b2a0e880a8fcdb743efc5bfdbc1a" integrity sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ== -ramda@~0.27.1: - version "0.27.1" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.1.tgz#66fc2df3ef873874ffc2da6aa8984658abacf5c9" - integrity sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw== - randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" From 53042179f00d375465bb75ba03d3a7cb289127ed Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 9 Feb 2022 14:03:50 -0600 Subject: [PATCH 0069/2129] Add Submission e2e tests, enhance MyDSpace tests. Minor cleanup to support tests --- cypress.json | 5 +- cypress/integration/my-dspace.spec.ts | 52 +++++-- cypress/integration/submission.spec.ts | 134 ++++++++++++++++++ cypress/support/index.ts | 6 +- .../date-picker/date-picker.component.html | 3 + .../workspaceitem-actions.component.html | 8 +- .../number-picker.component.html | 3 +- .../number-picker.component.spec.ts | 1 + .../number-picker/number-picker.component.ts | 2 +- .../submission-form-footer.component.html | 6 +- 10 files changed, 200 insertions(+), 20 deletions(-) create mode 100644 cypress/integration/submission.spec.ts diff --git a/cypress.json b/cypress.json index 725f02fcb77..fe74ce3ff97 100644 --- a/cypress.json +++ b/cypress.json @@ -16,8 +16,9 @@ "DSPACE_TEST_ADMIN_PASSWORD": "dspace", "DSPACE_TEST_COMMUNITY": "0958c910-2037-42a9-81c7-dca80e3892b4", "DSPACE_TEST_COLLECTION": "282164f5-d325-4740-8dd1-fa4d6d3e7200", - "DSPACE_TEST_COLLECTION_NAME": "Sample Collection", "DSPACE_TEST_ENTITY_PUBLICATION": "e98b0f27-5c19-49a0-960d-eb6ad5287067", - "DSPACE_TEST_SEARCH_TERM": "test" + "DSPACE_TEST_SEARCH_TERM": "test", + "DSPACE_TEST_SUBMIT_COLLECTION_NAME": "Sample Collection", + "DSPACE_TEST_SUBMIT_COLLECTION_UUID": "9d8334e9-25d3-4a67-9cea-3dffdef80144" } } \ No newline at end of file diff --git a/cypress/integration/my-dspace.spec.ts b/cypress/integration/my-dspace.spec.ts index 970255dd5a4..6222d30cfba 100644 --- a/cypress/integration/my-dspace.spec.ts +++ b/cypress/integration/my-dspace.spec.ts @@ -1,5 +1,5 @@ import { Options } from 'cypress-axe'; -import { TEST_ADMIN_USER, TEST_ADMIN_PASSWORD, TEST_COLLECTION_NAME } from 'cypress/support'; +import { TEST_ADMIN_USER, TEST_ADMIN_PASSWORD, TEST_SUBMIT_COLLECTION_NAME } from 'cypress/support'; import { testA11y } from 'cypress/support/utils'; describe('My DSpace page', () => { @@ -37,7 +37,7 @@ describe('My DSpace page', () => { it('should have a working detailed view that passes accessibility tests', () => { cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); - + cy.visit('/mydspace'); cy.get('ds-my-dspace-page').should('exist'); @@ -59,8 +59,8 @@ describe('My DSpace page', () => { ); }); - - it('should let you start a new submission', () => { + // NOTE: Deleting existing submissions is exercised by submission.spec.ts + it('should let you start a new submission & edit in-progress submissions', () => { cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); cy.visit('/mydspace'); @@ -73,10 +73,10 @@ describe('My DSpace page', () => { cy.get('ds-create-item-parent-selector').should('be.visible'); // Type in a known Collection name in the search box - cy.get('ds-authorized-collection-selector input[type="search"]').type(TEST_COLLECTION_NAME); + cy.get('ds-authorized-collection-selector input[type="search"]').type(TEST_SUBMIT_COLLECTION_NAME); // Click on the button matching that known Collection name - cy.get('ds-authorized-collection-selector button[title="' + TEST_COLLECTION_NAME + '"]').click(); + cy.get('ds-authorized-collection-selector button[title="' + TEST_SUBMIT_COLLECTION_NAME + '"]').click(); // New URL should include /workspaceitems, as we've started a new submission cy.url().should('include', '/workspaceitems'); @@ -84,8 +84,44 @@ describe('My DSpace page', () => { // The Submission edit form tag should be visible cy.get('ds-submission-edit').should('be.visible'); - // A Collection menu button should exist & it's value should be the selected collection - cy.get('#collectionControlsMenuButton span').should('have.text', TEST_COLLECTION_NAME); + // A Collection menu button should exist & its value should be the selected collection + cy.get('#collectionControlsMenuButton span').should('have.text', TEST_SUBMIT_COLLECTION_NAME); + + // Now that we've created a submission, we'll test that we can go back and Edit it. + // Get our Submission URL, to parse out the ID of this new submission + cy.location().then(fullUrl => { + // This will be the full path (/workspaceitems/[id]/edit) + const path = fullUrl.pathname; + // Split on the slashes + const subpaths = path.split('/'); + // Part 2 will be the [id] of the submission + const id = subpaths[2]; + + // Go back to the MyDSpace page + cy.visit('/mydspace'); + + // This is the GET command that will actually run the search + cy.intercept('GET', '/server/api/discover/search/objects*').as('search-results'); + // On MyDSpace, find the submission we just created via its ID + cy.get('[data-e2e="search-box"]').type(id); + cy.get('[data-e2e="search-button"]').click(); + + // Wait for search results to come back from the above GET command + cy.wait('@search-results'); + + // Click the Edit button for this in-progress submission + cy.get('#edit_' + id).click(); + + // Should send us back to the submission form + cy.url().should('include', '/workspaceitems/' + id + '/edit'); + + // Discard our new submission by clicking Discard in Submission form & confirming + cy.get('button#discard').click(); + cy.get('button#discard_submit').click(); + + // Discarding should send us back to MyDSpace + cy.url().should('include', '/mydspace'); + }); }); it('should let you import from external sources', () => { diff --git a/cypress/integration/submission.spec.ts b/cypress/integration/submission.spec.ts new file mode 100644 index 00000000000..9469ee35e13 --- /dev/null +++ b/cypress/integration/submission.spec.ts @@ -0,0 +1,134 @@ +import { Options } from 'cypress-axe'; +import { TEST_ADMIN_USER, TEST_ADMIN_PASSWORD, TEST_SUBMIT_COLLECTION_NAME, TEST_SUBMIT_COLLECTION_UUID } from 'cypress/support'; +import { testA11y } from 'cypress/support/utils'; + +describe('New Submission page', () => { + // NOTE: We already test that new submissions can be started from MyDSpace in my-dspace.spec.ts + + it('should create a new submission when using /submit path', () => { + cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); + + // Test that calling /submit with collection & entityType will create a new submission + cy.visit('/submit?collection=' + TEST_SUBMIT_COLLECTION_UUID + '&entityType=none'); + + // Should redirect to /workspaceitems, as we've started a new submission + cy.url().should('include', '/workspaceitems'); + + // The Submission edit form tag should be visible + cy.get('ds-submission-edit').should('be.visible'); + + // A Collection menu button should exist & it's value should be the selected collection + cy.get('#collectionControlsMenuButton span').should('have.text', TEST_SUBMIT_COLLECTION_NAME); + + // 4 sections should be visible by default + cy.get('div#section_traditionalpageone').should('be.visible'); + cy.get('div#section_traditionalpagetwo').should('be.visible'); + cy.get('div#section_upload').should('be.visible'); + cy.get('div#section_license').should('be.visible'); + + // Discard button should work + // Clicking it will display a confirmation, which we will confirm with another click + cy.get('button#discard').click(); + cy.get('button#discard_submit').click(); + }); + + it('should block submission & show errors if required fields are missing', () => { + cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); + + // Create a new submission + cy.visit('/submit?collection=' + TEST_SUBMIT_COLLECTION_UUID + '&entityType=none'); + + // Attempt an immediate deposit without filling out any fields + cy.get('button#deposit').click(); + + // A warning alert should display. + cy.get('ds-notification div.alert-warning').should('be.visible'); + + // First section should have an exclamation error in the header + // (as it has required fields) + cy.get('div#traditionalpageone-header i.fa-exclamation-circle').should('be.visible'); + + // Title field should have class "is-invalid" applied, as it's required + cy.get('input#dc_title').should('have.class', 'is-invalid'); + + // Date Year field should also have "is-valid" class + cy.get('input#dc_date_issued_year').should('have.class', 'is-invalid'); + + // FINALLY, cleanup after ourselves. This also exercises the MyDSpace delete button. + // Get our Submission URL, to parse out the ID of this submission + cy.location().then(fullUrl => { + // This will be the full path (/workspaceitems/[id]/edit) + const path = fullUrl.pathname; + // Split on the slashes + const subpaths = path.split('/'); + // Part 2 will be the [id] of the submission + const id = subpaths[2]; + + // Even though form is incomplete, the "Save for Later" button should still work + cy.get('button#saveForLater').click(); + + // "Save for Later" should send us to MyDSpace + cy.url().should('include', '/mydspace'); + + // A success alert should be visible + cy.get('ds-notification div.alert-success').should('be.visible'); + // Now, dismiss any open alert boxes (may be multiple, as tests run quickly) + cy.get('[data-dismiss="alert"]').click({multiple: true}); + + // This is the GET command that will actually run the search + cy.intercept('GET', '/server/api/discover/search/objects*').as('search-results'); + // On MyDSpace, find the submission we just saved via its ID + cy.get('[data-e2e="search-box"]').type(id); + cy.get('[data-e2e="search-button"]').click(); + + // Wait for search results to come back from the above GET command + cy.wait('@search-results'); + + // Delete our created submission & confirm deletion + cy.get('button#delete_' + id).click(); + cy.get('button#delete_confirm').click(); + }); + }); + + it('should allow for deposit if all required fields completed & file uploaded', () => { + cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); + + // Create a new submission + cy.visit('/submit?collection=' + TEST_SUBMIT_COLLECTION_UUID + '&entityType=none'); + + // Fill out all required fields (Title, Date) + cy.get('input#dc_title').type('DSpace logo uploaded via e2e tests'); + cy.get('input#dc_date_issued_year').type('2022'); + + // Confirm the required license by checking checkbox + // (NOTE: requires "force:true" cause Cypress claims this checkbox is covered by its own ) + cy.get('input#granted').check( {force: true} ); + + // Before using Cypress drag & drop, we have to manually trigger the "dragover" event. + // This ensures our UI displays the dropzone that covers the entire submission page. + // (For some reason Cypress drag & drop doesn't trigger this even itself & upload won't work without this trigger) + cy.get('ds-uploader').trigger('dragover'); + + // This is the POST command that will upload the file + cy.intercept('POST', '/server/api/submission/workspaceitems/*').as('upload'); + + // Upload our DSpace logo via drag & drop onto submission form + // cy.get('div#section_upload') + cy.get('div.ds-document-drop-zone').selectFile('src/assets/images/dspace-logo.png', { + action: 'drag-drop' + }); + + // Wait for upload to complete before proceeding + cy.wait('@upload'); + // Close the upload success notice + cy.get('[data-dismiss="alert"]').click({multiple: true}); + + // Wait for deposit button to not be disabled & click it. + cy.get('button#deposit').should('not.be.disabled').click(); + + // No warnings should exist. Instead, just successful deposit alert is displayed + cy.get('ds-notification div.alert-warning').should('not.exist'); + cy.get('ds-notification div.alert-success').should('be.visible'); + }); + +}); diff --git a/cypress/support/index.ts b/cypress/support/index.ts index cf93b1fefba..a56ace7d38e 100644 --- a/cypress/support/index.ts +++ b/cypress/support/index.ts @@ -32,8 +32,8 @@ before(() => { // Borrowed from: https://glebbahmutov.com/blog/visit-blank-page-between-tests/ afterEach(() => { cy.window().then((win) => { - win.location.href = 'about:blank' - }) + win.location.href = 'about:blank'; + }); }); @@ -53,4 +53,4 @@ export const TEST_ENTITY_PUBLICATION = Cypress.env('DSPACE_TEST_ENTITY_PUBLICATI export const TEST_SEARCH_TERM = Cypress.env('DSPACE_TEST_SEARCH_TERM') || 'test'; // Collection used for submission tests export const TEST_SUBMIT_COLLECTION_NAME = Cypress.env('DSPACE_TEST_SUBMIT_COLLECTION_NAME') || 'Sample Collection'; -export const TEST_SUBMIT_COLLECTION_UUID = Cypress.env('DSPACE_TEST_SUBMIT_COLLECTION_UUID') || '9d8334e9-25d3-4a67-9cea-3dffdef80144'; \ No newline at end of file +export const TEST_SUBMIT_COLLECTION_UUID = Cypress.env('DSPACE_TEST_SUBMIT_COLLECTION_UUID') || '9d8334e9-25d3-4a67-9cea-3dffdef80144'; diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/date-picker/date-picker.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/models/date-picker/date-picker.component.html index d5421a254f7..1046dd6b2d3 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/date-picker/date-picker.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/date-picker/date-picker.component.html @@ -5,6 +5,7 @@ @@ -6,6 +7,7 @@
@@ -24,7 +26,7 @@
diff --git a/src/app/shared/number-picker/number-picker.component.html b/src/app/shared/number-picker/number-picker.component.html index 58b6def50b0..9b2ef989256 100644 --- a/src/app/shared/number-picker/number-picker.component.html +++ b/src/app/shared/number-picker/number-picker.component.html @@ -9,6 +9,7 @@ Increment
From 8c865b758eba2847056154a3bb20fb38a5bb2523 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 9 Feb 2022 15:07:08 -0600 Subject: [PATCH 0070/2129] Fix bugs / stability issues with search e2e tests --- cypress/integration/search-navbar.spec.ts | 6 +++--- cypress/integration/search-page.spec.ts | 18 +++++++----------- .../object-grid/object-grid.component.html | 2 +- .../object-list/object-list.component.html | 2 +- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/cypress/integration/search-navbar.spec.ts b/cypress/integration/search-navbar.spec.ts index 3aa8e7248df..211b4836b1e 100644 --- a/cypress/integration/search-navbar.spec.ts +++ b/cypress/integration/search-navbar.spec.ts @@ -31,7 +31,7 @@ describe('Search from Navigation Bar', () => { // Wait for search results to come back from the above GET command cy.wait('@search-results'); // At least one search result should be displayed - cy.get('ds-item-search-result-list-element').should('be.visible'); + cy.get('[data-e2e="list-object"]').should('be.visible'); }); it('should go to search page with correct query if submitted (from search)', () => { @@ -46,7 +46,7 @@ describe('Search from Navigation Bar', () => { // Wait for search results to come back from the above GET command cy.wait('@search-results'); // At least one search result should be displayed - cy.get('ds-item-search-result-list-element').should('be.visible'); + cy.get('[data-e2e="list-object"]').should('be.visible'); }); it('should allow user to also submit query by clicking icon', () => { @@ -61,6 +61,6 @@ describe('Search from Navigation Bar', () => { // Wait for search results to come back from the above GET command cy.wait('@search-results'); // At least one search result should be displayed - cy.get('ds-item-search-result-list-element').should('be.visible'); + cy.get('[data-e2e="list-object"]').should('be.visible'); }); }); diff --git a/cypress/integration/search-page.spec.ts b/cypress/integration/search-page.spec.ts index cbd518b97c8..981c9365aaa 100644 --- a/cypress/integration/search-page.spec.ts +++ b/cypress/integration/search-page.spec.ts @@ -1,13 +1,8 @@ import { Options } from 'cypress-axe'; +import { TEST_SEARCH_TERM } from 'cypress/support'; import { testA11y } from 'cypress/support/utils'; describe('Search Page', () => { - it('should contain query value when navigating to page with query parameter', () => { - const queryString = 'test query'; - cy.visit('/search?query=' + queryString); - cy.get('[data-e2e="search-box"]').should('have.value', queryString); - }); - it('should redirect to the correct url when query was set and submit button was triggered', () => { const queryString = 'Another interesting query string'; cy.visit('/search'); @@ -18,13 +13,14 @@ describe('Search Page', () => { }); it('should load results and pass accessibility tests', () => { - cy.visit('/search'); + cy.visit('/search?query=' + TEST_SEARCH_TERM); + cy.get('[data-e2e="search-box"]').should('have.value', TEST_SEARCH_TERM); // tag must be loaded cy.get('ds-search-page').should('exist'); // At least one search result should be displayed - cy.get('ds-item-search-result-list-element').should('be.visible'); + cy.get('[data-e2e="list-object"]').should('be.visible'); // Click each filter toggle to open *every* filter // (As we want to scan filter section for accessibility issues as well) @@ -49,7 +45,7 @@ describe('Search Page', () => { }); it('should have a working grid view that passes accessibility tests', () => { - cy.visit('/search'); + cy.visit('/search?query=' + TEST_SEARCH_TERM); // Click button in sidebar to display grid view cy.get('ds-search-sidebar [data-e2e="grid-view"]').click(); @@ -57,8 +53,8 @@ describe('Search Page', () => { // tag must be loaded cy.get('ds-search-page').should('exist'); - // At least one grid element (card) should be displayed - cy.get('ds-item-search-result-grid-element').should('be.visible'); + // At least one grid object (card) should be displayed + cy.get('[data-e2e="grid-object"]').should('be.visible'); // Analyze for accessibility issues testA11y('ds-search-page', diff --git a/src/app/shared/object-grid/object-grid.component.html b/src/app/shared/object-grid/object-grid.component.html index 0afd623d868..296f190d2d3 100644 --- a/src/app/shared/object-grid/object-grid.component.html +++ b/src/app/shared/object-grid/object-grid.component.html @@ -13,7 +13,7 @@ (paginationChange)="onPaginationChange($event)">
-
+
diff --git a/src/app/shared/object-list/object-list.component.html b/src/app/shared/object-list/object-list.component.html index 331ff1cb288..53a62ca1f5e 100644 --- a/src/app/shared/object-list/object-list.component.html +++ b/src/app/shared/object-list/object-list.component.html @@ -12,7 +12,7 @@ (sortFieldChange)="onSortFieldChange($event)" (paginationChange)="onPaginationChange($event)">
    -
  • +
  • Date: Mon, 14 Feb 2022 11:28:08 -0600 Subject: [PATCH 0071/2129] Update submission tests to use Demo Submitter. Switch Docker scripts to use updated `dspace7-entities-data.sql` which now includes demo in-progress submissions --- cypress.json | 4 +++- cypress/integration/my-dspace.spec.ts | 22 ++++++++++++++-------- cypress/integration/submission.spec.ts | 10 +++++----- cypress/support/index.ts | 2 ++ docker/cli.assetstore.yml | 2 +- docker/db.entities.yml | 2 +- docker/docker-compose-ci.yml | 2 +- 7 files changed, 27 insertions(+), 17 deletions(-) diff --git a/cypress.json b/cypress.json index fe74ce3ff97..c0b5a56a15b 100644 --- a/cypress.json +++ b/cypress.json @@ -19,6 +19,8 @@ "DSPACE_TEST_ENTITY_PUBLICATION": "e98b0f27-5c19-49a0-960d-eb6ad5287067", "DSPACE_TEST_SEARCH_TERM": "test", "DSPACE_TEST_SUBMIT_COLLECTION_NAME": "Sample Collection", - "DSPACE_TEST_SUBMIT_COLLECTION_UUID": "9d8334e9-25d3-4a67-9cea-3dffdef80144" + "DSPACE_TEST_SUBMIT_COLLECTION_UUID": "9d8334e9-25d3-4a67-9cea-3dffdef80144", + "DSPACE_TEST_SUBMIT_USER": "dspacedemo+submit@gmail.com", + "DSPACE_TEST_SUBMIT_USER_PASSWORD": "dspace" } } \ No newline at end of file diff --git a/cypress/integration/my-dspace.spec.ts b/cypress/integration/my-dspace.spec.ts index 6222d30cfba..da78ff8da67 100644 --- a/cypress/integration/my-dspace.spec.ts +++ b/cypress/integration/my-dspace.spec.ts @@ -1,17 +1,17 @@ import { Options } from 'cypress-axe'; -import { TEST_ADMIN_USER, TEST_ADMIN_PASSWORD, TEST_SUBMIT_COLLECTION_NAME } from 'cypress/support'; +import { TEST_SUBMIT_USER, TEST_SUBMIT_USER_PASSWORD, TEST_SUBMIT_COLLECTION_NAME } from 'cypress/support'; import { testA11y } from 'cypress/support/utils'; describe('My DSpace page', () => { it('should display recent submissions and pass accessibility tests', () => { - cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); + cy.login(TEST_SUBMIT_USER, TEST_SUBMIT_USER_PASSWORD); cy.visit('/mydspace'); cy.get('ds-my-dspace-page').should('exist'); // At least one recent submission should be displayed - cy.get('ds-item-search-result-list-element-submission').should('be.visible'); + cy.get('[data-e2e="list-object"]').should('be.visible'); // Click each filter toggle to open *every* filter // (As we want to scan filter section for accessibility issues as well) @@ -36,7 +36,7 @@ describe('My DSpace page', () => { }); it('should have a working detailed view that passes accessibility tests', () => { - cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); + cy.login(TEST_SUBMIT_USER, TEST_SUBMIT_USER_PASSWORD); cy.visit('/mydspace'); @@ -61,7 +61,7 @@ describe('My DSpace page', () => { // NOTE: Deleting existing submissions is exercised by submission.spec.ts it('should let you start a new submission & edit in-progress submissions', () => { - cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); + cy.login(TEST_SUBMIT_USER, TEST_SUBMIT_USER_PASSWORD); cy.visit('/mydspace'); // Open the New Submission dropdown @@ -97,8 +97,14 @@ describe('My DSpace page', () => { // Part 2 will be the [id] of the submission const id = subpaths[2]; - // Go back to the MyDSpace page - cy.visit('/mydspace'); + // Click the "Save for Later" button to save this submission + cy.get('button#saveForLater').click(); + + // "Save for Later" should send us to MyDSpace + cy.url().should('include', '/mydspace'); + + // Close any open notifications, to make sure they don't get in the way of next steps + cy.get('[data-dismiss="alert"]').click({multiple: true}); // This is the GET command that will actually run the search cy.intercept('GET', '/server/api/discover/search/objects*').as('search-results'); @@ -125,7 +131,7 @@ describe('My DSpace page', () => { }); it('should let you import from external sources', () => { - cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); + cy.login(TEST_SUBMIT_USER, TEST_SUBMIT_USER_PASSWORD); cy.visit('/mydspace'); // Open the New Import dropdown diff --git a/cypress/integration/submission.spec.ts b/cypress/integration/submission.spec.ts index 9469ee35e13..4c7758f8d63 100644 --- a/cypress/integration/submission.spec.ts +++ b/cypress/integration/submission.spec.ts @@ -1,12 +1,12 @@ import { Options } from 'cypress-axe'; -import { TEST_ADMIN_USER, TEST_ADMIN_PASSWORD, TEST_SUBMIT_COLLECTION_NAME, TEST_SUBMIT_COLLECTION_UUID } from 'cypress/support'; +import { TEST_SUBMIT_USER, TEST_SUBMIT_USER_PASSWORD, TEST_SUBMIT_COLLECTION_NAME, TEST_SUBMIT_COLLECTION_UUID } from 'cypress/support'; import { testA11y } from 'cypress/support/utils'; describe('New Submission page', () => { // NOTE: We already test that new submissions can be started from MyDSpace in my-dspace.spec.ts - it('should create a new submission when using /submit path', () => { - cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); + it('should create a new submission when using /submit path & pass accessibility', () => { + cy.login(TEST_SUBMIT_USER, TEST_SUBMIT_USER_PASSWORD); // Test that calling /submit with collection & entityType will create a new submission cy.visit('/submit?collection=' + TEST_SUBMIT_COLLECTION_UUID + '&entityType=none'); @@ -33,7 +33,7 @@ describe('New Submission page', () => { }); it('should block submission & show errors if required fields are missing', () => { - cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); + cy.login(TEST_SUBMIT_USER, TEST_SUBMIT_USER_PASSWORD); // Create a new submission cy.visit('/submit?collection=' + TEST_SUBMIT_COLLECTION_UUID + '&entityType=none'); @@ -91,7 +91,7 @@ describe('New Submission page', () => { }); it('should allow for deposit if all required fields completed & file uploaded', () => { - cy.login(TEST_ADMIN_USER, TEST_ADMIN_PASSWORD); + cy.login(TEST_SUBMIT_USER, TEST_SUBMIT_USER_PASSWORD); // Create a new submission cy.visit('/submit?collection=' + TEST_SUBMIT_COLLECTION_UUID + '&entityType=none'); diff --git a/cypress/support/index.ts b/cypress/support/index.ts index a56ace7d38e..8edfdedde33 100644 --- a/cypress/support/index.ts +++ b/cypress/support/index.ts @@ -54,3 +54,5 @@ export const TEST_SEARCH_TERM = Cypress.env('DSPACE_TEST_SEARCH_TERM') || 'test' // Collection used for submission tests export const TEST_SUBMIT_COLLECTION_NAME = Cypress.env('DSPACE_TEST_SUBMIT_COLLECTION_NAME') || 'Sample Collection'; export const TEST_SUBMIT_COLLECTION_UUID = Cypress.env('DSPACE_TEST_SUBMIT_COLLECTION_UUID') || '9d8334e9-25d3-4a67-9cea-3dffdef80144'; +export const TEST_SUBMIT_USER = Cypress.env('DSPACE_TEST_SUBMIT_USER') || 'dspacedemo+submit@gmail.com'; +export const TEST_SUBMIT_USER_PASSWORD = Cypress.env('DSPACE_TEST_SUBMIT_USER_PASSWORD') || 'dspace'; diff --git a/docker/cli.assetstore.yml b/docker/cli.assetstore.yml index c2846286d78..40e4974c7c7 100644 --- a/docker/cli.assetstore.yml +++ b/docker/cli.assetstore.yml @@ -35,6 +35,6 @@ services: tar xvfz /tmp/assetstore.tar.gz fi - /dspace/bin/dspace index-discovery + /dspace/bin/dspace index-discovery -b /dspace/bin/dspace oai import /dspace/bin/dspace oai clean-cache diff --git a/docker/db.entities.yml b/docker/db.entities.yml index 818d14877cb..d1dfdf4a26c 100644 --- a/docker/db.entities.yml +++ b/docker/db.entities.yml @@ -20,7 +20,7 @@ services: environment: # This LOADSQL should be kept in sync with the URL in DSpace/DSpace # This SQL is available from https://github.com/DSpace-Labs/AIP-Files/releases/tag/demo-entities-data - - LOADSQL=https://github.com/DSpace-Labs/AIP-Files/releases/download/demo-entities-data/dspace7-entities-2021-04-14.sql + - LOADSQL=https://github.com/DSpace-Labs/AIP-Files/releases/download/demo-entities-data/dspace7-entities-data.sql dspace: ### OVERRIDE default 'entrypoint' in 'docker-compose-rest.yml' #### # Ensure that the database is ready BEFORE starting tomcat diff --git a/docker/docker-compose-ci.yml b/docker/docker-compose-ci.yml index a895314a17e..3bd8f526303 100644 --- a/docker/docker-compose-ci.yml +++ b/docker/docker-compose-ci.yml @@ -63,7 +63,7 @@ services: # This LOADSQL should be kept in sync with the LOADSQL in # https://github.com/DSpace/DSpace/blob/main/dspace/src/main/docker-compose/db.entities.yml # This SQL is available from https://github.com/DSpace-Labs/AIP-Files/releases/tag/demo-entities-data - LOADSQL: https://github.com/DSpace-Labs/AIP-Files/releases/download/demo-entities-data/dspace7-entities-2021-04-14.sql + LOADSQL: https://github.com/DSpace-Labs/AIP-Files/releases/download/demo-entities-data/dspace7-entities-data.sql PGDATA: /pgdata image: dspace/dspace-postgres-pgcrypto:loadsql networks: From 852da27c2c9e0ac8bebe0a4310d54e55bd934020 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 4 Mar 2022 12:49:55 -0600 Subject: [PATCH 0072/2129] Update Cypress to read REST API URL dynamically from config.json --- cypress.json | 1 - cypress/support/commands.ts | 69 +++++++++++++++++++++++-------------- cypress/support/index.ts | 7 +++- 3 files changed, 50 insertions(+), 27 deletions(-) diff --git a/cypress.json b/cypress.json index c0b5a56a15b..80358eb6dde 100644 --- a/cypress.json +++ b/cypress.json @@ -11,7 +11,6 @@ "openMode": 0 }, "env": { - "DSPACE_TEST_REST_BASE_URL": "http://localhost:8080", "DSPACE_TEST_ADMIN_USER": "dspacedemo+admin@gmail.com", "DSPACE_TEST_ADMIN_PASSWORD": "dspace", "DSPACE_TEST_COMMUNITY": "0958c910-2037-42a9-81c7-dca80e3892b4", diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index dcac5aaaac1..d66e1ef0bd0 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -4,7 +4,7 @@ // *********************************************** import { AuthTokenInfo, TOKENITEM } from 'src/app/core/auth/models/auth-token-info.model'; -import { TEST_REST_BASE_URL } from '.'; +import { FALLBACK_TEST_REST_BASE_URL } from '.'; // Declare Cypress namespace to help with Intellisense & code completion in IDEs // ALL custom commands MUST be listed here for code completion to work @@ -30,34 +30,53 @@ declare global { * @param password password to login as */ function login(email: string, password: string): void { - // To login via REST, first we have to do a GET to obtain a valid CSRF token - cy.request( TEST_REST_BASE_URL + '/server/api/authn/status' ) - .then((response) => { - // We should receive a CSRF token returned in a response header - expect(response.headers).to.have.property('dspace-xsrf-token'); - const csrfToken = response.headers['dspace-xsrf-token']; + // Cypress doesn't have access to the running application in Node.js. + // So, it's not possible to inject or load the AppConfig or environment of the Angular UI. + // Instead, we'll read our running application's config.json, which contains the configs & + // is regenerated at runtime each time the Angular UI application starts up. + cy.readFile('./src/assets/config.json').then((str) => { + // Parse JSON file into a JSON object + const config = JSON.parse(JSON.stringify(str)); - // Now, send login POST request including that CSRF token - cy.request({ - method: 'POST', - url: TEST_REST_BASE_URL + '/server/api/authn/login', - headers: { 'X-XSRF-TOKEN' : csrfToken}, - form: true, // indicates the body should be form urlencoded - body: { user: email, password: password } - }).then((resp) => { - // We expect a successful login - expect(resp.status).to.eq(200); - // We expect to have a valid authorization header returned (with our auth token) - expect(resp.headers).to.have.property('authorization'); + // Find the URL of our REST API. Have a fallback ready, just in case 'rest.baseUrl' cannot be found. + let baseRestUrl = FALLBACK_TEST_REST_BASE_URL; + if (!config.rest.baseUrl) { + console.warn("Could not load 'rest.baseUrl' from config.json. Falling back to " + FALLBACK_TEST_REST_BASE_URL); + } else { + console.log("Found 'rest.baseUrl' in config.json. Using this REST API for login: " + config.rest.baseUrl); + baseRestUrl = config.rest.baseUrl; + } + + // To login via REST, first we have to do a GET to obtain a valid CSRF token + cy.request( baseRestUrl + '/api/authn/status' ) + .then((response) => { + // We should receive a CSRF token returned in a response header + expect(response.headers).to.have.property('dspace-xsrf-token'); + const csrfToken = response.headers['dspace-xsrf-token']; - // Initialize our AuthTokenInfo object from the authorization header. - const authheader = resp.headers.authorization as string; - const authinfo: AuthTokenInfo = new AuthTokenInfo(authheader); + // Now, send login POST request including that CSRF token + cy.request({ + method: 'POST', + url: baseRestUrl + '/api/authn/login', + headers: { 'X-XSRF-TOKEN' : csrfToken}, + form: true, // indicates the body should be form urlencoded + body: { user: email, password: password } + }).then((resp) => { + // We expect a successful login + expect(resp.status).to.eq(200); + // We expect to have a valid authorization header returned (with our auth token) + expect(resp.headers).to.have.property('authorization'); - // Save our AuthTokenInfo object to our dsAuthInfo UI cookie - // This ensures the UI will recognize we are logged in on next "visit()" - cy.setCookie(TOKENITEM, JSON.stringify(authinfo)); + // Initialize our AuthTokenInfo object from the authorization header. + const authheader = resp.headers.authorization as string; + const authinfo: AuthTokenInfo = new AuthTokenInfo(authheader); + + // Save our AuthTokenInfo object to our dsAuthInfo UI cookie + // This ensures the UI will recognize we are logged in on next "visit()" + cy.setCookie(TOKENITEM, JSON.stringify(authinfo)); + }); }); + }); } // Add as a Cypress command (i.e. assign to 'cy.login') diff --git a/cypress/support/index.ts b/cypress/support/index.ts index 8edfdedde33..d9b6409a0d9 100644 --- a/cypress/support/index.ts +++ b/cypress/support/index.ts @@ -42,7 +42,12 @@ afterEach(() => { // Default values listed here are all valid for the Demo Entities Data set available at // https://github.com/DSpace-Labs/AIP-Files/releases/tag/demo-entities-data // (This is the data set used in our CI environment) -export const TEST_REST_BASE_URL = Cypress.env('DSPACE_TEST_REST_BASE_URL') || 'http://localhost:8080'; + +// NOTE: FALLBACK_TEST_REST_BASE_URL is only used if Cypress cannot read the REST API BaseURL +// from the Angular UI's config.json. See 'getBaseRESTUrl()' in commands.ts +export const FALLBACK_TEST_REST_BASE_URL = 'http://localhost:8080/server'; + +// Admin account used for administrative tests export const TEST_ADMIN_USER = Cypress.env('DSPACE_TEST_ADMIN_USER') || 'dspacedemo+admin@gmail.com'; export const TEST_ADMIN_PASSWORD = Cypress.env('DSPACE_TEST_ADMIN_PASSWORD') || 'dspace'; // Community/collection/publication used for view/edit tests From a0e2ac3d122bab4bb3dd092aa73195db154ca930 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 4 Mar 2022 12:50:21 -0600 Subject: [PATCH 0073/2129] Update README with clearer instructions on running 'ng e2e' --- README.md | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 74010f3c5c2..d9c911d30ae 100644 --- a/README.md +++ b/README.md @@ -193,7 +193,7 @@ After you have installed all dependencies you can now run the app. Run `yarn run When building for production we're using Ahead of Time (AoT) compilation. With AoT, the browser downloads a pre-compiled version of the application, so it can render the application immediately, without waiting to compile the app first. The compiler is roughly half the size of Angular itself, so omitting it dramatically reduces the application payload. -To build the app for production and start the server run: +To build the app for production and start the server (in one command) run: ```bash yarn start @@ -207,6 +207,10 @@ yarn run build:prod ``` This will build the application and put the result in the `dist` folder. You can copy this folder to wherever you need it for your application server. If you will be using the built-in Express server, you'll also need a copy of the `node_modules` folder tucked inside your copy of `dist`. +After building the app for production, it can be started by running: +```bash +yarn run serve:ssr +``` ### Running the application with Docker NOTE: At this time, we do not have production-ready Docker images for DSpace. @@ -268,11 +272,29 @@ E2E tests (aka integration tests) use [Cypress.io](https://www.cypress.io/). Con The test files can be found in the `./cypress/integration/` folder. -Before you can run e2e tests, two things are required: -1. You MUST have a running backend (i.e. REST API). By default, the e2e tests look for this at http://localhost:8080/server/ or whatever `rest` backend is defined in your `config.prod.yml` or `config.yml`. You may override this using env variables, see [Configuring](#configuring). -2. Your backend MUST include our Entities Test Data set. Some tests run against a (currently hardcoded) Community/Collection/Item UUID. These UUIDs are all valid for our Entities Test Data set. The Entities Test Data set may be installed easily via Docker, see https://github.com/DSpace/DSpace/tree/main/dspace/src/main/docker-compose#ingest-option-2-ingest-entities-test-data +Before you can run e2e tests, two things are REQUIRED: +1. You MUST be running the DSpace backend (i.e. REST API) locally. The e2e tests will *NOT* succeed if run against our demo REST API (https://api7.dspace.org/server/), as that server is uncontrolled and may have content added/removed at any time. + * After starting up your backend on localhost, make sure either your `config.prod.yml` or `config.dev.yml` has its `rest` settings defined to use that localhost backend. + * If you'd prefer, you may instead use environment variables as described at [Configuring](#configuring). For example: + ``` + DSPACE_REST_SSL = false + DSPACE_REST_HOST = localhost + DSPACE_REST_PORT = 8080 + ``` +2. Your backend MUST include our [Entities Test Data set](https://github.com/DSpace-Labs/AIP-Files/releases/tag/demo-entities-data). Some tests run against a specific Community/Collection/Item UUID. These UUIDs are all valid for our Entities Test Data set. + * (Recommended) The Entities Test Data set may be installed easily via Docker, see https://github.com/DSpace/DSpace/tree/main/dspace/src/main/docker-compose#ingest-option-2-ingest-entities-test-data + * Alternatively, the Entities Test Data set may be installed via a simple SQL import (e. g. `psql -U dspace < dspace7-entities-data.sql`). See instructions in link above. + +After performing the above setup, you can run the e2e tests using +``` +ng e2e +```` +NOTE: By default these tests will run against the REST API backend configured via environment variables or in `config.prod.yml`. If you'd rather it use `config.dev.yml`, just set the NODE_ENV environment variable like this: +``` +NODE_ENV=development ng e2e +``` -Run `ng e2e` to kick off the tests. This will start Cypress and allow you to select the browser you wish to use, as well as whether you wish to run all tests or an individual test file. Once you click run on test(s), this opens the [Cypress Test Runner](https://docs.cypress.io/guides/core-concepts/test-runner) to run your test(s) and show you the results. +The `ng e2e` command will start Cypress and allow you to select the browser you wish to use, as well as whether you wish to run all tests or an individual test file. Once you click run on test(s), this opens the [Cypress Test Runner](https://docs.cypress.io/guides/core-concepts/test-runner) to run your test(s) and show you the results. #### Writing E2E Tests From bc705df1444b7d5c8de548b089bd55de06536ab1 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 4 Mar 2022 17:02:42 -0600 Subject: [PATCH 0074/2129] Check two locations for config.json, as it's in a different location in CI --- cypress/plugins/index.ts | 23 +++++++++++++++++++++-- cypress/support/commands.ts | 6 +++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/cypress/plugins/index.ts b/cypress/plugins/index.ts index c6eb8742322..ead38afb921 100644 --- a/cypress/plugins/index.ts +++ b/cypress/plugins/index.ts @@ -1,15 +1,34 @@ +const fs = require('fs'); + // Plugins enable you to tap into, modify, or extend the internal behavior of Cypress // For more info, visit https://on.cypress.io/plugins-api module.exports = (on, config) => { - // Define "log" and "table" tasks, used for logging accessibility errors during CI - // Borrowed from https://github.com/component-driven/cypress-axe#in-cypress-plugins-file on('task', { + // Define "log" and "table" tasks, used for logging accessibility errors during CI + // Borrowed from https://github.com/component-driven/cypress-axe#in-cypress-plugins-file log(message: string) { console.log(message); return null; }, table(message: string) { console.table(message); + return null; + }, + // Cypress doesn't have access to the running application in Node.js. + // So, it's not possible to inject or load the AppConfig or environment of the Angular UI. + // Instead, we'll read our running application's config.json, which contains the configs & + // is regenerated at runtime each time the Angular UI application starts up. + readUIConfig() { + // Check if we have a config.json in the src/assets. If so, use that. + // This is where it's written when running "ng e2e" or "yarn serve" + if (fs.existsSync('./src/assets/config.json')) { + return fs.readFileSync('./src/assets/config.json', 'utf8'); + // Otherwise, check the dist/browser/assets + // This is where it's written when running "serve:ssr", which is what CI uses to start the frontend + } else if (fs.existsSync('./dist/browser/assets/config.json')) { + return fs.readFileSync('./dist/browser/assets/config.json', 'utf8'); + } + return null; } }); diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index d66e1ef0bd0..30951d46f1e 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -34,9 +34,9 @@ function login(email: string, password: string): void { // So, it's not possible to inject or load the AppConfig or environment of the Angular UI. // Instead, we'll read our running application's config.json, which contains the configs & // is regenerated at runtime each time the Angular UI application starts up. - cy.readFile('./src/assets/config.json').then((str) => { - // Parse JSON file into a JSON object - const config = JSON.parse(JSON.stringify(str)); + cy.task('readUIConfig').then((str: string) => { + // Parse config into a JSON object + const config = JSON.parse(str); // Find the URL of our REST API. Have a fallback ready, just in case 'rest.baseUrl' cannot be found. let baseRestUrl = FALLBACK_TEST_REST_BASE_URL; From 59f03817b36d51a5be77df0508ec097926a3e9f8 Mon Sep 17 00:00:00 2001 From: YPaulsen-TLC Date: Mon, 20 Dec 2021 12:58:51 +0100 Subject: [PATCH 0075/2129] DSpace translation German translations of DSpace 7 message keys. --- src/assets/i18n/de.json5 | 100 +++++++++++++-------------------------- 1 file changed, 33 insertions(+), 67 deletions(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index b414852bcdb..7edfd279935 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -768,31 +768,28 @@ // "bitstream.edit.form.embargo.hint": "The first day from which access is allowed. This date cannot be modified on this form. To set an embargo date for a bitstream, go to the Item Status tab, click Authorizations..., create or edit the bitstream's READ policy, and set the Start Date as desired.", // TODO New key - Add a translation "bitstream.edit.form.embargo.hint": "The first day from which access is allowed. This date cannot be modified on this form. To set an embargo date for a bitstream, go to the Item Status tab, click Authorizations..., create or edit the bitstream's READ policy, and set the Start Date as desired.", + // Der erste Tag, ab wann der Zugriff möglich ist. Dieses Datum kann in dieser Form nicht verändert werden. Um eine Embargo-Frist für eine Datei festzulegen, zu dem ()-Tab gehen, auf () klicken, die ()-Richtline für die Datei erstellen oder verändern und das Startdatum wie gewünscht einstellen. // "bitstream.edit.form.embargo.label": "Embargo until specific date", "bitstream.edit.form.embargo.label": "Embargo bis zu einem bestimmten Datum", // "bitstream.edit.form.fileName.hint": "Change the filename for the bitstream. Note that this will change the display bitstream URL, but old links will still resolve as long as the sequence ID does not change.", - // TODO New key - Add a translation - "bitstream.edit.form.fileName.hint": "Change the filename for the bitstream. Note that this will change the display bitstream URL, but old links will still resolve as long as the sequence ID does not change.", + "bitstream.edit.form.fileName.hint": "Ändern Sie den Dateinamen für die Datei. Beachten Sie, dass sich dadurch die angezeigte Datei-URL ändert, aber alte Links weiterhin funktionieren, solange sich die Sequenz-ID nicht ändert.", // "bitstream.edit.form.fileName.label": "Filename", "bitstream.edit.form.fileName.label": "Dateiname", // "bitstream.edit.form.newFormat.label": "Describe new format", - // TODO New key - Add a translation - "bitstream.edit.form.newFormat.label": "Describe new format", + "bitstream.edit.form.newFormat.label": "Neues Format beschreiben", // "bitstream.edit.form.newFormat.hint": "The application you used to create the file, and the version number (for example, \"ACMESoft SuperApp version 1.5\").", - // TODO New key - Add a translation - "bitstream.edit.form.newFormat.hint": "The application you used to create the file, and the version number (for example, \"ACMESoft SuperApp version 1.5\").", + "bitstream.edit.form.newFormat.hint": "Die Anwendung, mit der Sie die Datei erstellt haben, und die Versionsnummer (zum Beispiel, \"ACMESoft SuperApp version 1.5\").", // "bitstream.edit.form.primaryBitstream.label": "Primary bitstream", "bitstream.edit.form.primaryBitstream.label": "Primäre Datei", // "bitstream.edit.form.selectedFormat.hint": "If the format is not in the above list, select \"format not in list\" above and describe it under \"Describe new format\".", - // TODO New key - Add a translation - "bitstream.edit.form.selectedFormat.hint": "If the format is not in the above list, select \"format not in list\" above and describe it under \"Describe new format\".", + "bitstream.edit.form.selectedFormat.hint": "Wenn das Format nicht in der obigen Liste enthalten ist, wählen Sie \"Format in der Liste\" und beschreiben Sie es unter \"Neues Format beschreiben\".", // "bitstream.edit.form.selectedFormat.label": "Selected Format", "bitstream.edit.form.selectedFormat.label": "Ausgewähltes Format", @@ -1153,23 +1150,19 @@ // "collection.edit.template.head": "Edit Template Item for Collection \"{{ collection }}\"", // TODO New key - Add a translation - "collection.edit.template.head": "Edit Template Item for Collection \"{{ collection }}\"", + "collection.edit.template.head": "Itemvorlage für Collection \"{{ collection }}\" bearbeiten", // "collection.edit.template.label": "Template item", - // TODO New key - Add a translation - "collection.edit.template.label": "Template item", + "collection.edit.template.label": "Itemvorlage", // "collection.edit.template.notifications.delete.error": "Failed to delete the item template", - // TODO New key - Add a translation - "collection.edit.template.notifications.delete.error": "Failed to delete the item template", + "collection.edit.template.notifications.delete.error": "Löschen der Itemvorlage fehlgeschlagen", // "collection.edit.template.notifications.delete.success": "Successfully deleted the item template", - // TODO New key - Add a translation - "collection.edit.template.notifications.delete.success": "Successfully deleted the item template", + "collection.edit.template.notifications.delete.success": "Die Itemvorlage wurde erfolgreich gelöscht", // "collection.edit.template.title": "Edit Template Item", - // TODO New key - Add a translation - "collection.edit.template.title": "Edit Template Item", + "collection.edit.template.title": "Itemvorlage bearbeiten", @@ -1393,8 +1386,7 @@ // "comcol-role.edit.submitters.name": "Submitters", - // TODO New key - Add a translation - "comcol-role.edit.submitters.name": "Submitters", + "comcol-role.edit.submitters.name": "Einreichende", // "comcol-role.edit.submitters.description": "The E-People and Groups that have permission to submit new items to this collection.", // TODO New key - Add a translation @@ -1410,21 +1402,18 @@ "comcol-role.edit.item_read.description": "E-People and Groups that can read new items submitted to this collection. Changes to this role are not retroactive. Existing items in the system will still be viewable by those who had read access at the time of their addition.", // "comcol-role.edit.item_read.anonymous-group": "Default read for incoming items is currently set to Anonymous.", - // TODO New key - Add a translation - "comcol-role.edit.item_read.anonymous-group": "Default read for incoming items is currently set to Anonymous.", + "comcol-role.edit.item_read.anonymous-group": "Die Standardeinstellung für das Lesen eingehender Items ist derzeit auf Anonym eingestellt.", // "comcol-role.edit.bitstream_read.name": "Default bitstream read access", - // TODO New key - Add a translation - "comcol-role.edit.bitstream_read.name": "Default bitstream read access", + "comcol-role.edit.bitstream_read.name": "Standard-Lesezugriff Datei", // "comcol-role.edit.bitstream_read.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", // TODO New key - Add a translation "comcol-role.edit.bitstream_read.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", // "comcol-role.edit.bitstream_read.anonymous-group": "Default read for incoming bitstreams is currently set to Anonymous.", - // TODO New key - Add a translation - "comcol-role.edit.bitstream_read.anonymous-group": "Default read for incoming bitstreams is currently set to Anonymous.", + "comcol-role.edit.bitstream_read.anonymous-group": "Die Standardeinstellung für das Lesen eingehender Dateien ist derzeit auf Anonym eingestellt.", // "comcol-role.edit.editor.name": "Editors", @@ -1435,21 +1424,17 @@ // "comcol-role.edit.finaleditor.name": "Final editors", - // TODO New key - Add a translation - "comcol-role.edit.finaleditor.name": "Final editors", + "comcol-role.edit.finaleditor.name": "Endredakteure", // "comcol-role.edit.finaleditor.description": "Final editors are able to edit the metadata of incoming submissions, but will not be able to reject them.", - // TODO New key - Add a translation - "comcol-role.edit.finaleditor.description": "Final editors are able to edit the metadata of incoming submissions, but will not be able to reject them.", + "comcol-role.edit.finaleditor.description": "Die Endredakteure können die Metadaten der eingehenden Beiträge bearbeiten, sie können sie jedoch nicht ablehnen.", // "comcol-role.edit.reviewer.name": "Reviewers", - // TODO New key - Add a translation - "comcol-role.edit.reviewer.name": "Reviewers", + "comcol-role.edit.reviewer.name": "Prüfer", // "comcol-role.edit.reviewer.description": "Reviewers are able to accept or reject incoming submissions. However, they are not able to edit the submission's metadata.", - // TODO New key - Add a translation - "comcol-role.edit.reviewer.description": "Reviewers are able to accept or reject incoming submissions. However, they are not able to edit the submission's metadata.", + "comcol-role.edit.reviewer.description": "Die Prüfer können eingehende Beiträge annehmen oder ablehnen. Sie können jedoch nicht die Metadaten der Einreichung bearbeiten.", @@ -1509,16 +1494,13 @@ "cookies.consent.app.opt-out.title": "(opt-out)", // "cookies.consent.app.purpose": "purpose", - // TODO New key - Add a translation - "cookies.consent.app.purpose": "purpose", + "cookies.consent.app.purpose": "Verwendungszweck", // "cookies.consent.app.required.description": "This application is always required", - // TODO New key - Add a translation - "cookies.consent.app.required.description": "This application is always required", + "cookies.consent.app.required.description": "Dieser Eintrag ist immer erforderlich.", // "cookies.consent.app.required.title": "(always required)", - // TODO New key - Add a translation - "cookies.consent.app.required.title": "(always required)", + "cookies.consent.app.required.title": "(immer erforderlich)", // "cookies.consent.update": "There were changes since your last visit, please update your consent.", "cookies.consent.update": "Seit Ihrem letzten Besuch haben sich Änderungen ergeben, bitte aktualisieren Sie Ihr Einverständnis.", @@ -1569,33 +1551,27 @@ "cookies.consent.app.title.acknowledgement": "Bestätigung", // "cookies.consent.app.description.acknowledgement": "Required for saving your acknowledgements and consents", - // TODO New key - Add a translation "cookies.consent.app.description.acknowledgement": "Erforderlich für die Speicherung Ihrer Bestätigungen und Einwilligungen", // "cookies.consent.app.title.google-analytics": "Google Analytics", - // TODO New key - Add a translation "cookies.consent.app.title.google-analytics": "Google Analytics", // "cookies.consent.app.description.google-analytics": "Allows us to track statistical data", - // TODO New key - Add a translation - "cookies.consent.app.description.google-analytics": "Allows us to track statistical data", + "cookies.consent.app.description.google-analytics": "Erlaubt uns, statistische Daten zu erfassen", // "cookies.consent.purpose.functional": "Functional", - // TODO New key - Add a translation - "cookies.consent.purpose.functional": "Functional", + "cookies.consent.purpose.functional": "Funktionell", // "cookies.consent.purpose.statistical": "Statistical", - // TODO New key - Add a translation - "cookies.consent.purpose.statistical": "Statistical", + "cookies.consent.purpose.statistical": "Statistisch", // "curation-task.task.checklinks.label": "Check Links in Metadata", - // TODO New key - Add a translation - "curation-task.task.checklinks.label": "Check Links in Metadata", + "curation-task.task.checklinks.label": "Links in Metadaten prüfen", // "curation-task.task.noop.label": "NOOP", // TODO New key - Add a translation @@ -1606,45 +1582,35 @@ "curation-task.task.profileformats.label": "Profile Bitstream Formats", // "curation-task.task.requiredmetadata.label": "Check for Required Metadata", - // TODO New key - Add a translation - "curation-task.task.requiredmetadata.label": "Check for Required Metadata", + "curation-task.task.requiredmetadata.label": "Prüfung auf erforderliche Metadaten", // "curation-task.task.translate.label": "Microsoft Translator", - // TODO New key - Add a translation - "curation-task.task.translate.label": "Microsoft Translator", + "curation-task.task.translate.label": "Microsoft Übersetzer", // "curation-task.task.vscan.label": "Virus Scan", - // TODO New key - Add a translation - "curation-task.task.vscan.label": "Virus Scan", + "curation-task.task.vscan.label": "Viren-Scan", // "curation.form.task-select.label": "Task:", - // TODO New key - Add a translation - "curation.form.task-select.label": "Task:", + "curation.form.task-select.label": "Aufgabe:", // "curation.form.submit": "Start", - // TODO New key - Add a translation "curation.form.submit": "Start", // "curation.form.submit.success.head": "The curation task has been started successfully", - // TODO New key - Add a translation - "curation.form.submit.success.head": "The curation task has been started successfully", + "curation.form.submit.success.head": "Die Datenpflegeroutine wurde erfolgreich gestartet", // "curation.form.submit.success.content": "You will be redirected to the corresponding process page.", - // TODO New key - Add a translation - "curation.form.submit.success.content": "You will be redirected to the corresponding process page.", + "curation.form.submit.success.content": "Sie werden auf die entsprechende Prozessseite weitergeleitet.", // "curation.form.submit.error.head": "Running the curation task failed", - // TODO New key - Add a translation - "curation.form.submit.error.head": "Running the curation task failed", + "curation.form.submit.error.head": "Die Ausführung der Datenpflegeroutine ist fehlgeschlagen", // "curation.form.submit.error.content": "An error occured when trying to start the curation task.", - // TODO New key - Add a translation - "curation.form.submit.error.content": "An error occured when trying to start the curation task.", + "curation.form.submit.error.content": "Beim Versuch, die Datenpflegeroutine zu starten, ist ein Fehler aufgetreten.", // "curation.form.handle.label": "Handle:", - // TODO New key - Add a translation "curation.form.handle.label": "Handle:", // "curation.form.handle.hint": "Hint: Enter [your-handle-prefix]/0 to run a task across entire site (not all tasks may support this capability)", From 8b0c0348b2d582bb106ccc00ab67171017763b74 Mon Sep 17 00:00:00 2001 From: YPaulsen-TLC Date: Fri, 7 Jan 2022 14:34:18 +0100 Subject: [PATCH 0076/2129] New message key translations German translations of DSpace 7 message keys. --- src/assets/i18n/de.json5 | 400 +++++++++++++++------------------------ 1 file changed, 152 insertions(+), 248 deletions(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index 7edfd279935..77105cc7aa8 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -107,7 +107,7 @@ "admin.registries.bitstream-formats.edit.head": "Dateiformat: {{ format }}", // "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.", - "admin.registries.bitstream-formats.edit.internal.hint": "Dateiformate, die als intern gekennzeichnet sind, dienen administrativen Zwecken und bleiben dem Endnutzer verborgen.", + "admin.registries.bitstream-formats.edit.internal.hint": "Dateiformate, die als intern gekennzeichnet sind, dienen administrativen Zwecken und bleiben dem/der Endnutzer:in verborgen.", // "admin.registries.bitstream-formats.edit.internal.label": "Internal", "admin.registries.bitstream-formats.edit.internal.label": "Intern", @@ -812,7 +812,7 @@ // "browse.comcol.by.author": "By Author", - "browse.comcol.by.author": "Nach Autor/in", + "browse.comcol.by.author": "Nach Autor:in", // "browse.comcol.by.dateissued": "By Issue Date", "browse.comcol.by.dateissued": "Nach Erscheinungsjahr", @@ -830,7 +830,7 @@ "browse.empty": "Es gibt keine Dokumente, die angezeigt werden können.", // "browse.metadata.author": "Author", - "browse.metadata.author": "Autor/in", + "browse.metadata.author": "Autor:in", // "browse.metadata.dateissued": "Issue Date", "browse.metadata.dateissued": "Erscheinungsdatum", @@ -842,7 +842,7 @@ "browse.metadata.title": "Titel", // "browse.metadata.author.breadcrumbs": "Browse by Author", - "browse.metadata.author.breadcrumbs": "Auflistung nach Autor(in)", + "browse.metadata.author.breadcrumbs": "Auflistung nach Autor:in", // "browse.metadata.dateissued.breadcrumbs": "Browse by Date", "browse.metadata.dateissued.breadcrumbs": "Auflistung nach Datum", @@ -978,7 +978,7 @@ "collection.edit.item-mapper.confirm": "Ausgewählte Ressourcen spiegeln", // "collection.edit.item-mapper.description": "This is the item mapper tool that allows collection administrators to map items from other collections into this collection. You can search for items from other collections and map them, or browse the list of currently mapped items.", - "collection.edit.item-mapper.description": "Sammlungsadministratoren haben die Möglichkeit Ressourcen von einer Sammlung in eine andere zu spiegeln. Man kann nach Ressourcen in anderen Sammlungen suchen und diese spiegeln oder sich eine Liste der gespiegelten Ressourcen anzeigen lassen.", + "collection.edit.item-mapper.description": "Sammlungsadministrator:innen haben die Möglichkeit Ressourcen von einer Sammlung in eine andere zu spiegeln. Man kann nach Ressourcen in anderen Sammlungen suchen und diese spiegeln oder sich eine Liste der gespiegelten Ressourcen anzeigen lassen.", // "collection.edit.item-mapper.head": "Item Mapper - Map Items from Other Collections", "collection.edit.item-mapper.head": "Ressourcen spiegeln - Spiegelt Ressourcen aus anderen Sammlungen", @@ -1370,10 +1370,10 @@ // "comcol-role.edit.community-admin.name": "Administrators", - "comcol-role.edit.community-admin.name": "Administratoren", + "comcol-role.edit.community-admin.name": "Administrator:innen", // "comcol-role.edit.collection-admin.name": "Administrators", - "comcol-role.edit.collection-admin.name": "Administratoren", + "comcol-role.edit.collection-admin.name": "Administrator:innen", // "comcol-role.edit.community-admin.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", @@ -1417,24 +1417,24 @@ // "comcol-role.edit.editor.name": "Editors", - "comcol-role.edit.editor.name": "Redakteure", + "comcol-role.edit.editor.name": "Redakteur:innen", // "comcol-role.edit.editor.description": "Editors are able to edit the metadata of incoming submissions, and then accept or reject them.", "comcol-role.edit.editor.description": "Die Redakteure können die Metadaten der eingehenden Beiträge bearbeiten und sie dann annehmen oder ablehnen.", // "comcol-role.edit.finaleditor.name": "Final editors", - "comcol-role.edit.finaleditor.name": "Endredakteure", + "comcol-role.edit.finaleditor.name": "Endredakteur:innen", // "comcol-role.edit.finaleditor.description": "Final editors are able to edit the metadata of incoming submissions, but will not be able to reject them.", - "comcol-role.edit.finaleditor.description": "Die Endredakteure können die Metadaten der eingehenden Beiträge bearbeiten, sie können sie jedoch nicht ablehnen.", + "comcol-role.edit.finaleditor.description": "Die Endredakteur:innen können die Metadaten der eingehenden Beiträge bearbeiten, sie können sie jedoch nicht ablehnen.", // "comcol-role.edit.reviewer.name": "Reviewers", - "comcol-role.edit.reviewer.name": "Prüfer", + "comcol-role.edit.reviewer.name": "Prüfer:innen", // "comcol-role.edit.reviewer.description": "Reviewers are able to accept or reject incoming submissions. However, they are not able to edit the submission's metadata.", - "comcol-role.edit.reviewer.description": "Die Prüfer können eingehende Beiträge annehmen oder ablehnen. Sie können jedoch nicht die Metadaten der Einreichung bearbeiten.", + "comcol-role.edit.reviewer.description": "Die Prüfer:innen können eingehende Beiträge annehmen oder ablehnen. Sie können jedoch nicht die Metadaten der Einreichung bearbeiten.", @@ -1623,8 +1623,7 @@ "dso-selector.create.collection.head": "Neue Sammlung", // "dso-selector.create.collection.sub-level": "Create a new collection in", - // TODO New key - Add a translation - "dso-selector.create.collection.sub-level": "Create a new collection in", + "dso-selector.create.collection.sub-level": "Eine neue Sammlung erstellen in", // "dso-selector.create.community.head": "New community", "dso-selector.create.community.head": "Neuer Bereich", @@ -1639,12 +1638,10 @@ "dso-selector.create.item.head": "Neue Ressource", // "dso-selector.create.item.sub-level": "Create a new item in", - // TODO New key - Add a translation - "dso-selector.create.item.sub-level": "Create a new item in", + "dso-selector.create.item.sub-level": "Ein neues Item erstellen in", // "dso-selector.create.submission.head": "New submission", - // TODO New key - Add a translation - "dso-selector.create.submission.head": "New submission", + "dso-selector.create.submission.head": "Neue Veröffentlichung", // "dso-selector.edit.collection.head": "Edit collection", "dso-selector.edit.collection.head": "Sammlung bearbeiten", @@ -1656,8 +1653,7 @@ "dso-selector.edit.item.head": "Ressource bearbeiten", // "dso-selector.export-metadata.dspaceobject.head": "Export metadata from", - // TODO New key - Add a translation - "dso-selector.export-metadata.dspaceobject.head": "Export metadata from", + "dso-selector.export-metadata.dspaceobject.head": "Exportieren der Metadaten aus", // "dso-selector.no-results": "No {{ type }} found", "dso-selector.no-results": "Kein(e) {{ type }} gefunden", @@ -1668,36 +1664,28 @@ // "confirmation-modal.export-metadata.header": "Export metadata for {{ dsoName }}", - // TODO New key - Add a translation - "confirmation-modal.export-metadata.header": "Export metadata for {{ dsoName }}", + "confirmation-modal.export-metadata.header": "Exportieren der Metadaten für {{ dsoName }}", // "confirmation-modal.export-metadata.info": "Are you sure you want to export metadata for {{ dsoName }}", - // TODO New key - Add a translation - "confirmation-modal.export-metadata.info": "Are you sure you want to export metadata for {{ dsoName }}", + "confirmation-modal.export-metadata.info": "Sind Sie sicher, dass Sie die Metadaten für {{ dsoName }} exportieren wollen", // "confirmation-modal.export-metadata.cancel": "Cancel", - // TODO New key - Add a translation - "confirmation-modal.export-metadata.cancel": "Cancel", + "confirmation-modal.export-metadata.cancel": "Abbrechen", // "confirmation-modal.export-metadata.confirm": "Export", - // TODO New key - Add a translation - "confirmation-modal.export-metadata.confirm": "Export", + "confirmation-modal.export-metadata.confirm": "Exportieren", // "confirmation-modal.delete-eperson.header": "Delete EPerson \"{{ dsoName }}\"", - // TODO New key - Add a translation - "confirmation-modal.delete-eperson.header": "Delete EPerson \"{{ dsoName }}\"", + "confirmation-modal.delete-eperson.header": "Person \"{{ dsoName }}\" löschen", // "confirmation-modal.delete-eperson.info": "Are you sure you want to delete EPerson \"{{ dsoName }}\"", - // TODO New key - Add a translation - "confirmation-modal.delete-eperson.info": "Are you sure you want to delete EPerson \"{{ dsoName }}\"", + "confirmation-modal.delete-eperson.info": "Sind Sie sicher, dass Sie die Person \"{{ dsoName }}\" löschen möchten", // "confirmation-modal.delete-eperson.cancel": "Cancel", - // TODO New key - Add a translation - "confirmation-modal.delete-eperson.cancel": "Cancel", + "confirmation-modal.delete-eperson.cancel": "Abbrechen", // "confirmation-modal.delete-eperson.confirm": "Delete", - // TODO New key - Add a translation - "confirmation-modal.delete-eperson.confirm": "Delete", + "confirmation-modal.delete-eperson.confirm": "Löschen", // "error.bitstream": "Error fetching bitstream", @@ -1726,7 +1714,7 @@ "error.item": "Fehler beim Laden der Ressource", // "error.items": "Error fetching items", - "error.items": "Fejöer beim Laden der Ressourcen", + "error.items": "Fehler beim Laden der Ressourcen", // "error.objects": "Error fetching objects", "error.objects": "Fehler beim Laden der Objekte", @@ -1761,8 +1749,7 @@ // "file-section.error.header": "Error obtaining files for this item", - // TODO New key - Add a translation - "file-section.error.header": "Error obtaining files for this item", + "file-section.error.header": "Fehler beim Abrufen der Dateien für dieses Item", @@ -1776,124 +1763,98 @@ "footer.link.lyrasis": "LYRASIS", // "footer.link.cookies": "Cookie settings", - // TODO New key - Add a translation - "footer.link.cookies": "Cookie settings", + "footer.link.cookies": "Cookie Einstellungen", // "footer.link.privacy-policy": "Privacy policy", - // TODO New key - Add a translation - "footer.link.privacy-policy": "Privacy policy", + "footer.link.privacy-policy": "Datenschutzbestimmungen", // "footer.link.end-user-agreement":"End User Agreement", - // TODO New key - Add a translation - "footer.link.end-user-agreement":"End User Agreement", - + "footer.link.end-user-agreement":"Endnutzervereinbarung", + // "forgot-email.form.header": "Forgot Password", - // TODO New key - Add a translation - "forgot-email.form.header": "Forgot Password", + "forgot-email.form.header": "Passwort vergessen", // "forgot-email.form.info": "Enter Register an account to subscribe to collections for email updates, and submit new items to DSpace.", // TODO New key - Add a translation "forgot-email.form.info": "Enter Register an account to subscribe to collections for email updates, and submit new items to DSpace.", // "forgot-email.form.email": "Email Address *", - // TODO New key - Add a translation - "forgot-email.form.email": "Email Address *", + "forgot-email.form.email": "E-Mail-Addresse *", // "forgot-email.form.email.error.required": "Please fill in an email address", - // TODO New key - Add a translation - "forgot-email.form.email.error.required": "Please fill in an email address", + "forgot-email.form.email.error.required": "Bitte geben Sie eine E-Mail-Adresse ein", // "forgot-email.form.email.error.pattern": "Please fill in a valid email address", - // TODO New key - Add a translation - "forgot-email.form.email.error.pattern": "Please fill in a valid email address", + "forgot-email.form.email.error.pattern": "Bitte geben Sie eine gültige E-Mail-Adresse ein", // "forgot-email.form.email.hint": "This address will be verified and used as your login name.", - // TODO New key - Add a translation - "forgot-email.form.email.hint": "This address will be verified and used as your login name.", + "forgot-email.form.email.hint": "Diese Adresse wird überprüft und als Ihr Anmeldename verwendet.", // "forgot-email.form.submit": "Submit", - // TODO New key - Add a translation - "forgot-email.form.submit": "Submit", + "forgot-email.form.submit": "Einreichen", // "forgot-email.form.success.head": "Verification email sent", - // TODO New key - Add a translation - "forgot-email.form.success.head": "Verification email sent", + "forgot-email.form.success.head": "Verifizierungs-E-Mail gesendet", // "forgot-email.form.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", // TODO New key - Add a translation "forgot-email.form.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", // "forgot-email.form.error.head": "Error when trying to register email", - // TODO New key - Add a translation - "forgot-email.form.error.head": "Error when trying to register email", + "forgot-email.form.error.head": "Fehler beim Versuch, die E-Mail zu registrieren", // "forgot-email.form.error.content": "An error occured when registering the following email address: {{ email }}", // TODO New key - Add a translation - "forgot-email.form.error.content": "An error occured when registering the following email address: {{ email }}", + "forgot-email.form.error.content": "Bei der Registrierung der folgenden E-Mail-Adresse ist ein Fehler aufgetreten: {{ email }}", // "forgot-password.title": "Forgot Password", - // TODO New key - Add a translation - "forgot-password.title": "Forgot Password", + "forgot-password.title": "Passwort vergessen", // "forgot-password.form.head": "Forgot Password", - // TODO New key - Add a translation - "forgot-password.form.head": "Forgot Password", + "forgot-password.form.head": "Passwort vergessen", // "forgot-password.form.info": "Enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", - // TODO New key - Add a translation - "forgot-password.form.info": "Enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", + "forgot-password.form.info": "Geben Sie ein neues Kennwort in das unten stehende Feld ein und bestätigen Sie es, indem Sie es erneut in das zweite Feld eingeben. Es sollte mindestens sechs Zeichen lang sein.", // "forgot-password.form.card.security": "Security", - // TODO New key - Add a translation - "forgot-password.form.card.security": "Security", + "forgot-password.form.card.security": "Sicherheit", // "forgot-password.form.identification.header": "Identify", - // TODO New key - Add a translation - "forgot-password.form.identification.header": "Identify", + "forgot-password.form.identification.header": "Identifizieren", // "forgot-password.form.identification.email": "Email address: ", - // TODO New key - Add a translation - "forgot-password.form.identification.email": "Email address: ", + "forgot-password.form.identification.email": "E-Mail-Addresse: ", // "forgot-password.form.label.password": "Password", - // TODO New key - Add a translation - "forgot-password.form.label.password": "Password", + "forgot-password.form.label.password": "Passwort", // "forgot-password.form.label.passwordrepeat": "Retype to confirm", - // TODO New key - Add a translation - "forgot-password.form.label.passwordrepeat": "Retype to confirm", + "forgot-password.form.label.passwordrepeat": "Zum Bestätigen wiederholen", // "forgot-password.form.error.empty-password": "Please enter a password in the box below.", - // TODO New key - Add a translation - "forgot-password.form.error.empty-password": "Please enter a password in the box below.", + "forgot-password.form.error.empty-password": "Bitte geben Sie in das unten stehende Feld ein Passwort ein.", // "forgot-password.form.error.matching-passwords": "The passwords do not match.", - // TODO New key - Add a translation - "forgot-password.form.error.matching-passwords": "The passwords do not match.", + "forgot-password.form.error.matching-passwords": "Die Passwörter stimmen nicht überein.", // "forgot-password.form.error.password-length": "The password should be at least 6 characters long.", - // TODO New key - Add a translation - "forgot-password.form.error.password-length": "The password should be at least 6 characters long.", + "forgot-password.form.error.password-length": "Das Passwort sollte mindestens 6 Zeichen lang sein.", // "forgot-password.form.notification.error.title": "Error when trying to submit new password", - // TODO New key - Add a translation - "forgot-password.form.notification.error.title": "Error when trying to submit new password", + "forgot-password.form.notification.error.title": "Fehler beim Versuch, ein neues Passwort zu übermitteln", // "forgot-password.form.notification.success.content": "The password reset was successful. You have been logged in as the created user.", - // TODO New key - Add a translation - "forgot-password.form.notification.success.content": "The password reset was successful. You have been logged in as the created user.", + "forgot-password.form.notification.success.content": "Das Zurücksetzen des Passworts war erfolgreich. Sie wurden in den erstellten Account eingeloggt.", // "forgot-password.form.notification.success.title": "Password reset completed", - // TODO New key - Add a translation - "forgot-password.form.notification.success.title": "Password reset completed", + "forgot-password.form.notification.success.title": "Passwort zurücksetzen abgeschlossen", // "forgot-password.form.submit": "Submit password", - // TODO New key - Add a translation - "forgot-password.form.submit": "Submit password", + "forgot-password.form.submit": "Passwort abschicken", @@ -1967,7 +1928,6 @@ "form.search": "Suche", // "form.search-help": "Click here to look for an existing correspondence", - // TODO Source message changed - Revise the translation "form.search-help": "Klicken Sie hier, um eine Übereinstimmung zu suchen", // "form.submit": "Submit", @@ -1979,8 +1939,7 @@ "home.description": "", // "home.breadcrumbs": "Home", - // TODO New key - Add a translation - "home.breadcrumbs": "Home", + "home.breadcrumbs": "Startseite", // "search.search-form.placeholder": "Search the repository ...", "home.search-form.placeholder": "Durchsuche Repositorium", @@ -2032,12 +1991,10 @@ // "item.alerts.private": "This item is private", - // TODO New key - Add a translation - "item.alerts.private": "This item is private", + "item.alerts.private": "Dieses Item ist privat", // "item.alerts.withdrawn": "This item has been withdrawn", - // TODO New key - Add a translation - "item.alerts.withdrawn": "This item has been withdrawn", + "item.alerts.withdrawn": "Dieses Item wurde zurückgezogen", @@ -2046,8 +2003,7 @@ "item.edit.authorizations.heading": "With this editor you can view and alter the policies of an item, plus alter policies of individual item components: bundles and bitstreams. Briefly, an item is a container of bundles, and bundles are containers of bitstreams. Containers usually have ADD/REMOVE/READ/WRITE policies, while bitstreams only have READ/WRITE policies.", // "item.edit.authorizations.title": "Edit item's Policies", - // TODO New key - Add a translation - "item.edit.authorizations.title": "Edit item's Policies", + "item.edit.authorizations.title": "Item-Richtlinien bearbeiten", @@ -2079,7 +2035,6 @@ "item.bitstreams.upload.drop-message": "Eine Datei zum Hochladen ablegen", // "item.bitstreams.upload.item": "Item: ", - // TODO New key - Add a translation "item.bitstreams.upload.item": "Item: ", // "item.bitstreams.upload.notifications.bundle.created.content": "Successfully created new bundle.", @@ -2092,8 +2047,7 @@ "item.bitstreams.upload.notifications.upload.failed": "Hochladen fehlgeschlagen. Bitte überprüfen Sie den Inhalt, bevor Sie es erneut versuchen.", // "item.bitstreams.upload.title": "Upload bitstream", - // TODO New key - Add a translation - "item.bitstreams.upload.title": "Upload bitstream", + "item.bitstreams.upload.title": "Datei hochladen", @@ -2105,8 +2059,7 @@ "item.edit.bitstreams.bundle.displaying": "Currently displaying {{ amount }} bitstreams of {{ total }}.", // "item.edit.bitstreams.bundle.load.all": "Load all ({{ total }})", - // TODO New key - Add a translation - "item.edit.bitstreams.bundle.load.all": "Load all ({{ total }})", + "item.edit.bitstreams.bundle.load.all": "Alle ({{ total }}) laden", // "item.edit.bitstreams.bundle.load.more": "Load more", "item.edit.bitstreams.bundle.load.more": "Mehr laden", @@ -2168,7 +2121,7 @@ "item.edit.bitstreams.notifications.move.saved.title": "Move changes saved", // "item.edit.bitstreams.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", - "item.edit.bitstreams.notifications.outdated.content": "Die Ressource, an der Sie gerade arbeiten, wurde von einem anderen Benutzer geändert. Ihre aktuellen Änderungen werden verworfen, um Konflikte zu vermeiden.", + "item.edit.bitstreams.notifications.outdated.content": "Die Ressource, an der Sie gerade arbeiten, wurde von einem anderen Account geändert. Ihre aktuellen Änderungen werden verworfen, um Konflikte zu vermeiden.", // "item.edit.bitstreams.notifications.outdated.title": "Changes outdated", "item.edit.bitstreams.notifications.outdated.title": "Veraltete Änderungen", @@ -2236,7 +2189,7 @@ "item.edit.item-mapper.cancel": "Abbrechen", // "item.edit.item-mapper.description": "This is the item mapper tool that allows administrators to map this item to other collections. You can search for collections and map them, or browse the list of collections the item is currently mapped to.", - "item.edit.item-mapper.description": "Sammlungsadministratoren haben die Möglichkeit Ressourcen von einer Sammlung in eine andere zu spiegeln. Man kann nach Ressourcen in anderen Sammlungen suchen und diese spiegeln oder sich eine Liste der gespiegelten Ressourcen anzeigen lassen.", + "item.edit.item-mapper.description": "Sammlungsadministrator:innen haben die Möglichkeit Ressourcen von einer Sammlung in eine andere zu spiegeln. Man kann nach Ressourcen in anderen Sammlungen suchen und diese spiegeln oder sich eine Liste der gespiegelten Ressourcen anzeigen lassen.", // "item.edit.item-mapper.head": "Item Mapper - Map Item to Collections", "item.edit.item-mapper.head": "Ressourcen spiegeln - Spiegelt eine Ressource in andere Sammlungen", @@ -2322,8 +2275,7 @@ "item.edit.metadata.notifications.discarded.title": "Änderungen verworfen", // "item.edit.metadata.notifications.error.title": "An error occurred", - // TODO New key - Add a translation - "item.edit.metadata.notifications.error.title": "An error occurred", + "item.edit.metadata.notifications.error.title": "Es ist ein Fehler aufgetreten", // "item.edit.metadata.notifications.invalid.content": "Your changes were not saved. Please make sure all fields are valid before you save.", "item.edit.metadata.notifications.invalid.content": "Ihre Änderungen wurden nicht gespeichert. Stellen Sie sicher, dass alle Felder gültig sind, bevor Sie Abspeichern.", @@ -2332,7 +2284,7 @@ "item.edit.metadata.notifications.invalid.title": "Metadaten ungültig", // "item.edit.metadata.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", - "item.edit.metadata.notifications.outdated.content": "Die Ressource, an der Sie gerade arbeiten, wurde von einem anderen Benutzer geändert. Ihre aktuellen Änderungen werden nicht angewandt, um Konflikte zu vermeiden.", + "item.edit.metadata.notifications.outdated.content": "Die Ressource, an der Sie gerade arbeiten, wurde von einem anderen Account geändert. Ihre aktuellen Änderungen werden nicht angewandt, um Konflikte zu vermeiden.", // "item.edit.metadata.notifications.outdated.title": "Changed outdated", "item.edit.metadata.notifications.outdated.title": "Änderung veraltet", @@ -2482,7 +2434,7 @@ "item.edit.relationships.notifications.failed.title": "Fehler beim Bearbeiten der Beziehung", // "item.edit.relationships.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", - "item.edit.relationships.notifications.outdated.content": "Die Ressource, die Sie gerade bearbeiten, wurde von einem anderen Benutzer geändert. Ihre aktuellen Änderungen werden verworfen, um Konflikte zu vermeiden.", + "item.edit.relationships.notifications.outdated.content": "Die Ressource, die Sie gerade bearbeiten, wurde von einem anderen Account geändert. Ihre aktuellen Änderungen werden verworfen, um Konflikte zu vermeiden.", // "item.edit.relationships.notifications.outdated.title": "Changes outdated", "item.edit.relationships.notifications.outdated.title": "Änderungen veraltet", @@ -2530,7 +2482,7 @@ "item.edit.tabs.relationships.title": "Ressource bearbeiten - Relationen", // "item.edit.tabs.status.buttons.authorizations.button": "Authorizations...", - "item.edit.tabs.status.buttons.authorizations.button": "Rechte...", + "item.edit.tabs.status.buttons.authorizations.button": "Berechtigungen...", // "item.edit.tabs.status.buttons.authorizations.label": "Edit item's authorization policies", "item.edit.tabs.status.buttons.authorizations.label": "Rechte der Ressource bearbeiten", @@ -2671,7 +2623,7 @@ "item.page.abstract": "Zusammenfassung", // "item.page.author": "Authors", - "item.page.author": "AutorInnen", + "item.page.author": "Autor:innen", // "item.page.citation": "Citation", "item.page.citation": "Zitierform", @@ -2713,7 +2665,7 @@ "item.page.link.simple": "Kurzanzeige", // "item.page.person.search.title": "Articles by this author", - "item.page.person.search.title": "Veröffentlichungen dieses/r Autor/in", + "item.page.person.search.title": "Veröffentlichungen dieses/dieser Autor:in", // "item.page.related-items.view-more": "Show {{ amount }} more", "item.page.related-items.view-more": "{{ amount }} mehr anzeigen", @@ -2728,7 +2680,7 @@ "item.page.relationships.isJournalOfPublication": "Veröffentlichungen", // "item.page.relationships.isOrgUnitOfPerson": "Authors", - "item.page.relationships.isOrgUnitOfPerson": "AutorInnen", + "item.page.relationships.isOrgUnitOfPerson": "Autor:innen", // "item.page.relationships.isOrgUnitOfProject": "Research Projects", "item.page.relationships.isOrgUnitOfProject": "Forschungsprojekte", @@ -2755,7 +2707,7 @@ "item.preview.dc.identifier.uri": "Identifikator:", // "item.preview.dc.contributor.author": "Authors:", - "item.preview.dc.contributor.author": "AutorInnen:", + "item.preview.dc.contributor.author": "Autor:innen:", // "item.preview.dc.date.issued": "Published date:", "item.preview.dc.date.issued": "Erscheinungsdatum:", @@ -2793,7 +2745,7 @@ "item.select.empty": "Es gibt keine Ressourcen dazu", // "item.select.table.author": "Author", - "item.select.table.author": "Autor/in", + "item.select.table.author": "Autor:in", // "item.select.table.collection": "Collection", "item.select.table.collection": "Sammlung", @@ -2809,7 +2761,6 @@ "item.version.history.head": "Versionsgeschichte", // "item.version.history.return": "Return", - // TODO New key - Add a translation "item.version.history.return": "Zurück", // "item.version.history.selected": "Selected version", @@ -2822,7 +2773,7 @@ "item.version.history.table.item": "Ressource", // "item.version.history.table.editor": "Editor", - "item.version.history.table.editor": "Herausgeber/in", + "item.version.history.table.editor": "Herausgeber:in", // "item.version.history.table.date": "Date", "item.version.history.table.date": "Datum", @@ -2848,7 +2799,7 @@ "journal.page.edit": "Diese Ressource bearbeiten", // "journal.page.editor": "Editor-in-Chief", - "journal.page.editor": "Chefredakteur", + "journal.page.editor": "Chefredakteur:in", // "journal.page.issn": "ISSN", "journal.page.issn": "ISSN", @@ -3038,7 +2989,7 @@ // "menu.section.admin_search": "Admin Search", - "menu.section.admin_search": "Administratoren Suche", + "menu.section.admin_search": "Administrator:innen Suche", @@ -3046,7 +2997,7 @@ "menu.section.browse_community": "Dieser Bereich", // "menu.section.browse_community_by_author": "By Author", - "menu.section.browse_community_by_author": "Nach Autor/in", + "menu.section.browse_community_by_author": "Nach Autor:in", // "menu.section.browse_community_by_issue_date": "By Issue Date", "menu.section.browse_community_by_issue_date": "Nach Erscheinungsdateum", @@ -3058,7 +3009,7 @@ "menu.section.browse_global": "Das gesamte Repositorium", // "menu.section.browse_global_by_author": "By Author", - "menu.section.browse_global_by_author": "Nach Autor/in", + "menu.section.browse_global_by_author": "Nach Autor:in", // "menu.section.browse_global_by_dateissued": "By Issue Date", "menu.section.browse_global_by_dateissued": "Nach Erscheinungsjahr", @@ -3260,8 +3211,7 @@ "mydspace.description": "", // "mydspace.general.text-here": "here", - // TODO New key - Add a translation - "mydspace.general.text-here": "here", + "mydspace.general.text-here": "hier", // "mydspace.messages.controller-help": "Select this option to send a message to item's submitter.", "mydspace.messages.controller-help": "Wählen Sie diese Option, um dem/derjenigen, die die Ressource eingereicht hat, eine Nachricht zu schicken.", @@ -3318,7 +3268,7 @@ "mydspace.results.no-abstract": "Keine Zusammenfassung", // "mydspace.results.no-authors": "No Authors", - "mydspace.results.no-authors": "Keine AutorInnen", + "mydspace.results.no-authors": "Keine Autor:innen", // "mydspace.results.no-collections": "No Collections", "mydspace.results.no-collections": "Keine Sammlungen", @@ -3587,14 +3537,12 @@ "process.detail.output-files" : "Output Files", // "process.detail.output-files.empty" : "This process doesn't contain any output files", - // TODO New key - Add a translation - "process.detail.output-files.empty" : "This process doesn't contain any output files", + "process.detail.output-files.empty" : "Dieser Prozess enthält keine Ausgabedateien", // "process.detail.script" : "Script", "process.detail.script" : "Skript", // "process.detail.title" : "Process: {{ id }} - {{ name }}", - // TODO New key - Add a translation "process.detail.title" : "Prozess: {{ id }} - {{ name }}", // "process.detail.start-time" : "Start time", @@ -3627,7 +3575,7 @@ "process.overview.table.status" : "Status", // "process.overview.table.user" : "User", - "process.overview.table.user" : "Benutzer", + "process.overview.table.user" : "Benutzer:in", // "process.overview.title": "Processes Overview", "process.overview.title": "Überblick der Prozesse", @@ -3652,8 +3600,7 @@ "profile.form.submit": "Profil aktualisieren", // "profile.groups.head": "Authorization groups you belong to", - // TODO New key - Add a translation - "profile.groups.head": "Authorization groups you belong to", + "profile.groups.head": "Berechtigungsgruppen, denen Sie angehören", // "profile.head": "Update Profile", "profile.head": "Profil aktualisieren", @@ -3793,7 +3740,7 @@ // "register-email.title": "New user registration", - "register-email.title": "Registrierung neuer Benutzer", + "register-email.title": "Registrierung neuer Benutzer:innen", // "register-page.create-profile.header": "Create Profile", "register-page.create-profile.header": "Profil erstellen", @@ -3847,20 +3794,20 @@ "register-page.create-profile.submit": "Vollständige Registrierung", // "register-page.create-profile.submit.error.content": "Something went wrong while registering a new user.", - "register-page.create-profile.submit.error.content": "Bei der Registrierung eines neuen Benutzers ist ein Fehler aufgetreten.", + "register-page.create-profile.submit.error.content": "Bei der Registrierung eines neuen Accounts ist ein Fehler aufgetreten.", // "register-page.create-profile.submit.error.head": "Registration failed", "register-page.create-profile.submit.error.head": "Registrierung fehlgeschlagen.", // "register-page.create-profile.submit.success.content": "The registration was successful. You have been logged in as the created user.", - "register-page.create-profile.submit.success.content": "Die Registrierung war erfolgreich. Sie wurden als der angelegte Benutzer angemeldet.", + "register-page.create-profile.submit.success.content": "Die Registrierung war erfolgreich. Sie wurden als der/die angelegte Benutzer:in angemeldet.", // "register-page.create-profile.submit.success.head": "Registration completed", "register-page.create-profile.submit.success.head": "Registrierung abgeschlossen", // "register-page.registration.header": "New user registration", - "register-page.registration.header": "Registrierung neuer Benutzer", + "register-page.registration.header": "Registrierung neuer Benutzer:innen", // "register-page.registration.info": "Register an account to subscribe to collections for email updates, and submit new items to DSpace.", "register-page.registration.info": "Registrieren Sie ein Konto, um Sammlungen für E-Mail-Updates zu abonnieren und neue Ressourcen in DSpace einzugeben.", @@ -3875,7 +3822,7 @@ "register-page.registration.email.error.pattern": "Bitte geben Sie eine gültige E-Mail Adresse an", // "register-page.registration.email.hint": "This address will be verified and used as your login name.", - "register-page.registration.email.hint": "Diese Adresse wird überprüft und als Ihr Benutzername verwendet..", + "register-page.registration.email.hint": "Diese Adresse wird überprüft und als Ihr Accountname verwendet..", // "register-page.registration.submit": "Register", "register-page.registration.submit": "Registrieren", @@ -3904,13 +3851,13 @@ "relationships.add.error.title": "Beziehung kann nicht hinzugefügt werden", // "relationships.isAuthorOf": "Authors", - "relationships.isAuthorOf": "AutorInnen", + "relationships.isAuthorOf": "Autor:innen", // "relationships.isAuthorOf.Person": "Authors (persons)", "relationships.isAuthorOf.Person": "AutorInnen (Personen)", // "relationships.isAuthorOf.OrgUnit": "Authors (organizational units)", - "relationships.isAuthorOf.OrgUnit": "AutorInnen (Organisationseinheiten)", + "relationships.isAuthorOf.OrgUnit": "Autor:innen (Organisationseinheiten)", // "relationships.isIssueOf": "Journal Issues", "relationships.isIssueOf": "Zeitschriftenausgaben", @@ -3925,7 +3872,7 @@ "relationships.isOrgUnitOf": "Organisationseinheiten", // "relationships.isPersonOf": "Authors", - "relationships.isPersonOf": "AutorInnen", + "relationships.isPersonOf": "Autor:innen", // "relationships.isProjectOf": "Research Projects", "relationships.isProjectOf": "Forschungsvorhaben", @@ -3957,24 +3904,19 @@ "resource-policies.add.for.": "Eine neue Richtlinie hinzufügen", // "resource-policies.add.for.bitstream": "Add a new Bitstream policy", - // TODO New key - Add a translation - "resource-policies.add.for.bitstream": "Add a new Bitstream policy", + "resource-policies.add.for.bitstream": "Eine neue Datei-Richtlinie hinzufügen", // "resource-policies.add.for.bundle": "Add a new Bundle policy", - // TODO New key - Add a translation - "resource-policies.add.for.bundle": "Add a new Bundle policy", + "resource-policies.add.for.bundle": "Eine neue Bündel-Richtlinie hinzufügen", // "resource-policies.add.for.item": "Add a new Item policy", - // TODO New key - Add a translation - "resource-policies.add.for.item": "Add a new Item policy", + "resource-policies.add.for.item": "Eine neue Item-Richtlinie hinzufügen", // "resource-policies.add.for.community": "Add a new Community policy", - // TODO New key - Add a translation - "resource-policies.add.for.community": "Add a new Community policy", + "resource-policies.add.for.community": "Eine neue Bereiche-Richtlinie hinzufügen", // "resource-policies.add.for.collection": "Add a new Collection policy", - // TODO New key - Add a translation - "resource-policies.add.for.collection": "Add a new Collection policy", + "resource-policies.add.for.collection": "Eine neue Sammlungen-Richtlinie hinzufügen", // "resource-policies.create.page.heading": "Create new resource policy for ", // TODO New key - Add a translation @@ -4021,15 +3963,13 @@ "resource-policies.edit.page.title": "Edit resource policy", // "resource-policies.form.action-type.label": "Select the action type", - // TODO New key - Add a translation - "resource-policies.form.action-type.label": "Select the action type", + "resource-policies.form.action-type.label": "Wählen Sie die Aktionsart", // "resource-policies.form.action-type.required": "You must select the resource policy action.", // TODO New key - Add a translation "resource-policies.form.action-type.required": "You must select the resource policy action.", // "resource-policies.form.eperson-group-list.label": "The eperson or group that will be granted the permission", - // TODO New key - Add a translation "resource-policies.form.eperson-group-list.label": "Die Person oder Gruppe, der die Genehmigung erteilt wird", // "resource-policies.form.eperson-group-list.select.btn": "Select", @@ -4064,16 +4004,14 @@ "resource-policies.form.name.label": "Name", // "resource-policies.form.policy-type.label": "Select the policy type", - // TODO New key - Add a translation - "resource-policies.form.policy-type.label": "Select the policy type", + "resource-policies.form.policy-type.label": "Wählen Sie den Richtlinientyp", // "resource-policies.form.policy-type.required": "You must select the resource policy type.", // TODO New key - Add a translation "resource-policies.form.policy-type.required": "You must select the resource policy type.", // "resource-policies.table.headers.action": "Action", - // TODO New key - Add a translation - "resource-policies.table.headers.action": "Action", + "resource-policies.table.headers.action": "Aktion", // "resource-policies.table.headers.date.end": "End Date", "resource-policies.table.headers.date.end": "Enddatum", @@ -4106,24 +4044,19 @@ "resource-policies.table.headers.policyType": "Typ", // "resource-policies.table.headers.title.for.bitstream": "Policies for Bitstream", - // TODO New key - Add a translation - "resource-policies.table.headers.title.for.bitstream": "Policies for Bitstream", + "resource-policies.table.headers.title.for.bitstream": "Richtlinien für Dateien", // "resource-policies.table.headers.title.for.bundle": "Policies for Bundle", - // TODO New key - Add a translation - "resource-policies.table.headers.title.for.bundle": "Policies for Bundle", + "resource-policies.table.headers.title.for.bundle": "Richtlinien für Bündel", // "resource-policies.table.headers.title.for.item": "Policies for Item", - // TODO New key - Add a translation - "resource-policies.table.headers.title.for.item": "Policies for Item", + "resource-policies.table.headers.title.for.item": "Richtlinien für Items", // "resource-policies.table.headers.title.for.community": "Policies for Community", - // TODO New key - Add a translation - "resource-policies.table.headers.title.for.community": "Policies for Community", + "resource-policies.table.headers.title.for.community": "Richtlinien für Bereiche", // "resource-policies.table.headers.title.for.collection": "Policies for Collection", - // TODO New key - Add a translation - "resource-policies.table.headers.title.for.collection": "Policies for Collection", + "resource-policies.table.headers.title.for.collection": "Richtlinien für Sammlungen", @@ -4143,7 +4076,7 @@ "search.search-form.placeholder": "Durchsuche Repositorium", // "search.filters.applied.f.author": "Author", - "search.filters.applied.f.author": "AutorIn", + "search.filters.applied.f.author": "Autor:in", // "search.filters.applied.f.dateIssued.max": "End date", "search.filters.applied.f.dateIssued.max": "Enddatum", @@ -4173,7 +4106,7 @@ "search.filters.applied.f.subject": "Thema", // "search.filters.applied.f.submitter": "Submitter", - "search.filters.applied.f.submitter": "Einreichende(r)", + "search.filters.applied.f.submitter": "Einreichende:r", // "search.filters.applied.f.jobTitle": "Job Title", "search.filters.applied.f.jobTitle": "Berufsbezeichnung", @@ -4190,10 +4123,10 @@ // "search.filters.filter.author.head": "Author", - "search.filters.filter.author.head": "AutorIn", + "search.filters.filter.author.head": "Autor:in", // "search.filters.filter.author.placeholder": "Author name", - "search.filters.filter.author.placeholder": "Name des/r AutorIn", + "search.filters.filter.author.placeholder": "Name des/der Autor:in", // "search.filters.filter.birthDate.head": "Birth Date", "search.filters.filter.birthDate.head": "Geburtsdatum", @@ -4208,10 +4141,10 @@ "search.filters.filter.creativeDatePublished.placeholder": "Erscheinungsdatum", // "search.filters.filter.creativeWorkEditor.head": "Editor", - "search.filters.filter.creativeWorkEditor.head": "Herausgeber", + "search.filters.filter.creativeWorkEditor.head": "Herausgeber:in", // "search.filters.filter.creativeWorkEditor.placeholder": "Editor", - "search.filters.filter.creativeWorkEditor.placeholder": "Herausgeber", + "search.filters.filter.creativeWorkEditor.placeholder": "Herausgeber:in", // "search.filters.filter.creativeWorkKeywords.head": "Subject", "search.filters.filter.creativeWorkKeywords.head": "Thema", @@ -4322,10 +4255,10 @@ "search.filters.filter.subject.placeholder": "Thema", // "search.filters.filter.submitter.head": "Submitter", - "search.filters.filter.submitter.head": "Einreichende(r)", + "search.filters.filter.submitter.head": "Einreichende:r", // "search.filters.filter.submitter.placeholder": "Submitter", - "search.filters.filter.submitter.placeholder": "Einreichende(r)", + "search.filters.filter.submitter.placeholder": "Einreichende:r", @@ -4591,10 +4524,10 @@ "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "Import Remote Author", // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "Successfully added local author to the selection", - "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "Erfolgreicher Import und Hinzufügen eines lokalen Autors zur Auswahl", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "Erfolgreicher Import und Hinzufügen eines/einer lokalen Autor:in zur Auswahl", // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.new-entity": "Successfully imported and added external author to the selection", - "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.new-entity": "Erfolgreicher Import und Hinzufügen eines externen Autors zur Auswahl", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.new-entity": "Erfolgreicher Import und Hinzufügen eines/einer externen Autor:in zur Auswahl", // "submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "Authority", "submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "Referenz", @@ -4756,12 +4689,10 @@ "submission.sections.describe.relationship-lookup.search-tab.tab-title.arxiv": "arXiv ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfPublication": "Search for Funding Agencies", - // TODO New key - Add a translation "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfPublication": "Suche nach Fördereinrichtungen", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingOfPublication": "Search for Funding", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingOfPublication": "Search for Funding", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingOfPublication": "Suche nach Förderungen", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isChildOrgUnitOf": "Search for Organizational Units", "submission.sections.describe.relationship-lookup.search-tab.tab-title.isChildOrgUnitOf": "Suche nach Organisationseinheiten", @@ -4783,7 +4714,7 @@ "submission.sections.describe.relationship-lookup.title.isJournalOfPublication": "Zeitschriften", // "submission.sections.describe.relationship-lookup.title.isAuthorOfPublication": "Authors", - "submission.sections.describe.relationship-lookup.title.isAuthorOfPublication": "AutorInnen", + "submission.sections.describe.relationship-lookup.title.isAuthorOfPublication": "Autor:innen", // "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfPublication": "Funding Agency", "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfPublication": "Fördereinrichtung", @@ -4794,14 +4725,13 @@ "submission.sections.describe.relationship-lookup.title.Publication": "Publikationen", // "submission.sections.describe.relationship-lookup.title.Person": "Authors", - "submission.sections.describe.relationship-lookup.title.Person": "AutorInnen", + "submission.sections.describe.relationship-lookup.title.Person": "Autor:innen", // "submission.sections.describe.relationship-lookup.title.OrgUnit": "Organizational Units", "submission.sections.describe.relationship-lookup.title.OrgUnit": "Organisationseinheiten", // "submission.sections.describe.relationship-lookup.title.DataPackage": "Data Packages", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.DataPackage": "Data Packages", + "submission.sections.describe.relationship-lookup.title.DataPackage": "Datenpakete", // "submission.sections.describe.relationship-lookup.title.DataFile": "Data Files", // TODO New key - Add a translation @@ -4811,12 +4741,10 @@ "submission.sections.describe.relationship-lookup.title.Funding Agency": "Fördereinrichtung", // "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Funding", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Funding", + "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Förderung", // "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "Parent Organizational Unit", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "Parent Organizational Unit", + "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "Übergeordnete Organisationeinheit", // "submission.sections.describe.relationship-lookup.search-tab.toggle-dropdown": "Toggle dropdown", "submission.sections.describe.relationship-lookup.search-tab.toggle-dropdown": "Liste umschalten", @@ -4828,13 +4756,14 @@ "submission.sections.describe.relationship-lookup.selection-tab.no-selection": "Ihre Auswahl ist momentan leer.", // "submission.sections.describe.relationship-lookup.selection-tab.title.isAuthorOfPublication": "Selected Authors", - "submission.sections.describe.relationship-lookup.selection-tab.title.isAuthorOfPublication": "Ausgewählte AutorInnen", + "submission.sections.describe.relationship-lookup.selection-tab.title.isAuthorOfPublication": "Ausgewählte Autor:innen", // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalOfPublication": "Selected Journals", "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalOfPublication": "Ausgewählte Zeitschriften", // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalVolumeOfPublication": "Selected Journal Volume", "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalVolumeOfPublication": "Ausgewählte Zeitschriftenbände", + // "submission.sections.describe.relationship-lookup.selection-tab.title.Project": "Selected Projects", "submission.sections.describe.relationship-lookup.selection-tab.title.Project": "Ausgewählte Projekte", @@ -4842,14 +4771,13 @@ "submission.sections.describe.relationship-lookup.selection-tab.title.Publication": "Ausgewählte Publikationen", // "submission.sections.describe.relationship-lookup.selection-tab.title.Person": "Selected Authors", - "submission.sections.describe.relationship-lookup.selection-tab.title.Person": "Ausgewählte AutorInnen", + "submission.sections.describe.relationship-lookup.selection-tab.title.Person": "Ausgewählte Autor:innen", // "submission.sections.describe.relationship-lookup.selection-tab.title.OrgUnit": "Selected Organizational Units", "submission.sections.describe.relationship-lookup.selection-tab.title.OrgUnit": "Ausgewählte Organisationseinheiten", // "submission.sections.describe.relationship-lookup.selection-tab.title.DataPackage": "Selected Data Packages", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.DataPackage": "Selected Data Packages", + "submission.sections.describe.relationship-lookup.selection-tab.title.DataPackage": "Ausgewählte Datenpakete", // "submission.sections.describe.relationship-lookup.selection-tab.title.DataFile": "Selected Data Files", // TODO New key - Add a translation @@ -4860,6 +4788,7 @@ // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalIssueOfPublication": "Selected Issue", "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalIssueOfPublication": "Ausgewählte Ausgaben", + // "submission.sections.describe.relationship-lookup.selection-tab.title.JournalVolume": "Selected Journal Volume", "submission.sections.describe.relationship-lookup.selection-tab.title.JournalVolume": "Ausgewählte Zeitschriftenbände", @@ -4867,8 +4796,8 @@ "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingAgencyOfPublication": "Ausgewählte Fördereinrichtung", // "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingOfPublication": "Selected Funding", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingOfPublication": "Selected Funding", + "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingOfPublication": "Ausgewählte Förderung", + // "submission.sections.describe.relationship-lookup.selection-tab.title.JournalIssue": "Selected Issue", "submission.sections.describe.relationship-lookup.selection-tab.title.JournalIssue": "Ausgewählte Ausgabe", @@ -5110,7 +5039,7 @@ "submission.workflow.tasks.claimed.edit_help": "Wählen Sie diese Option, um die Metadaten der Ressource zu bearbeiten.", // "submission.workflow.tasks.claimed.reject.reason.info": "Please enter your reason for rejecting the submission into the box below, indicating whether the submitter may fix a problem and resubmit.", - "submission.workflow.tasks.claimed.reject.reason.info": "Bitte geben Sie den Grund für die Ablehnung der eingereichten Ressource in das Feld unten ein. Bitte geben Sie an ob und wie der/die Einreichenden das Problem beheben und die Ressource erneut einreichen kann.", + "submission.workflow.tasks.claimed.reject.reason.info": "Bitte geben Sie den Grund für die Ablehnung der eingereichten Ressource in das Feld unten ein. Bitte geben Sie an ob und wie der/die Einreichende:n das Problem beheben und die Ressource erneut einreichen kann.", // "submission.workflow.tasks.claimed.reject.reason.placeholder": "Describe the reason of reject", "submission.workflow.tasks.claimed.reject.reason.placeholder": "Beschreiben Sie den Grund für die Ablehnung", @@ -5142,7 +5071,7 @@ "submission.workflow.tasks.generic.processing": "Verarbeitung läuft...", // "submission.workflow.tasks.generic.submitter": "Submitter", - "submission.workflow.tasks.generic.submitter": "Einreichende(r)", + "submission.workflow.tasks.generic.submitter": "Einreichende:r", // "submission.workflow.tasks.generic.success": "Operation successful", "submission.workflow.tasks.generic.success": "Aktion erfolgreich", @@ -5169,32 +5098,25 @@ // "vocabulary-treeview.header": "Hierarchical tree view", - // TODO New key - Add a translation - "vocabulary-treeview.header": "Hierarchical tree view", + "vocabulary-treeview.header": "Hierarchische Baumstruktur", // "vocabulary-treeview.load-more": "Load more", - // TODO New key - Add a translation - "vocabulary-treeview.load-more": "Load more", + "vocabulary-treeview.load-more": "Mehr laden", // "vocabulary-treeview.search.form.reset": "Reset", - // TODO New key - Add a translation - "vocabulary-treeview.search.form.reset": "Reset", + "vocabulary-treeview.search.form.reset": "Zurücksetzen", // "vocabulary-treeview.search.form.search": "Search", - // TODO New key - Add a translation - "vocabulary-treeview.search.form.search": "Search", + "vocabulary-treeview.search.form.search": "Suche", // "vocabulary-treeview.search.no-result": "There were no items to show", - // TODO New key - Add a translation - "vocabulary-treeview.search.no-result": "There were no items to show", + "vocabulary-treeview.search.no-result": "Es gibt keine Items zu zeigen", // "vocabulary-treeview.tree.description.nsi": "The Norwegian Science Index", - // TODO New key - Add a translation - "vocabulary-treeview.tree.description.nsi": "The Norwegian Science Index", + "vocabulary-treeview.tree.description.nsi": "Der norwegische Wissenschaftsindex", // "vocabulary-treeview.tree.description.srsc": "Research Subject Categories", - // TODO New key - Add a translation - "vocabulary-treeview.tree.description.srsc": "Research Subject Categories", + "vocabulary-treeview.tree.description.srsc": "Kategorien von Forschungsthemen", @@ -5205,8 +5127,7 @@ "uploader.drag-message": "Ziehen Sie Ihre Dateien hierhin", // "uploader.or": ", or ", - // TODO Source message changed - Revise the translation - "uploader.or": " oder", + "uploader.or": ", oder", // "uploader.processing": "Processing", "uploader.processing": "Bearbeitung läuft", @@ -5226,74 +5147,57 @@ // "workflowAdmin.search.results.head": "Administer Workflow", - // TODO New key - Add a translation - "workflowAdmin.search.results.head": "Administer Workflow", + "workflowAdmin.search.results.head": "Workflow verwalten", // "workflow-item.delete.notification.success.title": "Deleted", - // TODO New key - Add a translation - "workflow-item.delete.notification.success.title": "Deleted", + "workflow-item.delete.notification.success.title": "Gelöscht", // "workflow-item.delete.notification.success.content": "This workflow item was successfully deleted", - // TODO New key - Add a translation - "workflow-item.delete.notification.success.content": "This workflow item was successfully deleted", + "workflow-item.delete.notification.success.content": "Dieses Workflow-Item wurde erfolgreich gelöscht", // "workflow-item.delete.notification.error.title": "Something went wrong", - // TODO New key - Add a translation - "workflow-item.delete.notification.error.title": "Something went wrong", + "workflow-item.delete.notification.error.title": "Etwas ist schief gelaufen", // "workflow-item.delete.notification.error.content": "The workflow item could not be deleted", - // TODO New key - Add a translation - "workflow-item.delete.notification.error.content": "The workflow item could not be deleted", + "workflow-item.delete.notification.error.content": "Das Workflow-Item konnte nicht gelöscht werden", // "workflow-item.delete.title": "Delete workflow item", - // TODO New key - Add a translation - "workflow-item.delete.title": "Delete workflow item", + "workflow-item.delete.title": "Workflow-Item löschen", // "workflow-item.delete.header": "Delete workflow item", - // TODO New key - Add a translation - "workflow-item.delete.header": "Delete workflow item", + "workflow-item.delete.header": "Workflow-Item löschen", // "workflow-item.delete.button.cancel": "Cancel", - // TODO New key - Add a translation - "workflow-item.delete.button.cancel": "Cancel", + "workflow-item.delete.button.cancel": "Abbrechen", // "workflow-item.delete.button.confirm": "Delete", - // TODO New key - Add a translation - "workflow-item.delete.button.confirm": "Delete", + "workflow-item.delete.button.confirm": "Löschen", // "workflow-item.send-back.notification.success.title": "Sent back to submitter", - // TODO New key - Add a translation - "workflow-item.send-back.notification.success.title": "Sent back to submitter", + "workflow-item.send-back.notification.success.title": "An die/den Einreichende:n zurückgeschickt", // "workflow-item.send-back.notification.success.content": "This workflow item was successfully sent back to the submitter", - // TODO New key - Add a translation - "workflow-item.send-back.notification.success.content": "This workflow item was successfully sent back to the submitter", + "workflow-item.send-back.notification.success.content": "Dieses Workflow-Item wurde erfolgreich an die/den Einreichende:n zurückgeschickt", // "workflow-item.send-back.notification.error.title": "Something went wrong", - // TODO New key - Add a translation - "workflow-item.send-back.notification.error.title": "Something went wrong", + "workflow-item.send-back.notification.error.title": "Etwas ist schief gelaufen", // "workflow-item.send-back.notification.error.content": "The workflow item could not be sent back to the submitter", - // TODO New key - Add a translation - "workflow-item.send-back.notification.error.content": "The workflow item could not be sent back to the submitter", + "workflow-item.send-back.notification.error.content": "Das Workflow-Item konnte nicht an die/den Einreichende:n zurückgeschickt werden", // "workflow-item.send-back.title": "Send workflow item back to submitter", - // TODO New key - Add a translation - "workflow-item.send-back.title": "Send workflow item back to submitter", + "workflow-item.send-back.title": "Workflow-Item an die/den Einreichende:n zurücksenden", // "workflow-item.send-back.header": "Send workflow item back to submitter", - // TODO New key - Add a translation - "workflow-item.send-back.header": "Send workflow item back to submitter", + "workflow-item.send-back.header": "Workflow-Item an die/den Einreichende:n zurücksenden", // "workflow-item.send-back.button.cancel": "Cancel", - // TODO New key - Add a translation - "workflow-item.send-back.button.cancel": "Cancel", + "workflow-item.send-back.button.cancel": "Abbrechen", // "workflow-item.send-back.button.confirm": "Send back" - // TODO New key - Add a translation - "workflow-item.send-back.button.confirm": "Send back" + "workflow-item.send-back.button.confirm": "Zurücksenden" } From 3bbd2d9d6405b802b9a020533c6c9dc9e37ecaa5 Mon Sep 17 00:00:00 2001 From: YPaulsen-TLC Date: Fri, 14 Jan 2022 14:05:41 +0100 Subject: [PATCH 0077/2129] message key translations Final German message keys translations for DSpace 7, --- src/assets/i18n/de.json5 | 454 +++++++++++++++++---------------------- 1 file changed, 194 insertions(+), 260 deletions(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index 77105cc7aa8..d3fc1131aa4 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -483,8 +483,7 @@ "admin.access-control.groups.form.alert.permanent": "Diese Gruppe ist permanent, das heißt sie kann nicht bearbeitet oder gelöscht werden. Sie können jedoch über diese Seite Gruppenmitglieder hinzufügen und entfernen.", // "admin.access-control.groups.form.alert.workflowGroup": "This group can’t be modified or deleted because it corresponds to a role in the submission and workflow process in the \"{{name}}\" {{comcol}}. You can delete it from the \"assign roles\" tab on the edit {{comcol}} page. You can still add and remove group members using this page.", - // TODO New key - Add a translation - "admin.access-control.groups.form.alert.workflowGroup": "This group can’t be modified or deleted because it corresponds to a role in the submission and workflow process in the \"{{name}}\" {{comcol}}. You can delete it from the \"assign roles\" tab on the edit {{comcol}} page. You can still add and remove group members using this page.", + "admin.access-control.groups.form.alert.workflowGroup": "Diese Gruppe kann nicht geändert oder gelöscht werden, da sie einer Rolle im Einreichungs- und Workflow-Prozess im \"{{name}}\" {{comcol}} zugeordnet ist. Sie können sie über die Registerkarte \"assign roles\" auf der Bearbeitungsseite {{comcol}} löschen. Sie können über diese Seite weiterhin Gruppenmitglieder hinzufügen und entfernen.", // "admin.access-control.groups.form.head.create": "Create group", "admin.access-control.groups.form.head.create": "Gruppe erstellen", @@ -766,9 +765,8 @@ "bitstream.edit.form.description.label": "Beschreibung", // "bitstream.edit.form.embargo.hint": "The first day from which access is allowed. This date cannot be modified on this form. To set an embargo date for a bitstream, go to the Item Status tab, click Authorizations..., create or edit the bitstream's READ policy, and set the Start Date as desired.", - // TODO New key - Add a translation - "bitstream.edit.form.embargo.hint": "The first day from which access is allowed. This date cannot be modified on this form. To set an embargo date for a bitstream, go to the Item Status tab, click Authorizations..., create or edit the bitstream's READ policy, and set the Start Date as desired.", - // Der erste Tag, ab wann der Zugriff möglich ist. Dieses Datum kann in dieser Form nicht verändert werden. Um eine Embargo-Frist für eine Datei festzulegen, zu dem ()-Tab gehen, auf () klicken, die ()-Richtline für die Datei erstellen oder verändern und das Startdatum wie gewünscht einstellen. + "bitstream.edit.form.embargo.hint": "Der erste Tag, ab dem der Zugang erlaubt ist. This date cannot be modified on this form. Um eine Embargo-Frist für eine Datei festzulegen, zu Item Status gehen, auf Authorizations... klicken, die Richtlinie READ für die Datei erstellen oder verändern und das Start Date wie gewünscht einstellen.", + // "bitstream.edit.form.embargo.label": "Embargo until specific date", "bitstream.edit.form.embargo.label": "Embargo bis zu einem bestimmten Datum", @@ -827,7 +825,7 @@ "browse.comcol.head": "Listen", // "browse.empty": "No items to show.", - "browse.empty": "Es gibt keine Dokumente, die angezeigt werden können.", + "browse.empty": "Es gibt keine Items, die angezeigt werden können.", // "browse.metadata.author": "Author", "browse.metadata.author": "Autor:in", @@ -963,10 +961,10 @@ // "collection.edit.tabs.mapper.head": "Item Mapper", - "collection.edit.tabs.mapper.head": "Ressource spiegeln", + "collection.edit.tabs.mapper.head": "Item spiegeln", // "collection.edit.tabs.item-mapper.title": "Collection Edit - Item Mapper", - "collection.edit.tabs.item-mapper.title": "Sammlung bearbeiten - Ressource spiegeln", + "collection.edit.tabs.item-mapper.title": "Sammlung bearbeiten - Item spiegeln", // "collection.edit.item-mapper.cancel": "Cancel", "collection.edit.item-mapper.cancel": "Abbrechen", @@ -975,13 +973,13 @@ "collection.edit.item-mapper.collection": "Sammlung: \"{{name}}\"", // "collection.edit.item-mapper.confirm": "Map selected items", - "collection.edit.item-mapper.confirm": "Ausgewählte Ressourcen spiegeln", + "collection.edit.item-mapper.confirm": "Ausgewählte Items spiegeln", // "collection.edit.item-mapper.description": "This is the item mapper tool that allows collection administrators to map items from other collections into this collection. You can search for items from other collections and map them, or browse the list of currently mapped items.", - "collection.edit.item-mapper.description": "Sammlungsadministrator:innen haben die Möglichkeit Ressourcen von einer Sammlung in eine andere zu spiegeln. Man kann nach Ressourcen in anderen Sammlungen suchen und diese spiegeln oder sich eine Liste der gespiegelten Ressourcen anzeigen lassen.", + "collection.edit.item-mapper.description": "Sammlungsadministrator:innen haben die Möglichkeit Items von einer Sammlung in eine andere zu spiegeln. Man kann nach Items in anderen Sammlungen suchen und diese spiegeln oder sich eine Liste der gespiegelten Items anzeigen lassen.", // "collection.edit.item-mapper.head": "Item Mapper - Map Items from Other Collections", - "collection.edit.item-mapper.head": "Ressourcen spiegeln - Spiegelt Ressourcen aus anderen Sammlungen", + "collection.edit.item-mapper.head": "Item spiegeln - Spiegelt Items aus anderen Sammlungen", // "collection.edit.item-mapper.no-search": "Please enter a query to search", "collection.edit.item-mapper.no-search": "Bitte geben Sie eine Suchanfrage ein.", @@ -993,13 +991,13 @@ "collection.edit.item-mapper.notifications.map.error.head": "Fehler beim Spiegeln", // "collection.edit.item-mapper.notifications.map.success.content": "Successfully mapped {{amount}} items.", - "collection.edit.item-mapper.notifications.map.success.content": "{{amount}} Ressource(n) erfolgreich gespiegelt.", + "collection.edit.item-mapper.notifications.map.success.content": "{{amount}} Item(s) erfolgreich gespiegelt.", // "collection.edit.item-mapper.notifications.map.success.head": "Mapping completed", "collection.edit.item-mapper.notifications.map.success.head": "Spiegelung abgeschlossen", // "collection.edit.item-mapper.notifications.unmap.error.content": "Errors occurred for removing the mappings of {{amount}} items.", - "collection.edit.item-mapper.notifications.unmap.error.content": "Beim Spiegeln von {{amount}} Ressource(n) ist ein Fehler aufgetreten.", + "collection.edit.item-mapper.notifications.unmap.error.content": "Beim Spiegeln von {{amount}} Item(s) ist ein Fehler aufgetreten.", // "collection.edit.item-mapper.notifications.unmap.error.head": "Remove mapping errors", "collection.edit.item-mapper.notifications.unmap.error.head": "Spiegeln Entfernen Fehler", @@ -1011,13 +1009,13 @@ "collection.edit.item-mapper.notifications.unmap.success.head": "Spiegelung entfernen abgeschlossen", // "collection.edit.item-mapper.remove": "Remove selected item mappings", - "collection.edit.item-mapper.remove": "Spiegelung der gewählten Ressourcen entfernen.", + "collection.edit.item-mapper.remove": "Spiegelung der gewählten Items entfernen.", // "collection.edit.item-mapper.tabs.browse": "Browse mapped items", - "collection.edit.item-mapper.tabs.browse": "Gespiegelte Ressourcen auflisten", + "collection.edit.item-mapper.tabs.browse": "Gespiegelte Items auflisten", // "collection.edit.item-mapper.tabs.map": "Map new items", - "collection.edit.item-mapper.tabs.map": "Neue Ressourcen spiegeln", + "collection.edit.item-mapper.tabs.map": "Neue Items spiegeln", @@ -1062,8 +1060,7 @@ "collection.edit.tabs.authorizations.head": "Berechtigungen", // "collection.edit.tabs.authorizations.title": "Collection Edit - Authorizations", - // TODO New key - Add a translation - "collection.edit.tabs.authorizations.title": "Collection Edit - Authorizations", + "collection.edit.tabs.authorizations.title": "Sammlung bearbeiten - Berechtigungen", // "collection.edit.tabs.metadata.head": "Edit Metadata", "collection.edit.tabs.metadata.head": "Metadaten bearbeiten", @@ -1149,20 +1146,19 @@ "collection.edit.template.edit-button": "Bearbeiten", // "collection.edit.template.head": "Edit Template Item for Collection \"{{ collection }}\"", - // TODO New key - Add a translation - "collection.edit.template.head": "Itemvorlage für Collection \"{{ collection }}\" bearbeiten", + "collection.edit.template.head": "Itemvorlage für Sammlung \"{{ collection }}\" bearbeiten", // "collection.edit.template.label": "Template item", "collection.edit.template.label": "Itemvorlage", // "collection.edit.template.notifications.delete.error": "Failed to delete the item template", - "collection.edit.template.notifications.delete.error": "Löschen der Itemvorlage fehlgeschlagen", + "collection.edit.template.notifications.delete.error": "Löschen der Metadatenvorlage fehlgeschlagen", // "collection.edit.template.notifications.delete.success": "Successfully deleted the item template", - "collection.edit.template.notifications.delete.success": "Die Itemvorlage wurde erfolgreich gelöscht", + "collection.edit.template.notifications.delete.success": "Die Metadatenvorlage wurde erfolgreich gelöscht", // "collection.edit.template.title": "Edit Template Item", - "collection.edit.template.title": "Itemvorlage bearbeiten", + "collection.edit.template.title": "Metadatenvorlage bearbeiten", @@ -1201,7 +1197,7 @@ "collection.page.browse.recent.head": "Neueste Veröffentlichungen", // "collection.page.browse.recent.empty": "No items to show", - "collection.page.browse.recent.empty": "Es gibt keine Ressourcen zum Anzeigen", + "collection.page.browse.recent.empty": "Es gibt keine Items zum Anzeigen", // "collection.page.edit": "Edit this collection", "collection.page.edit": "Diese Sammlung bearbeiten", @@ -1362,8 +1358,7 @@ "comcol-role.edit.create": "Erstellen", // "comcol-role.edit.restrict": "Restrict", - // TODO New key - Add a translation - "comcol-role.edit.restrict": "Restrict", + "comcol-role.edit.restrict": "Beschränken", // "comcol-role.edit.delete": "Delete", "comcol-role.edit.delete": "Löschen", @@ -1377,29 +1372,24 @@ // "comcol-role.edit.community-admin.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", - // TODO New key - Add a translation - "comcol-role.edit.community-admin.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", + "comcol-role.edit.community-admin.description": "Community-Administrator:innen können Teilbereiche oder Sammlungen erstellen, verwalten oder die Verwaltung anderen zuweisen. Darüber hinaus entscheiden sie, wer Items zu einer Teilsammlung einreichen, Item-Metadaten bearbeiten (nach der Einreichung) und bestehende Items von anderen Sammlungen verknüpfen kann (vorbehaltlich einer Berechtigung).", // "comcol-role.edit.collection-admin.description": "Collection administrators decide who can submit items to the collection, edit item metadata (after submission), and add (map) existing items from other collections to this collection (subject to authorization for that collection).", - // TODO New key - Add a translation - "comcol-role.edit.collection-admin.description": "Collection administrators decide who can submit items to the collection, edit item metadata (after submission), and add (map) existing items from other collections to this collection (subject to authorization for that collection).", + "comcol-role.edit.collection-admin.description": "Sammlungsadministrator:innen entscheiden, wer Items zu einer Sammlung einreichen, Item-Metadaten bearbeiten (nach der Einreichung) and und bestehende Items von anderen Sammlungen mit dieser Sammlung verknüpfen kann (vorbehaltlich einer Berechtigung für diese Sammlung).", // "comcol-role.edit.submitters.name": "Submitters", "comcol-role.edit.submitters.name": "Einreichende", // "comcol-role.edit.submitters.description": "The E-People and Groups that have permission to submit new items to this collection.", - // TODO New key - Add a translation - "comcol-role.edit.submitters.description": "The E-People and Groups that have permission to submit new items to this collection.", + "comcol-role.edit.submitters.description": "Die Personen und Gruppen, die die Berechtigungen haben, neue Items zu dieser Sammlung einzureichen.", // "comcol-role.edit.item_read.name": "Default item read access", - // TODO New key - Add a translation - "comcol-role.edit.item_read.name": "Default item read access", + "comcol-role.edit.item_read.name": "Standard-Lesezugriff Item", // "comcol-role.edit.item_read.description": "E-People and Groups that can read new items submitted to this collection. Changes to this role are not retroactive. Existing items in the system will still be viewable by those who had read access at the time of their addition.", - // TODO New key - Add a translation - "comcol-role.edit.item_read.description": "E-People and Groups that can read new items submitted to this collection. Changes to this role are not retroactive. Existing items in the system will still be viewable by those who had read access at the time of their addition.", + "comcol-role.edit.item_read.description": "Personen und Gruppen, die neu eingereichte Items dieser Sammlung lesen können. Änderungen an dieser Rolle sind nicht rückwirkend. Bestehende Items im System können weiterhin von denjenigen eingesehen werden, die zum Zeitpunkt des Hinzufügens Lesezugriff hatten.", // "comcol-role.edit.item_read.anonymous-group": "Default read for incoming items is currently set to Anonymous.", "comcol-role.edit.item_read.anonymous-group": "Die Standardeinstellung für das Lesen eingehender Items ist derzeit auf Anonym eingestellt.", @@ -1409,8 +1399,7 @@ "comcol-role.edit.bitstream_read.name": "Standard-Lesezugriff Datei", // "comcol-role.edit.bitstream_read.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", - // TODO New key - Add a translation - "comcol-role.edit.bitstream_read.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", + "comcol-role.edit.bitstream_read.description": "Community-Administrator:innen können Teilbereiche oder Sammlungen erstellen, verwalten oder die Verwaltung anderen zuweisen. Darüber hinaus entscheiden sie, wer Items zu einer Teilsammlung einreichen, Item-Metadaten bearbeiten (nach der Einreichung) und bestehende Items von anderen Sammlungen verknüpfen kann (vorbehaltlich einer Berechtigung).", // "comcol-role.edit.bitstream_read.anonymous-group": "Default read for incoming bitstreams is currently set to Anonymous.", "comcol-role.edit.bitstream_read.anonymous-group": "Die Standardeinstellung für das Lesen eingehender Dateien ist derzeit auf Anonym eingestellt.", @@ -1486,11 +1475,9 @@ "cookies.consent.accept-selected": "Ausgewählte annehmen", // "cookies.consent.app.opt-out.description": "This app is loaded by default (but you can opt out)", - // TODO New key - Add a translation - "cookies.consent.app.opt-out.description": "This app is loaded by default (but you can opt out)", + "cookies.consent.app.opt-out.description": "Diese App wird standardmäßig geladen (Sie können dies jedoch deaktivieren)", // "cookies.consent.app.opt-out.title": "(opt-out)", - // TODO New key - Add a translation "cookies.consent.app.opt-out.title": "(opt-out)", // "cookies.consent.app.purpose": "purpose", @@ -1512,8 +1499,7 @@ "cookies.consent.decline": "Ablehnen", // "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: Authentication, Preferences, Acknowledgement and Statistics.
    To learn more, please read our {privacyPolicy}.", - // TODO New key - Add a translation - "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: Authentication, Preferences, Acknowledgement and Statistics.
    To learn more, please read our {privacyPolicy}.", + "cookies.consent.content-notice.description": "Wir sammeln und verarbeiten Ihre personenbezogenen Daten für die folgenden Zwecke: Authentication, Preferences, Acknowledgement and Statistics.
    Um mehr zu erfahren, lesen Sie bitte unsere {privacyPolicy}.", // "cookies.consent.content-notice.learnMore": "Customize", "cookies.consent.content-notice.learnMore": "Anpassen", @@ -1574,12 +1560,10 @@ "curation-task.task.checklinks.label": "Links in Metadaten prüfen", // "curation-task.task.noop.label": "NOOP", - // TODO New key - Add a translation "curation-task.task.noop.label": "NOOP", // "curation-task.task.profileformats.label": "Profile Bitstream Formats", - // TODO New key - Add a translation - "curation-task.task.profileformats.label": "Profile Bitstream Formats", + "curation-task.task.profileformats.label": "Dateiformate auflisten", // "curation-task.task.requiredmetadata.label": "Check for Required Metadata", "curation-task.task.requiredmetadata.label": "Prüfung auf erforderliche Metadaten", @@ -1614,8 +1598,7 @@ "curation.form.handle.label": "Handle:", // "curation.form.handle.hint": "Hint: Enter [your-handle-prefix]/0 to run a task across entire site (not all tasks may support this capability)", - // TODO New key - Add a translation - "curation.form.handle.hint": "Hint: Enter [your-handle-prefix]/0 to run a task across entire site (not all tasks may support this capability)", + "curation.form.handle.hint": "Hinweis: Geben Sie [your-handle-prefix]/0 ein, um eine Aufgabe für die gesamte Seite durchzuführen (nicht alle Aufgaben unterstützen diese Funktion)", @@ -1635,7 +1618,7 @@ "dso-selector.create.community.top-level": "Einen neuen Bereich auf oberster Ebene anlgen", // "dso-selector.create.item.head": "New item", - "dso-selector.create.item.head": "Neue Ressource", + "dso-selector.create.item.head": "Neues Item", // "dso-selector.create.item.sub-level": "Create a new item in", "dso-selector.create.item.sub-level": "Ein neues Item erstellen in", @@ -1650,7 +1633,7 @@ "dso-selector.edit.community.head": "Bereich bearbeiten", // "dso-selector.edit.item.head": "Edit item", - "dso-selector.edit.item.head": "Ressource bearbeiten", + "dso-selector.edit.item.head": "Item bearbeiten", // "dso-selector.export-metadata.dspaceobject.head": "Export metadata from", "dso-selector.export-metadata.dspaceobject.head": "Exportieren der Metadaten aus", @@ -1689,11 +1672,10 @@ // "error.bitstream": "Error fetching bitstream", - // TODO New key - Add a translation - "error.bitstream": "Error fetching bitstream", + "error.bitstream": "Fehler beim Laden der Datei", // "error.browse-by": "Error fetching items", - "error.browse-by": "Fehler beim Laden der Ressourcen", + "error.browse-by": "Fehler beim Laden der Items", // "error.collection": "Error fetching collection", "error.collection": "Fehler beim Laden der Sammlung", @@ -1705,16 +1687,16 @@ "error.community": "Fehler beim Laden des Bereichs", // "error.identifier": "No item found for the identifier", - "error.identifier": "Zu dieser Kennung wurde keine Ressource gefunden", + "error.identifier": "Zu dieser Kennung wurde kein Item gefunden", // "error.default": "Error", "error.default": "Fehler", // "error.item": "Error fetching item", - "error.item": "Fehler beim Laden der Ressource", + "error.item": "Fehler beim Laden des Items", // "error.items": "Error fetching items", - "error.items": "Fehler beim Laden der Ressourcen", + "error.items": "Fehler beim Laden der Items", // "error.objects": "Error fetching objects", "error.objects": "Fehler beim Laden der Objekte", @@ -1777,8 +1759,7 @@ "forgot-email.form.header": "Passwort vergessen", // "forgot-email.form.info": "Enter Register an account to subscribe to collections for email updates, and submit new items to DSpace.", - // TODO New key - Add a translation - "forgot-email.form.info": "Enter Register an account to subscribe to collections for email updates, and submit new items to DSpace.", + "forgot-email.form.info": "Geben Sie einen Account ein, um Sammlungen für E-Mail-Updates zu abonnieren und neue Items an DSpace zu übermitteln.", // "forgot-email.form.email": "Email Address *", "forgot-email.form.email": "E-Mail-Addresse *", @@ -1799,14 +1780,12 @@ "forgot-email.form.success.head": "Verifizierungs-E-Mail gesendet", // "forgot-email.form.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", - // TODO New key - Add a translation - "forgot-email.form.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", + "forgot-email.form.success.content": "Es wurde eine E-Mail mit einer speziellen URL und weiteren Anweisungen an {{ email }} gesendet.", // "forgot-email.form.error.head": "Error when trying to register email", "forgot-email.form.error.head": "Fehler beim Versuch, die E-Mail zu registrieren", // "forgot-email.form.error.content": "An error occured when registering the following email address: {{ email }}", - // TODO New key - Add a translation "forgot-email.form.error.content": "Bei der Registrierung der folgenden E-Mail-Adresse ist ein Fehler aufgetreten: {{ email }}", @@ -1999,8 +1978,7 @@ // "item.edit.authorizations.heading": "With this editor you can view and alter the policies of an item, plus alter policies of individual item components: bundles and bitstreams. Briefly, an item is a container of bundles, and bundles are containers of bitstreams. Containers usually have ADD/REMOVE/READ/WRITE policies, while bitstreams only have READ/WRITE policies.", - // TODO New key - Add a translation - "item.edit.authorizations.heading": "With this editor you can view and alter the policies of an item, plus alter policies of individual item components: bundles and bitstreams. Briefly, an item is a container of bundles, and bundles are containers of bitstreams. Containers usually have ADD/REMOVE/READ/WRITE policies, while bitstreams only have READ/WRITE policies.", + "item.edit.authorizations.heading": "Mit diesem Editor können Sie die Richtlinien eines Items anzeigen und ändern sowie die Richtlinien der einzelnen Itemkomponenten, d. h. Bündel und Dateien, ändern. Kurz gesagt, ein Item ist ein Container von Bündeln, und Bündel sind Container von Dateien. Container haben normalerweise ADD/REMOVE/READ/WRITE-Richtlinien, während Dateien nur READ/WRITE-Richtlinien haben.", // "item.edit.authorizations.title": "Edit item's Policies", "item.edit.authorizations.title": "Item-Richtlinien bearbeiten", @@ -2025,8 +2003,7 @@ "item.bitstreams.upload.bundle.new": "Bündel erstellen", // "item.bitstreams.upload.bundles.empty": "This item doesn\'t contain any bundles to upload a bitstream to.", - // TODO New key - Add a translation - "item.bitstreams.upload.bundles.empty": "This item doesn\'t contain any bundles to upload a bitstream to.", + "item.bitstreams.upload.bundles.empty": "Dieses Item enthält keine Bündel, um eine Datei hochzuladen.", // "item.bitstreams.upload.cancel": "Cancel", "item.bitstreams.upload.cancel": "Abbrechen", @@ -2055,8 +2032,7 @@ "item.edit.bitstreams.bundle.edit.buttons.upload": "Hochladen", // "item.edit.bitstreams.bundle.displaying": "Currently displaying {{ amount }} bitstreams of {{ total }}.", - // TODO New key - Add a translation - "item.edit.bitstreams.bundle.displaying": "Currently displaying {{ amount }} bitstreams of {{ total }}.", + "item.edit.bitstreams.bundle.displaying": "Derzeit werden {{ amount }} Dateien von insgesamt {{ total }} angezeigt.", // "item.edit.bitstreams.bundle.load.all": "Load all ({{ total }})", "item.edit.bitstreams.bundle.load.all": "Alle ({{ total }}) laden", @@ -2086,7 +2062,7 @@ "item.edit.bitstreams.edit.buttons.undo": "Änderungen rückgängig machen", // "item.edit.bitstreams.empty": "This item doesn't contain any bitstreams. Click the upload button to create one.", - "item.edit.bitstreams.empty": "Diese Ressource enthält keine Dateien. Klicken Sie auf das Feld Hochladen, um eine zu erstellen.", + "item.edit.bitstreams.empty": "Dieses Item enthält keine Dateien. Klicken Sie auf das Feld Hochladen, um eine zu erstellen.", // "item.edit.bitstreams.headers.actions": "Actions", "item.edit.bitstreams.headers.actions": "Aktionen", @@ -2113,15 +2089,13 @@ "item.edit.bitstreams.notifications.move.failed.title": "Fehler beim Verschieben von Dateien", // "item.edit.bitstreams.notifications.move.saved.content": "Your move changes to this item's bitstreams and bundles have been saved.", - // TODO New key - Add a translation - "item.edit.bitstreams.notifications.move.saved.content": "Your move changes to this item's bitstreams and bundles have been saved.", + "item.edit.bitstreams.notifications.move.saved.content": "Die von Ihnen vorgenommenen Änderungen an den Dateien und Bündeln dieses Artikels wurden gespeichert.", // "item.edit.bitstreams.notifications.move.saved.title": "Move changes saved", - // TODO New key - Add a translation - "item.edit.bitstreams.notifications.move.saved.title": "Move changes saved", + "item.edit.bitstreams.notifications.move.saved.title": "Änderungen gespeichert", // "item.edit.bitstreams.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", - "item.edit.bitstreams.notifications.outdated.content": "Die Ressource, an der Sie gerade arbeiten, wurde von einem anderen Account geändert. Ihre aktuellen Änderungen werden verworfen, um Konflikte zu vermeiden.", + "item.edit.bitstreams.notifications.outdated.content": "Das Item, an der Sie gerade arbeiten, wurde von einem anderen Account geändert. Ihre aktuellen Änderungen werden verworfen, um Konflikte zu vermeiden.", // "item.edit.bitstreams.notifications.outdated.title": "Changes outdated", "item.edit.bitstreams.notifications.outdated.title": "Veraltete Änderungen", @@ -2130,12 +2104,10 @@ "item.edit.bitstreams.notifications.remove.failed.title": "Fehler beim Löschen der Datei", // "item.edit.bitstreams.notifications.remove.saved.content": "Your removal changes to this item's bitstreams have been saved.", - // TODO New key - Add a translation - "item.edit.bitstreams.notifications.remove.saved.content": "Your removal changes to this item's bitstreams have been saved.", + "item.edit.bitstreams.notifications.remove.saved.content": "Ihre Entfernungsänderungen an den Dateien dieses Items wurden gespeichert.", // "item.edit.bitstreams.notifications.remove.saved.title": "Removal changes saved", - // TODO New key - Add a translation - "item.edit.bitstreams.notifications.remove.saved.title": "Removal changes saved", + "item.edit.bitstreams.notifications.remove.saved.title": "Änderungen gespeichert", // "item.edit.bitstreams.reinstate-button": "Undo", "item.edit.bitstreams.reinstate-button": "Rückgängig", @@ -2155,59 +2127,59 @@ "item.edit.delete.confirm": "Löschen", // "item.edit.delete.description": "Are you sure this item should be completely deleted? Caution: At present, no tombstone would be left.", - "item.edit.delete.description": "Sind Sie sicher, dass diese Ressource komplett gelöscht werden soll. Warnung: Zur Zeit wird kein Grabstein hinterlassen", + "item.edit.delete.description": "Sind Sie sicher, dass dieses Item komplett gelöscht werden soll. Warnung: Zur Zeit wird kein Grabstein hinterlassen", // "item.edit.delete.error": "An error occurred while deleting the item", "item.edit.delete.error": "Beim Löschen der Ressource ist ein Fehler aufgetreten", // "item.edit.delete.header": "Delete item: {{ id }}", - "item.edit.delete.header": "Löschen der Ressource: {{ id }}", + "item.edit.delete.header": "Löschen des Items: {{ id }}", // "item.edit.delete.success": "The item has been deleted", - "item.edit.delete.success": "Die Ressource wurde gelöscht", + "item.edit.delete.success": "Das Item wurde gelöscht", // "item.edit.head": "Edit Item", - "item.edit.head": "Ressource bearbeiten", + "item.edit.head": "Item bearbeiten", // "item.edit.breadcrumbs": "Edit Item", - "item.edit.breadcrumbs": "Ressource bearbeiten", + "item.edit.breadcrumbs": "Item bearbeiten", // "item.edit.tabs.mapper.head": "Collection Mapper", "item.edit.tabs.mapper.head": "Spiegeln", // "item.edit.tabs.item-mapper.title": "Item Edit - Collection Mapper", - "item.edit.tabs.item-mapper.title": "Ressource bearbeiten - Spiegeln", + "item.edit.tabs.item-mapper.title": "Item bearbeiten - Spiegeln", // "item.edit.item-mapper.buttons.add": "Map item to selected collections", - "item.edit.item-mapper.buttons.add": "Ressource in die gewählte(n) Sammlung(en) spiegeln", + "item.edit.item-mapper.buttons.add": "Item in die gewählte(n) Sammlung(en) spiegeln", // "item.edit.item-mapper.buttons.remove": "Remove item's mapping for selected collections", - "item.edit.item-mapper.buttons.remove": "Spiegelung der Ressource aus der/den gewählten Sammlung(en) entfernen", + "item.edit.item-mapper.buttons.remove": "Spiegelung des Items aus der/den gewählten Sammlung(en) entfernen", // "item.edit.item-mapper.cancel": "Cancel", "item.edit.item-mapper.cancel": "Abbrechen", // "item.edit.item-mapper.description": "This is the item mapper tool that allows administrators to map this item to other collections. You can search for collections and map them, or browse the list of collections the item is currently mapped to.", - "item.edit.item-mapper.description": "Sammlungsadministrator:innen haben die Möglichkeit Ressourcen von einer Sammlung in eine andere zu spiegeln. Man kann nach Ressourcen in anderen Sammlungen suchen und diese spiegeln oder sich eine Liste der gespiegelten Ressourcen anzeigen lassen.", + "item.edit.item-mapper.description": "Sammlungsadministrator:innen haben die Möglichkeit Items von einer Sammlung in eine andere zu spiegeln. Man kann nach Items in anderen Sammlungen suchen und diese spiegeln oder sich eine Liste der gespiegelten Items anzeigen lassen.", // "item.edit.item-mapper.head": "Item Mapper - Map Item to Collections", - "item.edit.item-mapper.head": "Ressourcen spiegeln - Spiegelt eine Ressource in andere Sammlungen", + "item.edit.item-mapper.head": "Item spiegeln - Spiegelt ein Item in andere Sammlungen", // "item.edit.item-mapper.item": "Item: \"{{name}}\"", - "item.edit.item-mapper.item": "Ressource: \"{{name}}\"", + "item.edit.item-mapper.item": "Item: \"{{name}}\"", // "item.edit.item-mapper.no-search": "Please enter a query to search", "item.edit.item-mapper.no-search": "Bitte geben Sie einen Suchbegriff ein", // "item.edit.item-mapper.notifications.add.error.content": "Errors occurred for mapping of item to {{amount}} collections.", - "item.edit.item-mapper.notifications.add.error.content": "Beim Spiegeln der Ressource in {{amount}} Sammlung(en) ist ein Fehler aufgetreten.", + "item.edit.item-mapper.notifications.add.error.content": "Beim Spiegeln des Items in {{amount}} Sammlung(en) ist ein Fehler aufgetreten.", // "item.edit.item-mapper.notifications.add.error.head": "Mapping errors", "item.edit.item-mapper.notifications.add.error.head": "Fehler beim Spiegeln", // "item.edit.item-mapper.notifications.add.success.content": "Successfully mapped item to {{amount}} collections.", - "item.edit.item-mapper.notifications.add.success.content": "Ressource erfolgreich in {{amount}} Sammlung(en) gespiegelt.", + "item.edit.item-mapper.notifications.add.success.content": "Item erfolgreich in {{amount}} Sammlung(en) gespiegelt.", // "item.edit.item-mapper.notifications.add.success.head": "Mapping completed", "item.edit.item-mapper.notifications.add.success.head": "Spiegeln abgeschlossen", @@ -2216,10 +2188,10 @@ "item.edit.item-mapper.notifications.remove.error.content": "Beim Entfernen der Spiegelung in {{amount}} Sammlung(en) ist ein Fehler aufgetreten.", // "item.edit.item-mapper.notifications.remove.error.head": "Removal of mapping errors", - "item.edit.item-mapper.notifications.remove.error.head": "Fehler beim Entfernen von gespiegelten Ressourcen", + "item.edit.item-mapper.notifications.remove.error.head": "Fehler beim Entfernen von gespiegelten Items", // "item.edit.item-mapper.notifications.remove.success.content": "Successfully removed mapping of item to {{amount}} collections.", - "item.edit.item-mapper.notifications.remove.success.content": "Spiegelung der Ressource aus {{amount}} Sammlung(en) erfolgreich.", + "item.edit.item-mapper.notifications.remove.success.content": "Spiegelung des Items aus {{amount}} Sammlung(en) erfolgreich.", // "item.edit.item-mapper.notifications.remove.success.head": "Removal of mapping completed", "item.edit.item-mapper.notifications.remove.success.head": "Entfernen der Spiegelung abgeschlossen", @@ -2251,7 +2223,7 @@ "item.edit.metadata.edit.buttons.unedit": "Bearbeitung beenden", // "item.edit.metadata.empty": "The item currently doesn't contain any metadata. Click Add to start adding a metadata value.", - "item.edit.metadata.empty": "Die Ressource enthält derzeit keine Metadaten. Klicken Sie auf Hinzufügen, um einen Metadatenwert hinzuzufügen.", + "item.edit.metadata.empty": "Das Item enthält derzeit keine Metadaten. Klicken Sie auf Hinzufügen, um einen Metadatenwert hinzuzufügen.", // "item.edit.metadata.headers.edit": "Edit", "item.edit.metadata.headers.edit": "Bearbeiten", @@ -2284,13 +2256,13 @@ "item.edit.metadata.notifications.invalid.title": "Metadaten ungültig", // "item.edit.metadata.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", - "item.edit.metadata.notifications.outdated.content": "Die Ressource, an der Sie gerade arbeiten, wurde von einem anderen Account geändert. Ihre aktuellen Änderungen werden nicht angewandt, um Konflikte zu vermeiden.", + "item.edit.metadata.notifications.outdated.content": "Das Item, an dem Sie gerade arbeiten, wurde von einem anderen Account geändert. Ihre aktuellen Änderungen werden nicht angewandt, um Konflikte zu vermeiden.", // "item.edit.metadata.notifications.outdated.title": "Changed outdated", "item.edit.metadata.notifications.outdated.title": "Änderung veraltet", // "item.edit.metadata.notifications.saved.content": "Your changes to this item's metadata were saved.", - "item.edit.metadata.notifications.saved.content": "Ihre Änderungen an den Metadaten der Ressource wurden gespeichert.", + "item.edit.metadata.notifications.saved.content": "Ihre Änderungen an den Metadaten des Items wurden gespeichert.", // "item.edit.metadata.notifications.saved.title": "Metadata saved", "item.edit.metadata.notifications.saved.title": "Metadaten gespeichert", @@ -2321,10 +2293,10 @@ "item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.", // "item.edit.move.error": "An error occurred when attempting to move the item", - "item.edit.move.error": "Ein Fehler ist beim Verschieben der Ressource aufgetreten", + "item.edit.move.error": "Ein Fehler ist beim Verschieben des Items aufgetreten", // "item.edit.move.head": "Move item: {{id}}", - "item.edit.move.head": "Ressource verschieben: {{id}}", + "item.edit.move.head": "Item verschieben: {{id}}", // "item.edit.move.inheritpolicies.checkbox": "Inherit policies", "item.edit.move.inheritpolicies.checkbox": "Rechte erben", @@ -2342,10 +2314,10 @@ "item.edit.move.search.placeholder": "Geben Sie einen Begriff ein, um nach Sammlungen zu suchen", // "item.edit.move.success": "The item has been moved successfully", - "item.edit.move.success": "Die Ressource wurde erfolgreich verschoben", + "item.edit.move.success": "Das Item wurde erfolgreich verschoben", // "item.edit.move.title": "Move item", - "item.edit.move.title": "Ressource verschieben", + "item.edit.move.title": "Item verschieben", @@ -2356,16 +2328,16 @@ "item.edit.private.confirm": "Privat machen", // "item.edit.private.description": "Are you sure this item should be made private in the archive?", - "item.edit.private.description": "Wollen Sie diese Ressource als privat markieren.", + "item.edit.private.description": "Wollen Sie dieses Item als privat markieren.", // "item.edit.private.error": "An error occurred while making the item private", - "item.edit.private.error": "Ein Fehler ist aufgetreten bei dem Versuch, die Ressource privat zu machen", + "item.edit.private.error": "Ein Fehler ist aufgetreten bei dem Versuch, das Item privat zu machen", // "item.edit.private.header": "Make item private: {{ id }}", - "item.edit.private.header": "Ressource: {{ id }} privat machen", + "item.edit.private.header": "Item: {{ id }} privat machen", // "item.edit.private.success": "The item is now private", - "item.edit.private.success": "Diese Ressource ist nun privat", + "item.edit.private.success": "Dieses Item ist nun privat", @@ -2376,16 +2348,16 @@ "item.edit.public.confirm": "Öffentlich machen", // "item.edit.public.description": "Are you sure this item should be made public in the archive?", - "item.edit.public.description": "Sind Sie sicher, dass diese Ressource im Repositorium öffentlich gemacht werden soll?", + "item.edit.public.description": "Sind Sie sicher, dass dieses Item im Repositorium öffentlich gemacht werden soll?", // "item.edit.public.error": "An error occurred while making the item public", - "item.edit.public.error": "Ein Fehler ist aufgetreten, als die Ressource öffentlich gemacht werden sollte.", + "item.edit.public.error": "Ein Fehler ist aufgetreten, als das Item öffentlich gemacht werden sollte.", // "item.edit.public.header": "Make item public: {{ id }}", - "item.edit.public.header": "Ressource: {{ id }} öffentlich machen", + "item.edit.public.header": "Item: {{ id }} öffentlich machen", // "item.edit.public.success": "The item is now public", - "item.edit.public.success": "Die Ressource ist nun öffentlich", + "item.edit.public.success": "Das Item ist nun öffentlich", @@ -2396,16 +2368,16 @@ "item.edit.reinstate.confirm": "Reinstantiieren", // "item.edit.reinstate.description": "Are you sure this item should be reinstated to the archive?", - "item.edit.reinstate.description": "Sind Sie sicher, dass die Ressource reinstantiiert werden soll?", + "item.edit.reinstate.description": "Sind Sie sicher, dass das Item reinstantiiert werden soll?", // "item.edit.reinstate.error": "An error occurred while reinstating the item", - "item.edit.reinstate.error": "Ein Fehler ist bei der Reinstantiierung der Ressource aufgetreten.", + "item.edit.reinstate.error": "Ein Fehler ist bei der Reinstantiierung des Items aufgetreten.", // "item.edit.reinstate.header": "Reinstate item: {{ id }}", - "item.edit.reinstate.header": "Ressource: {{ id }} reinstantiieren", + "item.edit.reinstate.header": "Item: {{ id }} reinstantiieren", // "item.edit.reinstate.success": "The item was reinstated successfully", - "item.edit.reinstate.success": "Die Ressource wurde erfolgreich reinstantiiert", + "item.edit.reinstate.success": "Das Item wurde erfolgreich reinstantiiert", @@ -2434,13 +2406,13 @@ "item.edit.relationships.notifications.failed.title": "Fehler beim Bearbeiten der Beziehung", // "item.edit.relationships.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", - "item.edit.relationships.notifications.outdated.content": "Die Ressource, die Sie gerade bearbeiten, wurde von einem anderen Account geändert. Ihre aktuellen Änderungen werden verworfen, um Konflikte zu vermeiden.", + "item.edit.relationships.notifications.outdated.content": "Das Item, das Sie gerade bearbeiten, wurde von einem anderen Account geändert. Ihre aktuellen Änderungen werden verworfen, um Konflikte zu vermeiden.", // "item.edit.relationships.notifications.outdated.title": "Changes outdated", "item.edit.relationships.notifications.outdated.title": "Änderungen veraltet", // "item.edit.relationships.notifications.saved.content": "Your changes to this item's relationships were saved.", - "item.edit.relationships.notifications.saved.content": "Ihre Änderungen an den Beziehungen der Ressource wurden gespeichert.", + "item.edit.relationships.notifications.saved.content": "Ihre Änderungen an den Beziehungen des Items wurden gespeichert.", // "item.edit.relationships.notifications.saved.title": "Relationships saved", "item.edit.relationships.notifications.saved.title": "Beziehungen gespeichert", @@ -2452,40 +2424,39 @@ "item.edit.relationships.save-button": "Speichern", // "item.edit.relationships.no-entity-type": "Add 'dspace.entity.type' metadata to enable relationships for this item", - "item.edit.relationships.no-entity-type": "Füge 'dspace.entity.type' in die Metadaten hinzu, um Beziehungen für diese Ressource zu ermöglichen", + "item.edit.relationships.no-entity-type": "Füge 'dspace.entity.type' in die Metadaten hinzu, um Beziehungen für dieses Item zu ermöglichen", // "item.edit.tabs.bitstreams.head": "Bitstreams", - // TODO Source message changed - Revise the translation "item.edit.tabs.bitstreams.head": "Dateien", // "item.edit.tabs.bitstreams.title": "Item Edit - Bitstreams", - "item.edit.tabs.bitstreams.title": "Ressource bearbeiten - Dateien", + "item.edit.tabs.bitstreams.title": "Item bearbeiten - Dateien", // "item.edit.tabs.curate.head": "Curate", "item.edit.tabs.curate.head": "Pflegen", // "item.edit.tabs.curate.title": "Item Edit - Curate", - "item.edit.tabs.curate.title": "Ressource bearbeiten - Pflegen", + "item.edit.tabs.curate.title": "Item bearbeiten - Pflegen", // "item.edit.tabs.metadata.head": "Metadata", "item.edit.tabs.metadata.head": "Metadaten", // "item.edit.tabs.metadata.title": "Item Edit - Metadata", - "item.edit.tabs.metadata.title": "Ressource bearbeiten - Metadaten", + "item.edit.tabs.metadata.title": "Item bearbeiten - Metadaten", // "item.edit.tabs.relationships.head": "Relationships", "item.edit.tabs.relationships.head": "Beziehungen", // "item.edit.tabs.relationships.title": "Item Edit - Relationships", - "item.edit.tabs.relationships.title": "Ressource bearbeiten - Relationen", + "item.edit.tabs.relationships.title": "Item bearbeiten - Relationen", // "item.edit.tabs.status.buttons.authorizations.button": "Authorizations...", "item.edit.tabs.status.buttons.authorizations.button": "Berechtigungen...", // "item.edit.tabs.status.buttons.authorizations.label": "Edit item's authorization policies", - "item.edit.tabs.status.buttons.authorizations.label": "Rechte der Ressource bearbeiten", + "item.edit.tabs.status.buttons.authorizations.label": "Rechte des Items bearbeiten", // "item.edit.tabs.status.buttons.delete.button": "Permanently delete", "item.edit.tabs.status.buttons.delete.button": "Endgültig löschen", @@ -2503,34 +2474,34 @@ "item.edit.tabs.status.buttons.move.button": "Verschieben...", // "item.edit.tabs.status.buttons.move.label": "Move item to another collection", - "item.edit.tabs.status.buttons.move.label": "Ressource in eine andere Sammlung verschieben", + "item.edit.tabs.status.buttons.move.label": "Item in eine andere Sammlung verschieben", // "item.edit.tabs.status.buttons.private.button": "Make it private...", "item.edit.tabs.status.buttons.private.button": "Privat machen...", // "item.edit.tabs.status.buttons.private.label": "Make item private", - "item.edit.tabs.status.buttons.private.label": "Ressource privat machen", + "item.edit.tabs.status.buttons.private.label": "Item privat machen", // "item.edit.tabs.status.buttons.public.button": "Make it public...", "item.edit.tabs.status.buttons.public.button": "Öffentlich machen...", // "item.edit.tabs.status.buttons.public.label": "Make item public", - "item.edit.tabs.status.buttons.public.label": "Ressource öffentlich machen", + "item.edit.tabs.status.buttons.public.label": "Item öffentlich machen", // "item.edit.tabs.status.buttons.reinstate.button": "Reinstate...", "item.edit.tabs.status.buttons.reinstate.button": "Reinstantiieren...", // "item.edit.tabs.status.buttons.reinstate.label": "Reinstate item into the repository", - "item.edit.tabs.status.buttons.reinstate.label": "Ressource wieder ins Repositorium einsetzen", + "item.edit.tabs.status.buttons.reinstate.label": "Item wieder ins Repositorium einsetzen", // "item.edit.tabs.status.buttons.withdraw.button": "Withdraw...", "item.edit.tabs.status.buttons.withdraw.button": "Zurückziehen...", // "item.edit.tabs.status.buttons.withdraw.label": "Withdraw item from the repository", - "item.edit.tabs.status.buttons.withdraw.label": "Ressource aus dem Repositorium zurückziehen", + "item.edit.tabs.status.buttons.withdraw.label": "Item aus dem Repositorium zurückziehen", // "item.edit.tabs.status.description": "Welcome to the item management page. From here you can withdraw, reinstate, move or delete the item. You may also update or add new metadata / bitstreams on the other tabs.", - "item.edit.tabs.status.description": "Ressource bearbeiten. Von hier können Sie Ressourcen zurückziehen, wiedereinsetzen, verschieben oder Löschen. Des weiteren können die Metadaten und die zugehörigen Dateien bearbeitet werden.", + "item.edit.tabs.status.description": "Item bearbeiten. Von hier können Sie Items zurückziehen, wiedereinsetzen, verschieben oder Löschen. Des weiteren können die Metadaten und die zugehörigen Dateien bearbeitet werden.", // "item.edit.tabs.status.head": "Status", "item.edit.tabs.status.head": "Status", @@ -2539,31 +2510,31 @@ "item.edit.tabs.status.labels.handle": "Handle", // "item.edit.tabs.status.labels.id": "Item Internal ID", - "item.edit.tabs.status.labels.id": "Interne ID der Ressource", + "item.edit.tabs.status.labels.id": "Interne ID des Items", // "item.edit.tabs.status.labels.itemPage": "Item Page", - "item.edit.tabs.status.labels.itemPage": "Startseite der Ressource", + "item.edit.tabs.status.labels.itemPage": "Startseite des Items", // "item.edit.tabs.status.labels.lastModified": "Last Modified", "item.edit.tabs.status.labels.lastModified": "Zuletzt geändert", // "item.edit.tabs.status.title": "Item Edit - Status", - "item.edit.tabs.status.title": "Ressource bearbeiten - Status", + "item.edit.tabs.status.title": "Item bearbeiten - Status", // "item.edit.tabs.versionhistory.head": "Version History", "item.edit.tabs.versionhistory.head": "Versionsgeschichte", // "item.edit.tabs.versionhistory.title": "Item Edit - Version History", - "item.edit.tabs.versionhistory.title": "Ressource bearbeiten - Versionsgeschichte", + "item.edit.tabs.versionhistory.title": "Item bearbeiten - Versionsgeschichte", // "item.edit.tabs.versionhistory.under-construction": "Editing or adding new versions is not yet possible in this user interface.", "item.edit.tabs.versionhistory.under-construction": "Das Bearbeiten oder Hinzufügen neuer Versionen ist in dieser Benutzeroberfläche noch nicht möglich.", // "item.edit.tabs.view.head": "View Item", - "item.edit.tabs.view.head": "Ressource ansehen", + "item.edit.tabs.view.head": "Item ansehen", // "item.edit.tabs.view.title": "Item Edit - View", - "item.edit.tabs.view.title": "Ressource bearbeiten - Ansicht", + "item.edit.tabs.view.title": "Item bearbeiten - Ansicht", @@ -2574,27 +2545,27 @@ "item.edit.withdraw.confirm": "Zurückziehen", // "item.edit.withdraw.description": "Are you sure this item should be withdrawn from the archive?", - "item.edit.withdraw.description": "Sind Sie sicher, dass Sie diese Ressource aus dem Repositorium zurückziehen wollen?", + "item.edit.withdraw.description": "Sind Sie sicher, dass Sie dieses Item aus dem Repositorium zurückziehen wollen?", // "item.edit.withdraw.error": "An error occurred while withdrawing the item", - "item.edit.withdraw.error": "Ein Fehler ist beim Zurückziehen der Ressource aufgetreten", + "item.edit.withdraw.error": "Ein Fehler ist beim Zurückziehen des Items aufgetreten", // "item.edit.withdraw.header": "Withdraw item: {{ id }}", - "item.edit.withdraw.header": "Ressource: {{ id }} zurückziehen", + "item.edit.withdraw.header": "Item: {{ id }} zurückziehen", // "item.edit.withdraw.success": "The item was withdrawn successfully", - "item.edit.withdraw.success": "Die Ressource wurde erfolgreich zurückgezogen", + "item.edit.withdraw.success": "Das Item wurde erfolgreich zurückgezogen", // "item.listelement.badge": "Item", - "item.listelement.badge": "Ressource", + "item.listelement.badge": "Item", // "item.page.description": "Description", "item.page.description": "Beschreibung", // "item.page.edit": "Edit this item", - "item.page.edit": "Diese Ressource bearbeiten", + "item.page.edit": "Dieses Item bearbeiten", // "item.page.journal-issn": "Journal ISSN", "item.page.journal-issn": "ISSN der Zeitschrift", @@ -2606,16 +2577,16 @@ "item.page.publisher": "Verlag", // "item.page.titleprefix": "Item: ", - "item.page.titleprefix": "Ressource: ", + "item.page.titleprefix": "Item: ", // "item.page.volume-title": "Volume Title", "item.page.volume-title": "Bandtitel", // "item.search.results.head": "Item Search Results", - "item.search.results.head": "Ressourcen Suchergebnisse", + "item.search.results.head": "Item Suchergebnisse", // "item.search.title": "DSpace Angular :: Item Search", - "item.search.title": "DSpace Angular :: Ressourcen-Suche", + "item.search.title": "DSpace Angular :: Item-Suche", @@ -2635,7 +2606,7 @@ "item.page.date": "Datum", // "item.page.edit": "Edit this item", - "item.page.edit": "Diese Ressource bearbeiten", + "item.page.edit": "Dieses Item bearbeiten", // "item.page.files": "Files", "item.page.files": "Dateien", @@ -2728,7 +2699,6 @@ "item.preview.dc.title": "Titel:", // "item.preview.person.familyName": "Surname:", - // TODO New key - Add a translation "item.preview.person.familyName": "Nachname:", // "item.preview.person.givenName": "Name:", @@ -2742,7 +2712,7 @@ "item.select.confirm": "Auswahl bestätigen", // "item.select.empty": "No items to show", - "item.select.empty": "Es gibt keine Ressourcen dazu", + "item.select.empty": "Es gibt keine Items dazu", // "item.select.table.author": "Author", "item.select.table.author": "Autor:in", @@ -2755,7 +2725,7 @@ // "item.version.history.empty": "There are no other versions for this item yet.", - "item.version.history.empty": "Es gibt noch keine anderen Versionen für diese Ressource.", + "item.version.history.empty": "Es gibt noch keine anderen Versionen für dieses Item.", // "item.version.history.head": "Version History", "item.version.history.head": "Versionsgeschichte", @@ -2770,7 +2740,7 @@ "item.version.history.table.version": "Version", // "item.version.history.table.item": "Item", - "item.version.history.table.item": "Ressource", + "item.version.history.table.item": "Item", // "item.version.history.table.editor": "Editor", "item.version.history.table.editor": "Herausgeber:in", @@ -2784,8 +2754,7 @@ // "item.version.notice": "This is not the latest version of this item. The latest version can be found here.", - // TODO New key - Add a translation - "item.version.notice": "Dies ist nicht die neueste Version dieses Artikels. Die neueste Version finden Sie hier.", + "item.version.notice": "Dies ist nicht die neueste Version dieses Items. Die neueste Version finden Sie unter hier.", @@ -2796,7 +2765,7 @@ "journal.page.description": "Beschreibung", // "journal.page.edit": "Edit this item", - "journal.page.edit": "Diese Ressource bearbeiten", + "journal.page.edit": "Dieses Item bearbeiten", // "journal.page.editor": "Editor-in-Chief", "journal.page.editor": "Chefredakteur:in", @@ -2825,7 +2794,7 @@ "journalissue.page.description": "Beschreibeung", // "journalissue.page.edit": "Edit this item", - "journalissue.page.edit": "Diese Ressource bearbeiten", + "journalissue.page.edit": "Dieses Item bearbeiten", // "journalissue.page.issuedate": "Issue Date", "journalissue.page.issuedate": "Erscheinungsdatum", @@ -2854,7 +2823,7 @@ "journalvolume.page.description": "Beschreibung", // "journalvolume.page.edit": "Edit this item", - "journalvolume.page.edit": "Diese Ressource bearbeiten", + "journalvolume.page.edit": "Dieses Item bearbeiten", // "journalvolume.page.issuedate": "Issue Date", "journalvolume.page.issuedate": "Erscheinungsdatum", @@ -2874,7 +2843,7 @@ "loading.bitstreams": "Lade Datei...", // "loading.browse-by": "Loading items...", - "loading.browse-by": "Lade Ressourcen...", + "loading.browse-by": "Lade Items...", // "loading.browse-by-page": "Loading page...", "loading.browse-by-page": "Lade Seite...", @@ -2895,13 +2864,13 @@ "loading.default": "Lade...", // "loading.item": "Loading item...", - "loading.item": "Lade Ressource...", + "loading.item": "Lade Item...", // "loading.items": "Loading items...", - "loading.items": "Lade Ressourcen...", + "loading.items": "Lade Items...", // "loading.mydspace-results": "Loading items...", - "loading.mydspace-results": "Lade Ressourcen...", + "loading.mydspace-results": "Lade Items...", // "loading.objects": "Loading...", "loading.objects": "Lade...", @@ -3043,7 +3012,7 @@ "menu.section.edit_community": "Bereich", // "menu.section.edit_item": "Item", - "menu.section.edit_item": "Ressource", + "menu.section.edit_item": "Item", @@ -3057,7 +3026,7 @@ "menu.section.export_community": "Bereich", // "menu.section.export_item": "Item", - "menu.section.export_item": "Ressource", + "menu.section.export_item": "Item", // "menu.section.export_metadata": "Metadata", "menu.section.export_metadata": "Metadaten", @@ -3068,8 +3037,7 @@ "menu.section.icon.access_control": "Menübereich Zugriffskontrolle", // "menu.section.icon.admin_search": "Admin search menu section", - // TODO New key - Add a translation - "menu.section.icon.admin_search": "Admin search menu section", + "menu.section.icon.admin_search": "Menübereich Admin-Suche", // "menu.section.icon.control_panel": "Control Panel menu section", "menu.section.icon.control_panel": "Menübereich Kontrollfeld", @@ -3130,10 +3098,10 @@ "menu.section.new_community": "Bereich", // "menu.section.new_item": "Item", - "menu.section.new_item": "Ressource", + "menu.section.new_item": "Item", // "menu.section.new_item_version": "Item Version", - "menu.section.new_item_version": "Ressourcenversion", + "menu.section.new_item_version": "Item-Version", // "menu.section.new_process": "Process", "menu.section.new_process": "Prozess", @@ -3214,7 +3182,7 @@ "mydspace.general.text-here": "hier", // "mydspace.messages.controller-help": "Select this option to send a message to item's submitter.", - "mydspace.messages.controller-help": "Wählen Sie diese Option, um dem/derjenigen, die die Ressource eingereicht hat, eine Nachricht zu schicken.", + "mydspace.messages.controller-help": "Wählen Sie diese Option, um dem/derjenigen, die das Item eingereicht hat, eine Nachricht zu schicken.", // "mydspace.messages.description-placeholder": "Insert your message here...", "mydspace.messages.description-placeholder": "Geben Sie Ihre Nachricht hier ein...", @@ -3280,7 +3248,7 @@ "mydspace.results.no-files": "Keine Dateien", // "mydspace.results.no-results": "There were no items to show", - "mydspace.results.no-results": "Es gibt keine Ressourcen anzuzeigen", + "mydspace.results.no-results": "Es gibt keine Items anzuzeigen", // "mydspace.results.no-title": "No title", "mydspace.results.no-title": "Kein Titel", @@ -3322,10 +3290,10 @@ "mydspace.upload.upload-failed-moreonefile": "Unverarbeitbare Anfrage. Nur eine Datei ist erlaubt.", // "mydspace.upload.upload-multiple-successful": "{{qty}} new workspace items created.", - "mydspace.upload.upload-multiple-successful": "{{qty}} neue(s) Arbeitsbereichressource(n) angelegt.", + "mydspace.upload.upload-multiple-successful": "{{qty}} neue(s) Arbeitsbereichitem(s) angelegt.", // "mydspace.upload.upload-successful": "New workspace item created. Click {{here}} for edit it.", - "mydspace.upload.upload-successful": "Neue Arbeitsbereichressource angelegt. Klicken Sie {{here}}, um sie zu bearbeiten.", + "mydspace.upload.upload-successful": "Neues Arbeitsbereichitem angelegt. Klicken Sie {{here}}, um sie zu bearbeiten.", // "mydspace.view-btn": "View", "mydspace.view-btn": "Anzeige", @@ -3380,7 +3348,7 @@ "orgunit.page.description": "Beschreibung", // "orgunit.page.edit": "Edit this item", - "orgunit.page.edit": "Diese Ressourcen bearbeiten", + "orgunit.page.edit": "Dieses Item bearbeiten", // "orgunit.page.id": "ID", "orgunit.page.id": "ID", @@ -3414,7 +3382,7 @@ "person.page.birthdate": "Geburtsdatum", // "person.page.edit": "Edit this item", - "person.page.edit": "Diese Ressource bearbeiten", + "person.page.edit": "Dieses Item bearbeiten", // "person.page.email": "Email Address", "person.page.email": "E-Mail-Adresse", @@ -3517,24 +3485,19 @@ "process.detail.back" : "Zurück", // "process.detail.output" : "Process Output", - // TODO New key - Add a translation - "process.detail.output" : "Process Output", + "process.detail.output" : "Prozessausgabe", // "process.detail.logs.button": "Retrieve process output", - // TODO New key - Add a translation - "process.detail.logs.button": "Retrieve process output", + "process.detail.logs.button": "Abrufen der Prozessausgabe", // "process.detail.logs.loading": "Retrieving", - // TODO New key - Add a translation - "process.detail.logs.loading": "Retrieving", + "process.detail.logs.loading": "Abrufen", // "process.detail.logs.none": "This process has no output", - // TODO New key - Add a translation - "process.detail.logs.none": "This process has no output", + "process.detail.logs.none": "Dieser Prozess hat keine Ausgabe", // "process.detail.output-files" : "Output Files", - // TODO New key - Add a translation - "process.detail.output-files" : "Output Files", + "process.detail.output-files" : "Ausgabedateien", // "process.detail.output-files.empty" : "This process doesn't contain any output files", "process.detail.output-files.empty" : "Dieser Prozess enthält keine Ausgabedateien", @@ -3683,7 +3646,7 @@ "project.page.description": "Beschreibung", // "project.page.edit": "Edit this item", - "project.page.edit": "Diese Ressource bearbeiten", + "project.page.edit": "Dieses Item bearbeiten", // "project.page.expectedcompletion": "Expected Completion", "project.page.expectedcompletion": "Erwartetes Abschlussdatum", @@ -3715,7 +3678,7 @@ "publication.page.description": "Beschreibung", // "publication.page.edit": "Edit this item", - "publication.page.edit": "Diese Ressource bearbeiten", + "publication.page.edit": "Dieses Item bearbeiten", // "publication.page.journal-issn": "Journal ISSN", "publication.page.journal-issn": "ISSN der Zeitschrift", @@ -3810,7 +3773,7 @@ "register-page.registration.header": "Registrierung neuer Benutzer:innen", // "register-page.registration.info": "Register an account to subscribe to collections for email updates, and submit new items to DSpace.", - "register-page.registration.info": "Registrieren Sie ein Konto, um Sammlungen für E-Mail-Updates zu abonnieren und neue Ressourcen in DSpace einzugeben.", + "register-page.registration.info": "Registrieren Sie ein Konto, um Sammlungen für E-Mail-Updates zu abonnieren und neue Items in DSpace einzugeben.", // "register-page.registration.email": "Email Address *", "register-page.registration.email": "E-Mail-Adresse *", @@ -3842,7 +3805,7 @@ // "relationships.add.error.relationship-type.content": "No suitable match could be found for relationship type {{ type }} between the two items", - "relationships.add.error.relationship-type.content": "Für den Beziehungstyp {{ type }} zwischen den beiden Ressourcen konnte keine passende Übereinstimmung gefunden werden", + "relationships.add.error.relationship-type.content": "Für den Beziehungstyp {{ type }} zwischen den beiden Items konnte keine passende Übereinstimmung gefunden werden", // "relationships.add.error.server.content": "The server returned an error", "relationships.add.error.server.content": "Der Server hat einen Fehler zurückgegeben", @@ -3919,55 +3882,46 @@ "resource-policies.add.for.collection": "Eine neue Sammlungen-Richtlinie hinzufügen", // "resource-policies.create.page.heading": "Create new resource policy for ", - // TODO New key - Add a translation - "resource-policies.create.page.heading": "Create new resource policy for ", + "resource-policies.create.page.heading": "Eine neue Ressourcen-Richtlinie erstellen für ", // "resource-policies.create.page.failure.content": "An error occurred while creating the resource policy.", - // TODO New key - Add a translation - "resource-policies.create.page.failure.content": "An error occurred while creating the resource policy.", + "resource-policies.create.page.failure.content": "Bei der Erstellung der Ressourcen-Richtlinie ist ein Fehler aufgetreten.", // "resource-policies.create.page.success.content": "Operation successful", "resource-policies.create.page.success.content": "Vorgang erfolgreich", // "resource-policies.create.page.title": "Create new resource policy", - // TODO New key - Add a translation - "resource-policies.create.page.title": "Create new resource policy", + "resource-policies.create.page.title": "Eine neue Ressourcen-Richtlinie erstellen", // "resource-policies.delete.btn": "Delete selected", "resource-policies.delete.btn": "Ausgewählte löschen", // "resource-policies.delete.btn.title": "Delete selected resource policies", - // TODO New key - Add a translation - "resource-policies.delete.btn.title": "Delete selected resource policies", + "resource-policies.delete.btn.title": "Ausgewählte Ressourcen-Richtlinien löschen", // "resource-policies.delete.failure.content": "An error occurred while deleting selected resource policies.", - // TODO New key - Add a translation - "resource-policies.delete.failure.content": "An error occurred while deleting selected resource policies.", + "resource-policies.delete.failure.content": "Beim Löschen der ausgewählten Ressourcen-Richtlinien ist ein Fehler aufgetreten.", // "resource-policies.delete.success.content": "Operation successful", "resource-policies.delete.success.content": "Vorgang erfolgreich", // "resource-policies.edit.page.heading": "Edit resource policy ", - // TODO New key - Add a translation - "resource-policies.edit.page.heading": "Edit resource policy ", + "resource-policies.edit.page.heading": "Ressourcen-Richtlinie bearbeiten ", // "resource-policies.edit.page.failure.content": "An error occurred while editing the resource policy.", - // TODO New key - Add a translation - "resource-policies.edit.page.failure.content": "An error occurred while editing the resource policy.", + "resource-policies.edit.page.failure.content": "Beim Bearbeiten der Ressourcen-Richtlinie ist ein Fehler aufgetreten.", // "resource-policies.edit.page.success.content": "Operation successful", "resource-policies.edit.page.success.content": "Vorgang erfolgreich", // "resource-policies.edit.page.title": "Edit resource policy", - // TODO New key - Add a translation - "resource-policies.edit.page.title": "Edit resource policy", + "resource-policies.edit.page.title": "Ressourcen-Richtlinie bearbeiten", // "resource-policies.form.action-type.label": "Select the action type", "resource-policies.form.action-type.label": "Wählen Sie die Aktionsart", // "resource-policies.form.action-type.required": "You must select the resource policy action.", - // TODO New key - Add a translation - "resource-policies.form.action-type.required": "You must select the resource policy action.", + "resource-policies.form.action-type.required": "Sie müssen die Aktion der Ressourcen-Richtlinie auswählen.", // "resource-policies.form.eperson-group-list.label": "The eperson or group that will be granted the permission", "resource-policies.form.eperson-group-list.label": "Die Person oder Gruppe, der die Genehmigung erteilt wird", @@ -3982,8 +3936,7 @@ "resource-policies.form.eperson-group-list.tab.group": "Suche nach einer Gruppe", // "resource-policies.form.eperson-group-list.table.headers.action": "Action", - // TODO New key - Add a translation - "resource-policies.form.eperson-group-list.table.headers.action": "Action", + "resource-policies.form.eperson-group-list.table.headers.action": "Aktion", // "resource-policies.form.eperson-group-list.table.headers.id": "ID", "resource-policies.form.eperson-group-list.table.headers.id": "ID", @@ -4007,8 +3960,7 @@ "resource-policies.form.policy-type.label": "Wählen Sie den Richtlinientyp", // "resource-policies.form.policy-type.required": "You must select the resource policy type.", - // TODO New key - Add a translation - "resource-policies.form.policy-type.required": "You must select the resource policy type.", + "resource-policies.form.policy-type.required": "Sie müssen den Typ der Ressourcen-Richtlinie auswählen", // "resource-policies.table.headers.action": "Action", "resource-policies.table.headers.action": "Aktion", @@ -4091,7 +4043,7 @@ "search.filters.applied.f.discoverable": "Privat", // "search.filters.applied.f.entityType": "Item Type", - "search.filters.applied.f.entityType": "Art der Ressource", + "search.filters.applied.f.entityType": "Item-Typ", // "search.filters.applied.f.has_content_in_original_bundle": "Has files", "search.filters.applied.f.has_content_in_original_bundle": "Hat Dateien", @@ -4180,10 +4132,10 @@ "search.filters.filter.withdrawn.head": "Zurückgezogen", // "search.filters.filter.entityType.head": "Item Type", - "search.filters.filter.entityType.head": "Art der Ressource", + "search.filters.filter.entityType.head": "Item-Typ", // "search.filters.filter.entityType.placeholder": "Item Type", - "search.filters.filter.entityType.placeholder": "Art der Ressource", + "search.filters.filter.entityType.placeholder": "Item-Typ", // "search.filters.filter.has_content_in_original_bundle.head": "Has files", "search.filters.filter.has_content_in_original_bundle.head": "Enthält Dateien", @@ -4447,7 +4399,7 @@ "submission.import-external.title": "Importieren von Metadaten aus einer externen Quelle", // "submission.import-external.page.hint": "Enter a query above to find items from the web to import in to DSpace.", - "submission.import-external.page.hint": "Geben Sie oben eine Abfrage ein, um Ressourcen aus dem Internet zu finden, die in DSpace importiert werden sollen.", + "submission.import-external.page.hint": "Geben Sie oben eine Abfrage ein, um Items aus dem Internet zu finden, die in DSpace importiert werden sollen.", // "submission.import-external.back-to-my-dspace": "Back to MyDSpace", "submission.import-external.back-to-my-dspace": "Zurück zu MyDSpace", @@ -4486,7 +4438,7 @@ "submission.import-external.source.lcname": "Library of Congress Names", // "submission.import-external.preview.title": "Item Preview", - "submission.import-external.preview.title": "Ressourcen-Vorschau", + "submission.import-external.preview.title": "Item-Vorschau", // "submission.import-external.preview.subtitle": "The metadata below was imported from an external source. It will be pre-filled when you start the submission.", "submission.import-external.preview.subtitle": "Die folgenden Metadaten wurden aus einer externen Quelle importiert. Sie werden vorausgefüllt, wenn Sie die Eingabe starten.", @@ -4507,8 +4459,7 @@ "submission.sections.describe.relationship-lookup.external-source.added": "Der lokale Eintrage wurde erfolgreich zur Auswahl hinzugefügt.", // "submission.sections.describe.relationship-lookup.external-source.import-button-title.isAuthorOfPublication": "Import remote author", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.external-source.import-button-title.isAuthorOfPublication": "Import remote author", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.isAuthorOfPublication": "Importiere Autor:innen-Metadaten", // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal": "Import remote journal", "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal": "Zeitschrift importieren", @@ -4520,8 +4471,7 @@ "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "Zeitschriftenband importieren", // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "Import Remote Author", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "Import Remote Author", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "Importiere Autor:innen-Metadaten", // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "Successfully added local author to the selection", "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "Erfolgreicher Import und Hinzufügen eines/einer lokalen Autor:in zur Auswahl", @@ -4620,55 +4570,46 @@ "submission.sections.describe.relationship-lookup.search-tab.select-page": "Seite auswählen", // "submission.sections.describe.relationship-lookup.selected": "Selected {{ size }} items", - "submission.sections.describe.relationship-lookup.selected": "{{ size }} Ressourcen ausgewählt", + "submission.sections.describe.relationship-lookup.selected": "{{ size }} Items ausgewählt", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "Local Authors ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "Local Authors ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "Lokale Autoren ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalOfPublication": "Local Journals ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalOfPublication": "Local Journals ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalOfPublication": "Lokale Zeitschriften ({{ count }})", + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Project": "Local Projects ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.Project": "Local Projects ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Project": "Lokale Projekte ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Publication": "Local Publications ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.Publication": "Local Publications ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Publication": "Lokale Publicationen ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "Local Authors ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "Local Authors ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "Lokale Autoren ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "Local Organizational Units ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "Local Organizational Units ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "Lokale Organisationseinheiten ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataPackage": "Local Data Packages ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataPackage": "Local Data Packages ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataPackage": "Lokale Datenpakete ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataFile": "Local Data Files ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataFile": "Local Data Files ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataFile": "Lokale Dateien ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Journal": "Local Journals ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.Journal": "Lokale Zeitschriften ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalIssueOfPublication": "Local Journal Issues ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalIssueOfPublication": "Local Journal Issues ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalIssueOfPublication": "Lokale Zeitschriftenhefte ({{ count }})", + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalIssue": "Local Journal Issues ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalIssue": "Local Journal Issues ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalIssue": "Lokale Zeitschriftenhefte ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalVolumeOfPublication": "Local Journal Volumes ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalVolumeOfPublication": "Local Journal Volumes ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalVolumeOfPublication": "Lokale Zeitschriftenbände ({{ count }})", + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalVolume": "Local Journal Volumes ({{ count }})", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalVolume": "Local Journal Volumes ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalVolume": "Lokale Zeitschriftenbände ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaJournal": "Sherpa Journals ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaJournal": "Sherpa Zeitschriften ({{ count }})", @@ -4734,8 +4675,7 @@ "submission.sections.describe.relationship-lookup.title.DataPackage": "Datenpakete", // "submission.sections.describe.relationship-lookup.title.DataFile": "Data Files", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.title.DataFile": "Data Files", + "submission.sections.describe.relationship-lookup.title.DataFile": "Dateien", // "submission.sections.describe.relationship-lookup.title.Funding Agency": "Funding Agency", "submission.sections.describe.relationship-lookup.title.Funding Agency": "Fördereinrichtung", @@ -4780,8 +4720,7 @@ "submission.sections.describe.relationship-lookup.selection-tab.title.DataPackage": "Ausgewählte Datenpakete", // "submission.sections.describe.relationship-lookup.selection-tab.title.DataFile": "Selected Data Files", - // TODO New key - Add a translation - "submission.sections.describe.relationship-lookup.selection-tab.title.DataFile": "Selected Data Files", + "submission.sections.describe.relationship-lookup.selection-tab.title.DataFile": "Ausgewählte Dateien", // "submission.sections.describe.relationship-lookup.selection-tab.title.Journal": "Selected Journals", "submission.sections.describe.relationship-lookup.selection-tab.title.Journal": "Ausgewählte Zeitschriften", @@ -4850,12 +4789,10 @@ "submission.sections.ccLicense.option.select": "Wählen Sie eine Option…", // "submission.sections.ccLicense.link": "You’ve selected the following license:", - // TODO New key - Add a translation - "submission.sections.ccLicense.link": "You’ve selected the following license:", + "submission.sections.ccLicense.link": "Sie haben die folgende Lizenz ausgewählt:", // "submission.sections.ccLicense.confirmation": "I grant the license above", - // TODO New key - Add a translation - "submission.sections.ccLicense.confirmation": "I grant the license above", + "submission.sections.ccLicense.confirmation": "Ich erteile die oben genannte Lizenz", // "submission.sections.general.add-more": "Add more", "submission.sections.general.add-more": "Mehr Hinzufügen", @@ -4864,7 +4801,7 @@ "submission.sections.general.collection": "Sammlung", // "submission.sections.general.deposit_error_notice": "There was an issue when submitting the item, please try again later.", - "submission.sections.general.deposit_error_notice": "Beim Einreichen der Ressource ist ein Fehler aufgetreten. Bitte versuchen Sie es später noch einmal.", + "submission.sections.general.deposit_error_notice": "Beim Einreichen des Items ist ein Fehler aufgetreten. Bitte versuchen Sie es später noch einmal.", // "submission.sections.general.deposit_success_notice": "Submission deposited successfully.", "submission.sections.general.deposit_success_notice": "Veröffentlichung erfolgreich eingereicht", @@ -4888,7 +4825,7 @@ "submission.sections.general.no-sections": "Es stehen keine Optionen zur Verfügung", // "submission.sections.general.save_error_notice": "There was an issue when saving the item, please try again later.", - "submission.sections.general.save_error_notice": "Beim Speichern der Ressource ist ein Fehler aufgetreten, bitte versuchen Sie es später noch einmal.", + "submission.sections.general.save_error_notice": "Beim Speichern des Items ist ein Fehler aufgetreten, bitte versuchen Sie es später noch einmal.", // "submission.sections.general.save_success_notice": "Submission saved successfully.", "submission.sections.general.save_success_notice": "Einreichung erfolgreich gespeichert.", @@ -4902,7 +4839,6 @@ // "submission.sections.submit.progressbar.CClicense": "Creative commons license", - // TODO New key - Add a translation "submission.sections.submit.progressbar.CClicense": "Creative commons license", // "submission.sections.submit.progressbar.describe.recycle": "Recycle", @@ -4944,7 +4880,7 @@ "submission.sections.upload.delete.submit": "Löschen", // "submission.sections.upload.drop-message": "Drop files to attach them to the item", - "submission.sections.upload.drop-message": "Dateien herüberziehen, um sie der Ressource hinzuzufügen", + "submission.sections.upload.drop-message": "Dateien herüberziehen, um sie dem Item hinzuzufügen", // "submission.sections.upload.form.access-condition-label": "Access condition type", "submission.sections.upload.form.access-condition-label": "Zugriffsbedingung Typ", @@ -4953,7 +4889,6 @@ "submission.sections.upload.form.date-required": "Datum erforderlich.", // "submission.sections.upload.form.from-label": "Grant access from", - // TODO Source message changed - Revise the translation "submission.sections.upload.form.from-label": "Zugriff gewährt ab", // "submission.sections.upload.form.from-placeholder": "From", @@ -4966,7 +4901,6 @@ "submission.sections.upload.form.group-required": "Gruppe ist erforderlich", // "submission.sections.upload.form.until-label": "Grant access until", - // TODO Source message changed - Revise the translation "submission.sections.upload.form.until-label": "Zugriff gewährt bis", // "submission.sections.upload.form.until-placeholder": "Until", @@ -4979,7 +4913,7 @@ "submission.sections.upload.header.policy.default.withlist": "Bitte beachten Sie, dass in diese Sammlung {{collectionName}} hochgeladene Dateien zugüglich zu dem, was für einzelne Dateien entschieden wurde, für folgende Gruppe(n) zugänglich sein:", // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", - "submission.sections.upload.info": "Hier finden Sie alle Dateien, die aktuell zur Ressource gehören. Sie können die Metadaten und Zugriffsrechte bearbeiten oder weitere Dateien hinzufügen, indem Sie sie einfach irgenwo auf diese Seite ziehen.", + "submission.sections.upload.info": "Hier finden Sie alle Dateien, die aktuell zum Item gehören. Sie können die Metadaten und Zugriffsrechte bearbeiten oder weitere Dateien hinzufügen, indem Sie sie einfach irgenwo auf diese Seite ziehen.", // "submission.sections.upload.no-entry": "No", "submission.sections.upload.no-entry": "Kein Eintrag", @@ -5010,19 +4944,19 @@ "submission.workflow.generic.delete": "Löschen", // "submission.workflow.generic.delete-help": "If you would to discard this item, select \"Delete\". You will then be asked to confirm it.", - "submission.workflow.generic.delete-help": "Wenn Sie die Ressource verwerfen möchten, wählen Sie \"Löschen\". Sie werden dies noch einmal gefragt, um die Aktion zu bestätigen.", + "submission.workflow.generic.delete-help": "Wenn Sie das Item verwerfen möchten, wählen Sie \"Löschen\". Sie werden dies noch einmal gefragt, um die Aktion zu bestätigen.", // "submission.workflow.generic.edit": "Edit", "submission.workflow.generic.edit": "Bearbeiten", // "submission.workflow.generic.edit-help": "Select this option to change the item's metadata.", - "submission.workflow.generic.edit-help": "Wählen Sie diese Option, um die Metadaten der Ressource zu bearbeiten.", + "submission.workflow.generic.edit-help": "Wählen Sie diese Option, um die Metadaten des Items zu bearbeiten.", // "submission.workflow.generic.view": "View", "submission.workflow.generic.view": "Anzeige", // "submission.workflow.generic.view-help": "Select this option to view the item's metadata.", - "submission.workflow.generic.view-help": "Wählen Sie diese Option, um die Metadaten der Ressourcen anzuzeigen", + "submission.workflow.generic.view-help": "Wählen Sie diese Option, um die Metadaten des Items anzuzeigen", @@ -5030,13 +4964,13 @@ "submission.workflow.tasks.claimed.approve": "Zustimmen", // "submission.workflow.tasks.claimed.approve_help": "If you have reviewed the item and it is suitable for inclusion in the collection, select \"Approve\".", - "submission.workflow.tasks.claimed.approve_help": "Wenn Sie die Ressource begutachtet haben und die Aufnahme in die Sammlung befürworten, wählen Sie \"Zustimmen\".", + "submission.workflow.tasks.claimed.approve_help": "Wenn Sie das Item begutachtet haben und die Aufnahme in die Sammlung befürworten, wählen Sie \"Zustimmen\".", // "submission.workflow.tasks.claimed.edit": "Edit", "submission.workflow.tasks.claimed.edit": "Bearbeiten", // "submission.workflow.tasks.claimed.edit_help": "Select this option to change the item's metadata.", - "submission.workflow.tasks.claimed.edit_help": "Wählen Sie diese Option, um die Metadaten der Ressource zu bearbeiten.", + "submission.workflow.tasks.claimed.edit_help": "Wählen Sie diese Option, um die Metadaten des Items zu bearbeiten.", // "submission.workflow.tasks.claimed.reject.reason.info": "Please enter your reason for rejecting the submission into the box below, indicating whether the submitter may fix a problem and resubmit.", "submission.workflow.tasks.claimed.reject.reason.info": "Bitte geben Sie den Grund für die Ablehnung der eingereichten Ressource in das Feld unten ein. Bitte geben Sie an ob und wie der/die Einreichende:n das Problem beheben und die Ressource erneut einreichen kann.", @@ -5045,7 +4979,7 @@ "submission.workflow.tasks.claimed.reject.reason.placeholder": "Beschreiben Sie den Grund für die Ablehnung", // "submission.workflow.tasks.claimed.reject.reason.submit": "Reject item", - "submission.workflow.tasks.claimed.reject.reason.submit": "Ressource ablehnen", + "submission.workflow.tasks.claimed.reject.reason.submit": "Item ablehnen", // "submission.workflow.tasks.claimed.reject.reason.title": "Reason", "submission.workflow.tasks.claimed.reject.reason.title": "Grund", @@ -5054,7 +4988,7 @@ "submission.workflow.tasks.claimed.reject.submit": "Ablehnen", // "submission.workflow.tasks.claimed.reject_help": "If you have reviewed the item and found it is not suitable for inclusion in the collection, select \"Reject\". You will then be asked to enter a message indicating why the item is unsuitable, and whether the submitter should change something and resubmit.", - "submission.workflow.tasks.claimed.reject_help": "Wenn Sie die Ressource begutachtet und als ungeeignet für die Aufnahme in die Sammlung befunden haben, wählen Sie \"Ablehnen\". Sie haben dann die Möglichkeit dem/der Einreichenden, den Grund für die Ablehnung zu erklären und ob es eine Möglichkeit gibt, durch entsprechenden Änderungen die Ressource erneut einzureichen.", + "submission.workflow.tasks.claimed.reject_help": "Wenn Sie das Item begutachtet und als ungeeignet für die Aufnahme in die Sammlung befunden haben, wählen Sie \"Ablehnen\". Sie haben dann die Möglichkeit dem/der Einreichenden, den Grund für die Ablehnung zu erklären und ob es eine Möglichkeit gibt, durch entsprechenden Änderungen das Item erneut einzureichen.", // "submission.workflow.tasks.claimed.return": "Return to pool", "submission.workflow.tasks.claimed.return": "Zurück in den gemeinsamen Aufgabenbereich", @@ -5142,7 +5076,7 @@ "virtual-metadata.delete-item.modal-head": "Virtuelle Metadaten dieser Relation", // "virtual-metadata.delete-relationship.modal-head": "Select the items for which you want to save the virtual metadata as real metadata", - "virtual-metadata.delete-relationship.modal-head": "Wählen Sie die Ressourcen für die Sie die virtuellen Metadaten als reelle Metadaten speichern wollen", + "virtual-metadata.delete-relationship.modal-head": "Wählen Sie die Items für die Sie die virtuellen Metadaten als reelle Metadaten speichern wollen", From 07000297183c5182326132624cb0948f252dd708 Mon Sep 17 00:00:00 2001 From: Pascal-Nicolas Becker Date: Wed, 9 Mar 2022 16:28:38 +0100 Subject: [PATCH 0078/2129] Working on inclusivness of the German translation --- src/assets/i18n/de.json5 | 42 ++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index d3fc1131aa4..bbac4ccdef7 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -107,7 +107,7 @@ "admin.registries.bitstream-formats.edit.head": "Dateiformat: {{ format }}", // "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.", - "admin.registries.bitstream-formats.edit.internal.hint": "Dateiformate, die als intern gekennzeichnet sind, dienen administrativen Zwecken und bleiben dem/der Endnutzer:in verborgen.", + "admin.registries.bitstream-formats.edit.internal.hint": "Dateiformate, die als intern gekennzeichnet sind, dienen administrativen Zwecken und bleiben dem:der Endnutzer:in verborgen.", // "admin.registries.bitstream-formats.edit.internal.label": "Internal", "admin.registries.bitstream-formats.edit.internal.label": "Intern", @@ -765,7 +765,7 @@ "bitstream.edit.form.description.label": "Beschreibung", // "bitstream.edit.form.embargo.hint": "The first day from which access is allowed. This date cannot be modified on this form. To set an embargo date for a bitstream, go to the Item Status tab, click Authorizations..., create or edit the bitstream's READ policy, and set the Start Date as desired.", - "bitstream.edit.form.embargo.hint": "Der erste Tag, ab dem der Zugang erlaubt ist. This date cannot be modified on this form. Um eine Embargo-Frist für eine Datei festzulegen, zu Item Status gehen, auf Authorizations... klicken, die Richtlinie READ für die Datei erstellen oder verändern und das Start Date wie gewünscht einstellen.", + "bitstream.edit.form.embargo.hint": "Der erste Tag, ab dem der Zugang erlaubt ist. Dieses Datum kann in diesem Formular nicht verändert werden. Um eine Embargo-Frist für eine Datei festzulegen, zu Item Status gehen, auf Authorizations... klicken, die Richtlinie READ für die Datei erstellen oder verändern und das Start Date wie gewünscht einstellen.", // "bitstream.edit.form.embargo.label": "Embargo until specific date", @@ -1499,7 +1499,7 @@ "cookies.consent.decline": "Ablehnen", // "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: Authentication, Preferences, Acknowledgement and Statistics.
    To learn more, please read our {privacyPolicy}.", - "cookies.consent.content-notice.description": "Wir sammeln und verarbeiten Ihre personenbezogenen Daten für die folgenden Zwecke: Authentication, Preferences, Acknowledgement and Statistics.
    Um mehr zu erfahren, lesen Sie bitte unsere {privacyPolicy}.", + "cookies.consent.content-notice.description": "Wir sammeln und verarbeiten Ihre personenbezogenen Daten für die folgenden Zwecke: Authentifikation, Einstellungen, Zustimmungen und Statistiken.
    Um mehr zu erfahren, lesen Sie bitte unsere {privacyPolicy}.", // "cookies.consent.content-notice.learnMore": "Customize", "cookies.consent.content-notice.learnMore": "Anpassen", @@ -1598,7 +1598,7 @@ "curation.form.handle.label": "Handle:", // "curation.form.handle.hint": "Hint: Enter [your-handle-prefix]/0 to run a task across entire site (not all tasks may support this capability)", - "curation.form.handle.hint": "Hinweis: Geben Sie [your-handle-prefix]/0 ein, um eine Aufgabe für die gesamte Seite durchzuführen (nicht alle Aufgaben unterstützen diese Funktion)", + "curation.form.handle.hint": "Hinweis: Geben Sie [handle-prefix]/0 ein, um eine Aufgabe für die gesamte Seite durchzuführen (nicht alle Aufgaben unterstützen diese Funktion)", @@ -2636,7 +2636,7 @@ "item.page.link.simple": "Kurzanzeige", // "item.page.person.search.title": "Articles by this author", - "item.page.person.search.title": "Veröffentlichungen dieses/dieser Autor:in", + "item.page.person.search.title": "Veröffentlichungen dieses:dieser Autor:in", // "item.page.related-items.view-more": "Show {{ amount }} more", "item.page.related-items.view-more": "{{ amount }} mehr anzeigen", @@ -3182,7 +3182,7 @@ "mydspace.general.text-here": "hier", // "mydspace.messages.controller-help": "Select this option to send a message to item's submitter.", - "mydspace.messages.controller-help": "Wählen Sie diese Option, um dem/derjenigen, die das Item eingereicht hat, eine Nachricht zu schicken.", + "mydspace.messages.controller-help": "Wählen Sie diese Option, um dem:derjenigen, die das Item eingereicht hat, eine Nachricht zu schicken.", // "mydspace.messages.description-placeholder": "Insert your message here...", "mydspace.messages.description-placeholder": "Geben Sie Ihre Nachricht hier ein...", @@ -3290,10 +3290,10 @@ "mydspace.upload.upload-failed-moreonefile": "Unverarbeitbare Anfrage. Nur eine Datei ist erlaubt.", // "mydspace.upload.upload-multiple-successful": "{{qty}} new workspace items created.", - "mydspace.upload.upload-multiple-successful": "{{qty}} neue(s) Arbeitsbereichitem(s) angelegt.", + "mydspace.upload.upload-multiple-successful": "{{qty}} neue(s) Arbeitsbereichsitem(s) angelegt.", // "mydspace.upload.upload-successful": "New workspace item created. Click {{here}} for edit it.", - "mydspace.upload.upload-successful": "Neues Arbeitsbereichitem angelegt. Klicken Sie {{here}}, um sie zu bearbeiten.", + "mydspace.upload.upload-successful": "Neues Arbeitsbereichsitem angelegt. Klicken Sie {{here}}, um sie zu bearbeiten.", // "mydspace.view-btn": "View", "mydspace.view-btn": "Anzeige", @@ -3763,7 +3763,7 @@ "register-page.create-profile.submit.error.head": "Registrierung fehlgeschlagen.", // "register-page.create-profile.submit.success.content": "The registration was successful. You have been logged in as the created user.", - "register-page.create-profile.submit.success.content": "Die Registrierung war erfolgreich. Sie wurden als der/die angelegte Benutzer:in angemeldet.", + "register-page.create-profile.submit.success.content": "Die Registrierung war erfolgreich. Sie wurden als der:die angelegte Benutzer:in angemeldet.", // "register-page.create-profile.submit.success.head": "Registration completed", "register-page.create-profile.submit.success.head": "Registrierung abgeschlossen", @@ -4078,7 +4078,7 @@ "search.filters.filter.author.head": "Autor:in", // "search.filters.filter.author.placeholder": "Author name", - "search.filters.filter.author.placeholder": "Name des/der Autor:in", + "search.filters.filter.author.placeholder": "Name des:der Autor:in", // "search.filters.filter.birthDate.head": "Birth Date", "search.filters.filter.birthDate.head": "Geburtsdatum", @@ -4474,10 +4474,10 @@ "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "Importiere Autor:innen-Metadaten", // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "Successfully added local author to the selection", - "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "Erfolgreicher Import und Hinzufügen eines/einer lokalen Autor:in zur Auswahl", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "Erfolgreicher Import und Hinzufügen eines:einer lokalen Autor:in zur Auswahl", // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.new-entity": "Successfully imported and added external author to the selection", - "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.new-entity": "Erfolgreicher Import und Hinzufügen eines/einer externen Autor:in zur Auswahl", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.new-entity": "Erfolgreicher Import und Hinzufügen eines:einer externen Autor:in zur Auswahl", // "submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "Authority", "submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "Referenz", @@ -4573,7 +4573,7 @@ "submission.sections.describe.relationship-lookup.selected": "{{ size }} Items ausgewählt", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "Local Authors ({{ count }})", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "Lokale Autoren ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "Lokale Autor:innen ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalOfPublication": "Local Journals ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalOfPublication": "Lokale Zeitschriften ({{ count }})", @@ -4585,7 +4585,7 @@ "submission.sections.describe.relationship-lookup.search-tab.tab-title.Publication": "Lokale Publicationen ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "Local Authors ({{ count }})", - "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "Lokale Autoren ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "Lokale Autor:innen ({{ count }})", // "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "Local Organizational Units ({{ count }})", "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "Lokale Organisationseinheiten ({{ count }})", @@ -4973,7 +4973,7 @@ "submission.workflow.tasks.claimed.edit_help": "Wählen Sie diese Option, um die Metadaten des Items zu bearbeiten.", // "submission.workflow.tasks.claimed.reject.reason.info": "Please enter your reason for rejecting the submission into the box below, indicating whether the submitter may fix a problem and resubmit.", - "submission.workflow.tasks.claimed.reject.reason.info": "Bitte geben Sie den Grund für die Ablehnung der eingereichten Ressource in das Feld unten ein. Bitte geben Sie an ob und wie der/die Einreichende:n das Problem beheben und die Ressource erneut einreichen kann.", + "submission.workflow.tasks.claimed.reject.reason.info": "Bitte geben Sie den Grund für die Ablehnung der eingereichten Ressource in das Feld unten ein. Bitte geben Sie an ob und wie der:die Einreichende:n das Problem beheben und die Ressource erneut einreichen kann.", // "submission.workflow.tasks.claimed.reject.reason.placeholder": "Describe the reason of reject", "submission.workflow.tasks.claimed.reject.reason.placeholder": "Beschreiben Sie den Grund für die Ablehnung", @@ -4988,7 +4988,7 @@ "submission.workflow.tasks.claimed.reject.submit": "Ablehnen", // "submission.workflow.tasks.claimed.reject_help": "If you have reviewed the item and found it is not suitable for inclusion in the collection, select \"Reject\". You will then be asked to enter a message indicating why the item is unsuitable, and whether the submitter should change something and resubmit.", - "submission.workflow.tasks.claimed.reject_help": "Wenn Sie das Item begutachtet und als ungeeignet für die Aufnahme in die Sammlung befunden haben, wählen Sie \"Ablehnen\". Sie haben dann die Möglichkeit dem/der Einreichenden, den Grund für die Ablehnung zu erklären und ob es eine Möglichkeit gibt, durch entsprechenden Änderungen das Item erneut einzureichen.", + "submission.workflow.tasks.claimed.reject_help": "Wenn Sie das Item begutachtet und als ungeeignet für die Aufnahme in die Sammlung befunden haben, wählen Sie \"Ablehnen\". Sie haben dann die Möglichkeit dem:der Einreichenden, den Grund für die Ablehnung zu erklären und ob es eine Möglichkeit gibt, durch entsprechenden Änderungen das Item erneut einzureichen.", // "submission.workflow.tasks.claimed.return": "Return to pool", "submission.workflow.tasks.claimed.return": "Zurück in den gemeinsamen Aufgabenbereich", @@ -5111,22 +5111,22 @@ // "workflow-item.send-back.notification.success.title": "Sent back to submitter", - "workflow-item.send-back.notification.success.title": "An die/den Einreichende:n zurückgeschickt", + "workflow-item.send-back.notification.success.title": "An die:den Einreichende:n zurückgeschickt", // "workflow-item.send-back.notification.success.content": "This workflow item was successfully sent back to the submitter", - "workflow-item.send-back.notification.success.content": "Dieses Workflow-Item wurde erfolgreich an die/den Einreichende:n zurückgeschickt", + "workflow-item.send-back.notification.success.content": "Dieses Workflow-Item wurde erfolgreich an die:den Einreichende:n zurückgeschickt", // "workflow-item.send-back.notification.error.title": "Something went wrong", "workflow-item.send-back.notification.error.title": "Etwas ist schief gelaufen", // "workflow-item.send-back.notification.error.content": "The workflow item could not be sent back to the submitter", - "workflow-item.send-back.notification.error.content": "Das Workflow-Item konnte nicht an die/den Einreichende:n zurückgeschickt werden", + "workflow-item.send-back.notification.error.content": "Das Workflow-Item konnte nicht an die:den Einreichende:n zurückgeschickt werden", // "workflow-item.send-back.title": "Send workflow item back to submitter", - "workflow-item.send-back.title": "Workflow-Item an die/den Einreichende:n zurücksenden", + "workflow-item.send-back.title": "Workflow-Item an die:den Einreichende:n zurücksenden", // "workflow-item.send-back.header": "Send workflow item back to submitter", - "workflow-item.send-back.header": "Workflow-Item an die/den Einreichende:n zurücksenden", + "workflow-item.send-back.header": "Workflow-Item an die:den Einreichende:n zurücksenden", // "workflow-item.send-back.button.cancel": "Cancel", "workflow-item.send-back.button.cancel": "Abbrechen", From 2ffb72320221b923d0064fec6fc47a04d34606ac Mon Sep 17 00:00:00 2001 From: Sufiyan Shaikh Date: Thu, 10 Mar 2022 13:04:22 +0530 Subject: [PATCH 0079/2129] [CST-5329] Add validate only check in the Import > Metadata page --- .../metadata-import-page.component.html | 4 +++ .../metadata-import-page.component.spec.ts | 25 ++++++++++++++++++- .../metadata-import-page.component.ts | 8 ++++++ src/assets/i18n/en.json5 | 2 ++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html index 42a04b0de6b..c70bc459471 100644 --- a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html +++ b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html @@ -1,6 +1,10 @@

    {{'admin.metadata-import.page.help' | translate}}

    +

    + + {{'admin.metadata-import.page.validateOnly' | translate}} +

    { comp.setFile(fileMock); }); - describe('if proceed button is pressed', () => { + describe('if proceed button is pressed without validate only', () => { beforeEach(fakeAsync(() => { + comp.validateOnly = false; const proceed = fixture.debugElement.query(By.css('#proceedButton')).nativeElement; proceed.click(); fixture.detectChanges(); @@ -107,6 +108,28 @@ describe('MetadataImportPageComponent', () => { }); }); + describe('if proceed button is pressed with validate only', () => { + beforeEach(fakeAsync(() => { + comp.validateOnly = true; + const proceed = fixture.debugElement.query(By.css('#proceedButton')).nativeElement; + proceed.click(); + fixture.detectChanges(); + })); + it('metadata-import script is invoked with -f fileName and the mockFile and -v validate-only', () => { + const parameterValues: ProcessParameter[] = [ + Object.assign(new ProcessParameter(), { name: '-f', value: 'filename.txt' }), + Object.assign(new ProcessParameter(), { name: '-v', value: true }), + ]; + expect(scriptService.invoke).toHaveBeenCalledWith(METADATA_IMPORT_SCRIPT_NAME, parameterValues, [fileMock]); + }); + it('success notification is shown', () => { + expect(notificationService.success).toHaveBeenCalled(); + }); + it('redirected to process page', () => { + expect(router.navigateByUrl).toHaveBeenCalledWith('/processes/45'); + }); + }); + describe('if proceed is pressed; but script invoke fails', () => { beforeEach(fakeAsync(() => { jasmine.getEnv().allowRespy(true); diff --git a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.ts b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.ts index 3bdcca3084a..deb16c0d732 100644 --- a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.ts +++ b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.ts @@ -30,6 +30,11 @@ export class MetadataImportPageComponent { */ fileObject: File; + /** + * The validate only flag + */ + validateOnly = true; + public constructor(private location: Location, protected translate: TranslateService, protected notificationsService: NotificationsService, @@ -62,6 +67,9 @@ export class MetadataImportPageComponent { const parameterValues: ProcessParameter[] = [ Object.assign(new ProcessParameter(), { name: '-f', value: this.fileObject.name }), ]; + if (this.validateOnly) { + parameterValues.push(Object.assign(new ProcessParameter(), { name: '-v', value: true })); + } this.scriptDataService.invoke(METADATA_IMPORT_SCRIPT_NAME, parameterValues, [this.fileObject]).pipe( getFirstCompletedRemoteData(), diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index f33a195cfed..426fcb12d27 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -538,6 +538,8 @@ "admin.metadata-import.page.error.addFile": "Select file first!", + "admin.metadata-import.page.validateOnly": "Validate Only", + From 027b281d7a61031370a62f1388d23b8369410808 Mon Sep 17 00:00:00 2001 From: Sufiyan Shaikh Date: Thu, 10 Mar 2022 14:45:53 +0530 Subject: [PATCH 0080/2129] [CST-5329] Add validate only check in the Import > Metadata page --- .../metadata-import-page.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html index c70bc459471..fb96c4becd5 100644 --- a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html +++ b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html @@ -3,7 +3,7 @@

    {{'admin.metadata-import.page.help' | translate}}

    - {{'admin.metadata-import.page.validateOnly' | translate}} + {{'admin.metadata-import.page.validateOnly' | translate}}

    Date: Fri, 11 Mar 2022 12:18:14 +0100 Subject: [PATCH 0081/2129] [CST-5449] Fix failed test --- .../shared/browse-by/browse-by.component.html | 6 ++--- .../browse-by/browse-by.component.spec.ts | 26 +++++++------------ 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/app/shared/browse-by/browse-by.component.html b/src/app/shared/browse-by/browse-by.component.html index cc126768e4a..3b72ce2d233 100644 --- a/src/app/shared/browse-by/browse-by.component.html +++ b/src/app/shared/browse-by/browse-by.component.html @@ -1,15 +1,15 @@ -

    {{title | translate}}

    +

    {{title | translate}}

    - - +
    diff --git a/src/app/shared/browse-by/browse-by.component.spec.ts b/src/app/shared/browse-by/browse-by.component.spec.ts index 1e739dafbff..601c3527059 100644 --- a/src/app/shared/browse-by/browse-by.component.spec.ts +++ b/src/app/shared/browse-by/browse-by.component.spec.ts @@ -4,20 +4,17 @@ import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { By } from '@angular/platform-browser'; import { Component, NO_ERRORS_SCHEMA } from '@angular/core'; import { of as observableOf } from 'rxjs'; -import { SharedModule } from '../shared.module'; import { CommonModule } from '@angular/common'; import { Item } from '../../core/shared/item.model'; import { buildPaginatedList } from '../../core/data/paginated-list.model'; import { PageInfo } from '../../core/shared/page-info.model'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; -import { StoreModule } from '@ngrx/store'; import { TranslateLoaderMock } from '../mocks/translate-loader.mock'; import { RouterTestingModule } from '@angular/router/testing'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; -import { storeModuleConfig } from '../../app.reducer'; import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../testing/pagination-service.stub'; import { ListableObjectComponentLoaderComponent } from '../object-collection/shared/listable-object/listable-object-component-loader.component'; @@ -30,17 +27,18 @@ import { import { BrowseEntry } from '../../core/shared/browse-entry.model'; import { ITEM } from '../../core/shared/item.resource-type'; import { ThemeService } from '../theme-support/theme.service'; -import SpyObj = jasmine.SpyObj; import { SelectableListService } from '../object-list/selectable-list/selectable-list.service'; +import { HostWindowServiceStub } from '../testing/host-window-service.stub'; import { HostWindowService } from '../host-window.service'; -import { CSSVariableService } from '../sass-helper/sass-helper.service'; +import SpyObj = jasmine.SpyObj; @listableObjectComponent(BrowseEntry, ViewMode.ListElement, DEFAULT_CONTEXT, 'custom') @Component({ selector: 'ds-browse-entry-list-element', template: '' }) -class MockThemedBrowseEntryListElementComponent {} +class MockThemedBrowseEntryListElementComponent { +} describe('BrowseByComponent', () => { let comp: BrowseByComponent; @@ -86,10 +84,7 @@ describe('BrowseByComponent', () => { TestBed.configureTestingModule({ imports: [ CommonModule, - TranslateModule.forRoot(), - SharedModule, NgbModule, - StoreModule.forRoot({}, storeModuleConfig), TranslateModule.forRoot({ loader: { provide: TranslateLoader, @@ -97,16 +92,15 @@ describe('BrowseByComponent', () => { } }), RouterTestingModule, - BrowserAnimationsModule + NoopAnimationsModule ], declarations: [], providers: [ - {provide: PaginationService, useValue: paginationService}, - {provide: MockThemedBrowseEntryListElementComponent}, + { provide: PaginationService, useValue: paginationService }, + { provide: MockThemedBrowseEntryListElementComponent }, { provide: ThemeService, useValue: themeService }, - SelectableListService, - HostWindowService, - CSSVariableService + { provide: SelectableListService, useValue: {} }, + { provide: HostWindowService, useValue: new HostWindowServiceStub(800) }, ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); From d4ed4ca88350eccaab9f127644ff7843c7d61cfa Mon Sep 17 00:00:00 2001 From: reetagithub <51482276+reetagithub@users.noreply.github.com> Date: Mon, 14 Mar 2022 09:05:48 +0200 Subject: [PATCH 0082/2129] Corrected a typo --- src/assets/i18n/fi.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/i18n/fi.json5 b/src/assets/i18n/fi.json5 index 0348b906c22..02f020a45d1 100644 --- a/src/assets/i18n/fi.json5 +++ b/src/assets/i18n/fi.json5 @@ -4120,7 +4120,7 @@ "search.filters.filter.dateSubmitted.placeholder": "Tallennnusajankohta", // "search.filters.filter.discoverable.head": "Private", - "search.filters.filter.discoverable.head": "Ykstyinen", + "search.filters.filter.discoverable.head": "Yksityinen", // "search.filters.filter.withdrawn.head": "Withdrawn", "search.filters.filter.withdrawn.head": "Poistettu käytöstä", From 3a4a10e45385b46ee977fd4282b86b8ed9b140f5 Mon Sep 17 00:00:00 2001 From: William Welling <8352733+wwelling@users.noreply.github.com> Date: Mon, 14 Mar 2022 08:26:22 -0500 Subject: [PATCH 0083/2129] set default env preboot to false leaving production env to true --- src/environments/environment.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/environments/environment.ts b/src/environments/environment.ts index a64ccf26081..dc0e808be0d 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -10,7 +10,7 @@ export const environment: Partial = { // Angular Universal settings universal: { - preboot: true, + preboot: false, async: true, time: false } From b21f76456d641192d1b9b65362c0c6a7396be5b1 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Mon, 14 Mar 2022 16:33:10 +0100 Subject: [PATCH 0084/2129] 88248: #346: Withdrawn item tombstone page --- .../full/full-item-page.component.html | 44 ++++++------ .../full/full-item-page.component.spec.ts | 67 ++++++++++++++++++- .../full/full-item-page.component.ts | 4 +- .../item-page/simple/item-page.component.html | 2 +- .../simple/item-page.component.spec.ts | 62 +++++++++++++++++ .../item-page/simple/item-page.component.ts | 12 +++- .../item-alerts/item-alerts.component.html | 17 +++-- 7 files changed, 178 insertions(+), 30 deletions(-) diff --git a/src/app/item-page/full/full-item-page.component.html b/src/app/item-page/full/full-item-page.component.html index d2655c4ad03..e71dd92f966 100644 --- a/src/app/item-page/full/full-item-page.component.html +++ b/src/app/item-page/full/full-item-page.component.html @@ -4,19 +4,21 @@ -
    - -
    - +
    +
    + +
    + +
    -
    - - - + +
    + @@ -24,14 +26,16 @@ - -
    {{mdEntry.key}}{{mdValue.language}}
    - - - -
    -
    - + + + + + +
    +
    + +
    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 b4ab9266673..c7643a940e9 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 @@ -11,12 +11,15 @@ 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 { BehaviorSubject, of as observableOf } from 'rxjs'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { By } from '@angular/platform-browser'; import { 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 { createRelationshipsObservable } from '../simple/item-types/shared/item.component.spec'; +import { RemoteData } from '../../core/data/remote-data'; const mockItem: Item = Object.assign(new Item(), { bundles: createSuccessfulRemoteDataObject$(createPaginatedList([])), @@ -30,6 +33,13 @@ const mockItem: Item = Object.assign(new Item(), { } }); +const mockWithdrawnItem: Item = Object.assign(new Item(), { + bundles: createSuccessfulRemoteDataObject$(createPaginatedList([])), + metadata: [], + relationships: createRelationshipsObservable(), + isWithdrawn: true +}); + const metadataServiceStub = { /* tslint:disable:no-empty */ processRemoteData: () => { @@ -44,6 +54,7 @@ describe('FullItemPageComponent', () => { let authService: AuthService; let routeStub: ActivatedRouteStub; let routeData; + let authorizationDataService: AuthorizationDataService; @@ -61,6 +72,10 @@ describe('FullItemPageComponent', () => { data: observableOf(routeData) }); + authorizationDataService = jasmine.createSpyObj('authorizationDataService', { + isAuthorized: observableOf(false), + }); + TestBed.configureTestingModule({ imports: [TranslateModule.forRoot({ loader: { @@ -74,6 +89,7 @@ describe('FullItemPageComponent', () => { { provide: ItemDataService, useValue: {} }, { provide: MetadataService, useValue: metadataServiceStub }, { provide: AuthService, useValue: authService }, + { provide: AuthorizationDataService, useValue: authorizationDataService }, ], schemas: [NO_ERRORS_SCHEMA] @@ -111,4 +127,53 @@ describe('FullItemPageComponent', () => { expect(simpleViewBtn).toBeFalsy(); }); })); + + describe('when the item is withdrawn and the user is an admin', () => { + beforeEach(() => { + comp.isAdmin$ = observableOf(true); + comp.itemRD$ = new BehaviorSubject>(createSuccessfulRemoteDataObject(mockWithdrawnItem)); + fixture.detectChanges(); + }); + + it('should display the item', () => { + const objectLoader = fixture.debugElement.query(By.css('.full-item-info')); + expect(objectLoader.nativeElement).toBeDefined(); + }); + }); + describe('when the item is withdrawn and the user is not an admin', () => { + beforeEach(() => { + comp.itemRD$ = new BehaviorSubject>(createSuccessfulRemoteDataObject(mockWithdrawnItem)); + fixture.detectChanges(); + }); + + it('should not display the item', () => { + const objectLoader = fixture.debugElement.query(By.css('.full-item-info')); + expect(objectLoader).toBeNull(); + }); + }); + + describe('when the item is not withdrawn and the user is an admin', () => { + beforeEach(() => { + comp.isAdmin$ = observableOf(true); + comp.itemRD$ = new BehaviorSubject>(createSuccessfulRemoteDataObject(mockItem)); + fixture.detectChanges(); + }); + + it('should display the item', () => { + const objectLoader = fixture.debugElement.query(By.css('.full-item-info')); + expect(objectLoader.nativeElement).toBeDefined(); + }); + }); + + describe('when the item is not withdrawn and the user is not an admin', () => { + beforeEach(() => { + comp.itemRD$ = new BehaviorSubject>(createSuccessfulRemoteDataObject(mockItem)); + fixture.detectChanges(); + }); + + it('should display the item', () => { + const objectLoader = fixture.debugElement.query(By.css('.full-item-info')); + expect(objectLoader.nativeElement).toBeDefined(); + }); + }); }); 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 7f1b6de614d..369769c77d1 100644 --- a/src/app/item-page/full/full-item-page.component.ts +++ b/src/app/item-page/full/full-item-page.component.ts @@ -15,6 +15,7 @@ import { fadeInOut } from '../../shared/animations/fade'; 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'; /** @@ -46,8 +47,9 @@ export class FullItemPageComponent extends ItemPageComponent implements OnInit, router: Router, items: ItemDataService, authService: AuthService, + authorizationService: AuthorizationDataService, private _location: Location) { - super(route, router, items, authService); + super(route, router, items, authService, authorizationService); } /*** AoT inheritance fix, will hopefully be resolved in the near future **/ diff --git a/src/app/item-page/simple/item-page.component.html b/src/app/item-page/simple/item-page.component.html index e843155d10a..3e834b53dba 100644 --- a/src/app/item-page/simple/item-page.component.html +++ b/src/app/item-page/simple/item-page.component.html @@ -4,7 +4,7 @@ - +
    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 ff5a1e38d51..2ad0bbb272c 100644 --- a/src/app/item-page/simple/item-page.component.spec.ts +++ b/src/app/item-page/simple/item-page.component.spec.ts @@ -21,6 +21,7 @@ import { } 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'; const mockItem: Item = Object.assign(new Item(), { bundles: createSuccessfulRemoteDataObject$(createPaginatedList([])), @@ -28,10 +29,18 @@ const mockItem: Item = Object.assign(new Item(), { relationships: createRelationshipsObservable() }); +const mockWithdrawnItem: Item = Object.assign(new Item(), { + bundles: createSuccessfulRemoteDataObject$(createPaginatedList([])), + metadata: [], + relationships: createRelationshipsObservable(), + isWithdrawn: true +}); + describe('ItemPageComponent', () => { let comp: ItemPageComponent; let fixture: ComponentFixture; let authService: AuthService; + let authorizationDataService: AuthorizationDataService; const mockMetadataService = { /* tslint:disable:no-empty */ @@ -48,6 +57,9 @@ describe('ItemPageComponent', () => { isAuthenticated: observableOf(true), setRedirectUrl: {} }); + authorizationDataService = jasmine.createSpyObj('authorizationDataService', { + isAuthorized: observableOf(false), + }); TestBed.configureTestingModule({ imports: [TranslateModule.forRoot({ @@ -63,6 +75,7 @@ describe('ItemPageComponent', () => { { provide: MetadataService, useValue: mockMetadataService }, { provide: Router, useValue: {} }, { provide: AuthService, useValue: authService }, + { provide: AuthorizationDataService, useValue: authorizationDataService }, ], schemas: [NO_ERRORS_SCHEMA] @@ -102,4 +115,53 @@ describe('ItemPageComponent', () => { }); }); + describe('when the item is withdrawn and the user is an admin', () => { + beforeEach(() => { + comp.isAdmin$ = observableOf(true); + comp.itemRD$ = createSuccessfulRemoteDataObject$(mockWithdrawnItem); + fixture.detectChanges(); + }); + + it('should display the item', () => { + const objectLoader = fixture.debugElement.query(By.css('ds-listable-object-component-loader')); + expect(objectLoader.nativeElement).toBeDefined(); + }); + }); + describe('when the item is withdrawn and the user is not an admin', () => { + beforeEach(() => { + comp.itemRD$ = createSuccessfulRemoteDataObject$(mockWithdrawnItem); + fixture.detectChanges(); + }); + + it('should not display the item', () => { + const objectLoader = fixture.debugElement.query(By.css('ds-listable-object-component-loader')); + expect(objectLoader).toBeNull(); + }); + }); + + describe('when the item is not withdrawn and the user is an admin', () => { + beforeEach(() => { + comp.isAdmin$ = observableOf(true); + comp.itemRD$ = createSuccessfulRemoteDataObject$(mockItem); + fixture.detectChanges(); + }); + + it('should display the item', () => { + const objectLoader = fixture.debugElement.query(By.css('ds-listable-object-component-loader')); + expect(objectLoader.nativeElement).toBeDefined(); + }); + }); + + describe('when the item is not withdrawn and the user is not an admin', () => { + beforeEach(() => { + comp.itemRD$ = createSuccessfulRemoteDataObject$(mockItem); + fixture.detectChanges(); + }); + + it('should display the item', () => { + const objectLoader = fixture.debugElement.query(By.css('ds-listable-object-component-loader')); + expect(objectLoader.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 cc23ba86d5e..0559dc22191 100644 --- a/src/app/item-page/simple/item-page.component.ts +++ b/src/app/item-page/simple/item-page.component.ts @@ -1,4 +1,4 @@ -import { map } from 'rxjs/operators'; +import { map, switchMap } from 'rxjs/operators'; import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; @@ -13,6 +13,8 @@ import { getAllSucceededRemoteDataPayload, redirectOn4xx } from '../../core/shar import { ViewMode } from '../../core/shared/view-mode.model'; import { AuthService } from '../../core/auth/auth.service'; import { getItemPageRoute } from '../item-page-routing-paths'; +import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; +import { FeatureID } from '../../core/data/feature-authorization/feature-id'; /** * This component renders a simple item page. @@ -48,11 +50,17 @@ export class ItemPageComponent implements OnInit { */ itemPageRoute$: Observable; + /** + * Whether the current user is an admin or not + */ + isAdmin$: Observable; + constructor( protected route: ActivatedRoute, private router: Router, private items: ItemDataService, private authService: AuthService, + private authorizationService: AuthorizationDataService ) { } /** @@ -67,5 +75,7 @@ export class ItemPageComponent implements OnInit { getAllSucceededRemoteDataPayload(), map((item) => getItemPageRoute(item)) ); + + this.isAdmin$ = this.authorizationService.isAuthorized(FeatureID.AdministratorOf); } } diff --git a/src/app/shared/item/item-alerts/item-alerts.component.html b/src/app/shared/item/item-alerts/item-alerts.component.html index fce5c038e54..740ea2595d2 100644 --- a/src/app/shared/item/item-alerts/item-alerts.component.html +++ b/src/app/shared/item/item-alerts/item-alerts.component.html @@ -1,8 +1,13 @@
    -
    - -
    -
    - -
    +
    + +
    +
    + +
    + {{'item.alerts.withdrawn' | translate}} + {{"404.link.home-page" | translate}} +
    +
    +
    From 90e469ee167a3c37046825f0aea0f98ec9b7064f Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Mon, 14 Mar 2022 17:21:34 +0100 Subject: [PATCH 0085/2129] Fix LGTM issue --- src/app/item-page/simple/item-page.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/item-page/simple/item-page.component.ts b/src/app/item-page/simple/item-page.component.ts index 0559dc22191..95fbd7a2e04 100644 --- a/src/app/item-page/simple/item-page.component.ts +++ b/src/app/item-page/simple/item-page.component.ts @@ -1,4 +1,4 @@ -import { map, switchMap } from 'rxjs/operators'; +import { map } from 'rxjs/operators'; import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; From 97dc241c5208d949826a6ebd930615adb47c31c7 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Thu, 17 Mar 2022 13:00:00 +0100 Subject: [PATCH 0086/2129] 88300: Issue 1379 - Angular: Browse-by Subject does not allow to proceed to next pages once filtered --- .../shared/browse-by/browse-by.component.html | 23 +++- .../browse-by/browse-by.component.spec.ts | 20 +++- .../shared/browse-by/browse-by.component.ts | 19 ++- .../text/starts-with-text.component.html | 19 --- .../text/starts-with-text.component.spec.ts | 110 ------------------ src/app/shared/testing/route-service.stub.ts | 7 +- src/assets/i18n/en.json5 | 6 +- 7 files changed, 65 insertions(+), 139 deletions(-) diff --git a/src/app/shared/browse-by/browse-by.component.html b/src/app/shared/browse-by/browse-by.component.html index c1333246812..4837c92db86 100644 --- a/src/app/shared/browse-by/browse-by.component.html +++ b/src/app/shared/browse-by/browse-by.component.html @@ -12,6 +12,10 @@

    {{title | translate}}

    +
    @@ -29,14 +33,25 @@
- - + +
- diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.ts b/src/app/entity-groups/research-entities/item-pages/person/person.component.ts index 8b104cc9b13..ad2863034ac 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.ts +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; -import { ItemComponent } from '../../../../item-page/simple/item-types/shared/item.component'; import { ViewMode } from '../../../../core/shared/view-mode.model'; import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; +import { VersionedItemComponent } from '../../../../item-page/simple/item-types/versioned-item/versioned-item.component'; @listableObjectComponent('Person', ViewMode.StandalonePage) @Component({ @@ -12,5 +12,5 @@ import { listableObjectComponent } from '../../../../shared/object-collection/sh /** * The component for displaying metadata and relations of an item of the type Person */ -export class PersonComponent extends ItemComponent { +export class PersonComponent extends VersionedItemComponent { } diff --git a/src/app/entity-groups/research-entities/item-pages/project/project.component.html b/src/app/entity-groups/research-entities/item-pages/project/project.component.html index 8f2ff6adcda..243dae8b432 100644 --- a/src/app/entity-groups/research-entities/item-pages/project/project.component.html +++ b/src/app/entity-groups/research-entities/item-pages/project/project.component.html @@ -3,6 +3,9 @@

{{'project.page.titleprefix' | translate}}

+
diff --git a/src/app/entity-groups/research-entities/item-pages/project/project.component.ts b/src/app/entity-groups/research-entities/item-pages/project/project.component.ts index e53d8afd693..066427fc0d5 100644 --- a/src/app/entity-groups/research-entities/item-pages/project/project.component.ts +++ b/src/app/entity-groups/research-entities/item-pages/project/project.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; -import { ItemComponent } from '../../../../item-page/simple/item-types/shared/item.component'; import { ViewMode } from '../../../../core/shared/view-mode.model'; import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; +import { VersionedItemComponent } from '../../../../item-page/simple/item-types/versioned-item/versioned-item.component'; @listableObjectComponent('Project', ViewMode.StandalonePage) @Component({ @@ -12,5 +12,5 @@ import { listableObjectComponent } from '../../../../shared/object-collection/sh /** * The component for displaying metadata and relations of an item of the type Project */ -export class ProjectComponent extends ItemComponent { +export class ProjectComponent extends VersionedItemComponent { } diff --git a/src/app/item-page/simple/item-types/publication/publication.component.html b/src/app/item-page/simple/item-types/publication/publication.component.html index bace9fcd0ad..667dee96f53 100644 --- a/src/app/item-page/simple/item-types/publication/publication.component.html +++ b/src/app/item-page/simple/item-types/publication/publication.component.html @@ -12,6 +12,9 @@

{{'publication.page.titleprefix' | translate}}

+
diff --git a/src/app/item-page/simple/item-types/publication/publication.component.ts b/src/app/item-page/simple/item-types/publication/publication.component.ts index 5ace8d04739..ba5037a1043 100644 --- a/src/app/item-page/simple/item-types/publication/publication.component.ts +++ b/src/app/item-page/simple/item-types/publication/publication.component.ts @@ -1,7 +1,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; -import { ItemComponent } from '../shared/item.component'; import { ViewMode } from '../../../../core/shared/view-mode.model'; import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; +import { VersionedItemComponent } from '../versioned-item/versioned-item.component'; /** * Component that represents a publication Item page @@ -14,6 +14,6 @@ import { listableObjectComponent } from '../../../../shared/object-collection/sh templateUrl: './publication.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) -export class PublicationComponent extends ItemComponent { +export class PublicationComponent extends VersionedItemComponent { } From 26f821e8655d595796005670dd81e6c07cb68d1e Mon Sep 17 00:00:00 2001 From: louiserumpf <101128103+louiserumpf@users.noreply.github.com> Date: Tue, 22 Mar 2022 11:18:44 +0100 Subject: [PATCH 0095/2129] updated German translation --- src/assets/i18n/de.json5 | 236 +++++++++++++++++++-------------------- 1 file changed, 118 insertions(+), 118 deletions(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index bbac4ccdef7..bf7df7619a9 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -4,7 +4,7 @@ "401.help": "Sie sind nicht berechtigt, auf diese Seite zuzugreifen. Mit dem Link unten kommen Sie zurück zur Startseite.", // "401.link.home-page": "Take me to the home page", - "401.link.home-page": "Bringe mich zur Startseite", + "401.link.home-page": "Zur Startseite", // "401.unauthorized": "unauthorized", "401.unauthorized": "unautorisiert", @@ -12,10 +12,10 @@ // "403.help": "You don't have permission to access this page. You can use the button below to get back to the home page.", - "403.help": "Sie haben keine Berechtigung, auf diese Seite zuzugreifen. Mit dem Link unten kommen Sie zurück zur Startseite.", + "403.help": "Sie sind nicht berechtigt, auf diese Seite zuzugreifen. Über den Button unten auf der Seite gelangen Sie zurück zur Startseite.", // "403.link.home-page": "Take me to the home page", - "403.link.home-page": "Bringe mich zur Startseite", + "403.link.home-page": "Zur Startseite", // "403.forbidden": "forbidden", "403.forbidden": "verboten", @@ -23,22 +23,22 @@ // "404.help": "We can't find the page you're looking for. The page may have been moved or deleted. You can use the button below to get back to the home page. ", - "404.help": "Die Seite, die Sie aufrufen wollten, konnte nicht gefunden werden. Sie könnte verschoben oder gelöscht worden sein. Mit dem Link unten kommen Sie zurück zur Startseite. ", + "404.help": "Die Seite konnte nicht gefunden werden. Eventuell wurde sie verschoben oder gelöscht. Über den Button unten auf der Seite gelangen Sie zurück zur Startseite.", // "404.link.home-page": "Take me to the home page", - "404.link.home-page": "Zurück zur Startseite", + "404.link.home-page": "Zur Startseite", // "404.page-not-found": "page not found", "404.page-not-found": "Seite nicht gefunden", // "admin.curation-tasks.breadcrumbs": "System curation tasks", - "admin.curation-tasks.breadcrumbs": "Datenpflegeroutinen", + "admin.curation-tasks.breadcrumbs": "Wartungsarbeiten", // "admin.curation-tasks.title": "System curation tasks", - "admin.curation-tasks.title": "Datenpflegeroutinen", + "admin.curation-tasks.title": "Wartungsarbeiten", // "admin.curation-tasks.header": "System curation tasks", - "admin.curation-tasks.header": "Datenpflegeroutinen", + "admin.curation-tasks.header": "Wartungsarbeiten", // "admin.registries.bitstream-formats.breadcrumbs": "Format registry", "admin.registries.bitstream-formats.breadcrumbs": "Referenzliste der Dateiformate", @@ -47,10 +47,10 @@ "admin.registries.bitstream-formats.create.breadcrumbs": "Dateiformat", // "admin.registries.bitstream-formats.create.failure.content": "An error occurred while creating the new bitstream format.", - "admin.registries.bitstream-formats.create.failure.content": "Ein Fehler ist beim Anlegen eines neuen Dateiformates aufgetreten.", + "admin.registries.bitstream-formats.create.failure.content": "Beim Anlegen eines neuen Dateiformates ist ein Fehler aufgetreten.", // "admin.registries.bitstream-formats.create.failure.head": "Failure", - "admin.registries.bitstream-formats.create.failure.head": "Fehler", + "admin.registries.bitstream-formats.create.failure.head": "Aktion fehlgeschlagen", // "admin.registries.bitstream-formats.create.head": "Create Bitstream format", "admin.registries.bitstream-formats.create.head": "Neues Dateiformat anlegen", @@ -62,19 +62,19 @@ "admin.registries.bitstream-formats.create.success.content": "Das neue Dateiformat wurde erfolgreich angelegt.", // "admin.registries.bitstream-formats.create.success.head": "Success", - "admin.registries.bitstream-formats.create.success.head": "Erfolg", + "admin.registries.bitstream-formats.create.success.head": "Aktion erfolgreich", // "admin.registries.bitstream-formats.delete.failure.amount": "Failed to remove {{ amount }} format(s)", - "admin.registries.bitstream-formats.delete.failure.amount": "{{ amount }} Format(e) konnte(n) nicht gelöscht werden", + "admin.registries.bitstream-formats.delete.failure.amount": "{{ amount }} Dateiformat(e) konnte(n) nicht gelöscht werden.", // "admin.registries.bitstream-formats.delete.failure.head": "Failure", "admin.registries.bitstream-formats.delete.failure.head": "Fehler", // "admin.registries.bitstream-formats.delete.success.amount": "Successfully removed {{ amount }} format(s)", - "admin.registries.bitstream-formats.delete.success.amount": "{{ amount }} Format(e) erfolgreich gelöscht", + "admin.registries.bitstream-formats.delete.success.amount": "{{ amount }} Dateiformat(e) wurden erfolgreich gelöscht.", // "admin.registries.bitstream-formats.delete.success.head": "Success", - "admin.registries.bitstream-formats.delete.success.head": "Erfolg", + "admin.registries.bitstream-formats.delete.success.head": "Aktion erfolgreich", // "admin.registries.bitstream-formats.description": "This list of bitstream formats provides information about known formats and their support level.", "admin.registries.bitstream-formats.description": "Die Liste der Dateiformate enthält Informationen über bekannte Formate und deren Unterstützungsgrad.", @@ -89,19 +89,19 @@ "admin.registries.bitstream-formats.edit.description.label": "Beschreibung", // "admin.registries.bitstream-formats.edit.extensions.hint": "Extensions are file extensions that are used to automatically identify the format of uploaded files. You can enter several extensions for each format.", - "admin.registries.bitstream-formats.edit.extensions.hint": "Extensionen sind Dateieindungen, welche zur Identifizierung der Formate von hochgeladenen Dateien dienen. Sie können mehrere Endungen pro Format angeben.", + "admin.registries.bitstream-formats.edit.extensions.hint": "Hier können Sie Endungen angeben, anhand derer das Format hochgeladener Dateien automatisch erkannt wird. Sie können mehrere Endungen pro Dateiformat angeben.", // "admin.registries.bitstream-formats.edit.extensions.label": "File extensions", "admin.registries.bitstream-formats.edit.extensions.label": "Dateiendungen", // "admin.registries.bitstream-formats.edit.extensions.placeholder": "Enter a file extension without the dot", - "admin.registries.bitstream-formats.edit.extensions.placeholder": "Geben Sie die Endung des Dateinamens ohne Punkt ein", + "admin.registries.bitstream-formats.edit.extensions.placeholder": "Bitte geben Sie die Dateiendung ohne Punkt ein.", // "admin.registries.bitstream-formats.edit.failure.content": "An error occurred while editing the bitstream format.", - "admin.registries.bitstream-formats.edit.failure.content": "Ein Fehler ist beim Editieren des Dateiformates", + "admin.registries.bitstream-formats.edit.failure.content": "Beim Bearbeiten des Dateiformats ist ein Fehler aufgetreten.", // "admin.registries.bitstream-formats.edit.failure.head": "Failure", - "admin.registries.bitstream-formats.edit.failure.head": "Fehler", + "admin.registries.bitstream-formats.edit.failure.head": "Aktion fehlgeschlagen", // "admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}", "admin.registries.bitstream-formats.edit.head": "Dateiformat: {{ format }}", @@ -110,13 +110,13 @@ "admin.registries.bitstream-formats.edit.internal.hint": "Dateiformate, die als intern gekennzeichnet sind, dienen administrativen Zwecken und bleiben dem:der Endnutzer:in verborgen.", // "admin.registries.bitstream-formats.edit.internal.label": "Internal", - "admin.registries.bitstream-formats.edit.internal.label": "Intern", + "admin.registries.bitstream-formats.edit.internal.label": "intern", // "admin.registries.bitstream-formats.edit.mimetype.hint": "The MIME type associated with this format, does not have to be unique.", - "admin.registries.bitstream-formats.edit.mimetype.hint": "Der MIME Typ dieses Formates. Er muss nicht einzigartig sein.", + "admin.registries.bitstream-formats.edit.mimetype.hint": "MIME-Type dieses Dateiformats. Ein MIME-Type kann auch mehreren Dateiformaten zugeordnet werden.", // "admin.registries.bitstream-formats.edit.mimetype.label": "MIME Type", - "admin.registries.bitstream-formats.edit.mimetype.label": "MIME Typ", + "admin.registries.bitstream-formats.edit.mimetype.label": "MIME-Type", // "admin.registries.bitstream-formats.edit.shortDescription.hint": "A unique name for this format, (e.g. Microsoft Word XP or Microsoft Word 2000)", "admin.registries.bitstream-formats.edit.shortDescription.hint": "Ein eindeutiger Name für dieses Format, (z.B. Microsoft Word XP oder Microsoft Word 2000)", @@ -128,10 +128,10 @@ "admin.registries.bitstream-formats.edit.success.content": "Das Dateiformat wurde erfolgreich bearbeitet.", // "admin.registries.bitstream-formats.edit.success.head": "Success", - "admin.registries.bitstream-formats.edit.success.head": "Erfolg", + "admin.registries.bitstream-formats.edit.success.head": "Aktion erfolgreich", // "admin.registries.bitstream-formats.edit.supportLevel.hint": "The level of support your institution pledges for this format.", - "admin.registries.bitstream-formats.edit.supportLevel.hint": "Der Unterstützungsgrad den Ihre Einrichtung für dieses Format anbietet.", + "admin.registries.bitstream-formats.edit.supportLevel.hint": "Der Unterstützungsgrad, den Ihre Einrichtung für dieses Format anbietet", // "admin.registries.bitstream-formats.edit.supportLevel.label": "Support level", "admin.registries.bitstream-formats.edit.supportLevel.label": "Unterstützungsgrad", @@ -146,13 +146,13 @@ "admin.registries.bitstream-formats.table.delete": "Auswahl löschen", // "admin.registries.bitstream-formats.table.deselect-all": "Deselect all", - "admin.registries.bitstream-formats.table.deselect-all": "Alle abwählen", + "admin.registries.bitstream-formats.table.deselect-all": "Nichts auswählen", // "admin.registries.bitstream-formats.table.internal": "internal", "admin.registries.bitstream-formats.table.internal": "intern", // "admin.registries.bitstream-formats.table.mimetype": "MIME Type", - "admin.registries.bitstream-formats.table.mimetype": "MIME Typ", + "admin.registries.bitstream-formats.table.mimetype": "MIME-Type", // "admin.registries.bitstream-formats.table.name": "Name", "admin.registries.bitstream-formats.table.name": "Name", @@ -199,7 +199,7 @@ "admin.registries.metadata.head": "Metadatenreferenzliste", // "admin.registries.metadata.schemas.no-items": "No metadata schemas to show.", - "admin.registries.metadata.schemas.no-items": "Es gibt keinen Metadatenschemata in der Referenzliste.", + "admin.registries.metadata.schemas.no-items": "Es gibt keine Metadatenschemata in der Referenzliste.", // "admin.registries.metadata.schemas.table.delete": "Delete selected", "admin.registries.metadata.schemas.table.delete": "Auswahl löschen", @@ -261,7 +261,7 @@ "admin.registries.schema.notification.created": "\"{{prefix}}\" wurde erfolgreich angelegt.", // "admin.registries.schema.notification.deleted.failure": "Failed to delete {{amount}} metadata schemas", - "admin.registries.schema.notification.deleted.failure": "{{amount}} Metadatenschema(ta) konnte(n) nicht gelöscht werden", + "admin.registries.schema.notification.deleted.failure": "{{amount}} Metadatenschema(ta) konnte(n) nicht gelöscht werden.", // "admin.registries.schema.notification.deleted.success": "Successfully deleted {{amount}} metadata schemas", "admin.registries.schema.notification.deleted.success": "{{amount}} Metadatenschema(ta) wurde(n) gelöscht.", @@ -368,37 +368,37 @@ "admin.access-control.epeople.form.email": "E-Mail-Adresse", // "admin.access-control.epeople.form.emailHint": "Must be valid e-mail address", - "admin.access-control.epeople.form.emailHint": "Muss eine gültige E-Mail-Adresse sein", + "admin.access-control.epeople.form.emailHint": "Bitte geben Sie eine gültige E-Mail-Adresse an.", // "admin.access-control.epeople.form.canLogIn": "Can log in", "admin.access-control.epeople.form.canLogIn": "Darf sich anmelden", // "admin.access-control.epeople.form.requireCertificate": "Requires certificate", - "admin.access-control.epeople.form.requireCertificate": "Zertifikat benötigt", + "admin.access-control.epeople.form.requireCertificate": "Es wird ein Zertifikat benötigt.", // "admin.access-control.epeople.form.notification.created.success": "Successfully created EPerson \"{{name}}\"", - "admin.access-control.epeople.form.notification.created.success": "Person \"{{name}}\" erfolgreich erstellt", + "admin.access-control.epeople.form.notification.created.success": "Die Person \"{{name}}\" wurde erstellt.", // "admin.access-control.epeople.form.notification.created.failure": "Failed to create EPerson \"{{name}}\"", - "admin.access-control.epeople.form.notification.created.failure": "Person \"{{name}}\" konnte nicht erstellt werden", + "admin.access-control.epeople.form.notification.created.failure": "Die Person \"{{name}}\" konnte nicht erstellt werden.", // "admin.access-control.epeople.form.notification.created.failure.emailInUse": "Failed to create EPerson \"{{name}}\", email \"{{email}}\" already in use.", - "admin.access-control.epeople.form.notification.created.failure.emailInUse": "Person \"{{name}}\" konnte nicht erstellt werden, E-Mail \"{{email}}\" wird bereits verwendet.", + "admin.access-control.epeople.form.notification.created.failure.emailInUse": "Die Person \"{{name}}\" konnte nicht erstellt werden, weil die E-Mail-Adresse \"{{email}}\" bereits verwendet wird.", // "admin.access-control.epeople.form.notification.edited.failure.emailInUse": "Failed to edit EPerson \"{{name}}\", email \"{{email}}\" already in use.", - "admin.access-control.epeople.form.notification.edited.failure.emailInUse": "Person \"{{name}}\" konnte nicht bearbeitet werden, E-Mail \"{{email}}\" wird bereits verwendet.", + "admin.access-control.epeople.form.notification.edited.failure.emailInUse": "Die Person \"{{name}}\" konnte nicht bearbeitet werden, weil die E-Mail-Adresse \"{{email}}\" bereits verwendet wird.", // "admin.access-control.epeople.form.notification.edited.success": "Successfully edited EPerson \"{{name}}\"", - "admin.access-control.epeople.form.notification.edited.success": "Person \"{{name}}\" erfolgreich bearbeitet", + "admin.access-control.epeople.form.notification.edited.success": "Die Person \"{{name}}\" wurde erfolgreich bearbeitet.", // "admin.access-control.epeople.form.notification.edited.failure": "Failed to edit EPerson \"{{name}}\"", - "admin.access-control.epeople.form.notification.edited.failure": "Person \"{{name}}\" konnte nicht bearbeitet werden", + "admin.access-control.epeople.form.notification.edited.failure": "Die Person \"{{name}}\" konnte nicht bearbeitet werden.", // "admin.access-control.epeople.form.notification.deleted.success": "Successfully deleted EPerson \"{{name}}\"", - "admin.access-control.epeople.form.notification.deleted.success": "Person \"{{name}}\" erfolgreich gelöscht", + "admin.access-control.epeople.form.notification.deleted.success": "Die Person \"{{name}}\" wurde gelöscht.", // "admin.access-control.epeople.form.notification.deleted.failure": "Failed to delete EPerson \"{{name}}\"", - "admin.access-control.epeople.form.notification.deleted.failure": "Person \"{{name}}\" konnte nicht gelöscht werden", + "admin.access-control.epeople.form.notification.deleted.failure": "Die Person \"{{name}}\" konnte nicht gelöscht werden.", // "admin.access-control.epeople.form.groupsEPersonIsMemberOf": "Member of these groups:", "admin.access-control.epeople.form.groupsEPersonIsMemberOf": "Mitglied dieser Gruppen:", @@ -410,7 +410,7 @@ "admin.access-control.epeople.form.table.name": "Name", // "admin.access-control.epeople.form.memberOfNoGroups": "This EPerson is not a member of any groups", - "admin.access-control.epeople.form.memberOfNoGroups": "Diese Person ist kein Mitglied von einer Gruppe", + "admin.access-control.epeople.form.memberOfNoGroups": "Diese Person ist kein Mitglied einer Gruppe.", // "admin.access-control.epeople.form.goToGroups": "Add to groups", "admin.access-control.epeople.form.goToGroups": "Zu Gruppen hinzufügen", @@ -573,16 +573,16 @@ "admin.access-control.groups.form.members-list.table.edit.buttons.remove": "Mitglieder mit dem Namen \"{{name}}\" entfernen", // "admin.access-control.groups.form.members-list.notification.success.addMember": "Successfully added member: \"{{name}}\"", - "admin.access-control.groups.form.members-list.notification.success.addMember": "Mitglied: \"{{name}}\" erfolgreich hinzugefügt", + "admin.access-control.groups.form.members-list.notification.success.addMember": "Das Mitglied \"{{name}}\" wurde hinzugefügt.", // "admin.access-control.groups.form.members-list.notification.failure.addMember": "Failed to add member: \"{{name}}\"", - "admin.access-control.groups.form.members-list.notification.failure.addMember": "Mitglied: \"{{name}}\" konnte nicht hinzugefügt werden", + "admin.access-control.groups.form.members-list.notification.failure.addMember": "Das Mitglied \"{{name}}\" konnte nicht hinzugefügt werden.", // "admin.access-control.groups.form.members-list.notification.success.deleteMember": "Successfully deleted member: \"{{name}}\"", - "admin.access-control.groups.form.members-list.notification.success.deleteMember": "Mitglied: \"{{name}}\" erfolgreich gelöscht", + "admin.access-control.groups.form.members-list.notification.success.deleteMember": "Das Mitglied \"{{name}}\" wurde gelöscht.", // "admin.access-control.groups.form.members-list.notification.failure.deleteMember": "Failed to delete member: \"{{name}}\"", - "admin.access-control.groups.form.members-list.notification.failure.deleteMember": "Mitglied: \"{{name}}\" konnte nicht gelöscht werden", + "admin.access-control.groups.form.members-list.notification.failure.deleteMember": "Das Mitglied \"{{name}}\" konnte nicht gelöscht werden.", // "admin.access-control.groups.form.members-list.table.edit.buttons.add": "Add member with name \"{{name}}\"", "admin.access-control.groups.form.members-list.table.edit.buttons.add": "Mitglied mit dem Namen \"{{name}}\" hinzufügen", @@ -654,7 +654,7 @@ "admin.access-control.groups.form.subgroups-list.no-items": "Keine Gruppen gefunden, die dies in ihrem Namen oder als UUID haben", // "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "No subgroups in group yet.", - "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "Noch keine Untergruppen in der Gruppe.", + "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "Die Gruppe hat noch keine Untergruppen.", // "admin.access-control.groups.form.return": "Return to groups", "admin.access-control.groups.form.return": "Zurück zu den Gruppen", @@ -662,7 +662,7 @@ // "admin.search.breadcrumbs": "Administrative Search", - "admin.search.breadcrumbs": "Administrative Suche", + "admin.search.breadcrumbs": "Admin-Suche", // "admin.search.collection.edit": "Edit", "admin.search.collection.edit": "Bearbeiten", @@ -677,10 +677,10 @@ "admin.search.item.edit": "Bearbeiten", // "admin.search.item.make-private": "Make Private", - "admin.search.item.make-private": "Privat stellen", + "admin.search.item.make-private": "Verbergen", // "admin.search.item.make-public": "Make Public", - "admin.search.item.make-public": "Öffentlich stellen", + "admin.search.item.make-public": "Öffentlich anzeigen", // "admin.search.item.move": "Move", "admin.search.item.move": "Verschieben", @@ -692,22 +692,22 @@ "admin.search.item.withdraw": "Zurückziehen", // "admin.search.title": "Administrative Search", - "admin.search.title": "Administrative Suche", + "admin.search.title": "Admin-Suche", // "administrativeView.search.results.head": "Administrative Search", - "administrativeView.search.results.head": "Administrative Suche", + "administrativeView.search.results.head": "Admin-Suche", // "admin.workflow.breadcrumbs": "Administer Workflow", - "admin.workflow.breadcrumbs": "Geschäftsgänge verwalten", + "admin.workflow.breadcrumbs": "Workflows verwalten", // "admin.workflow.title": "Administer Workflow", - "admin.workflow.title": "Geschäftsgänghe verwalten", + "admin.workflow.title": "Workflows verwalten", // "admin.workflow.item.workflow": "Workflow", - "admin.workflow.item.workflow": "Geschäftsgänge", + "admin.workflow.item.workflow": "Workflows", // "admin.workflow.item.delete": "Delete", "admin.workflow.item.delete": "Löschen", @@ -727,13 +727,13 @@ "admin.metadata-import.page.header": "Metadaten importieren", // "admin.metadata-import.page.help": "You can drop or browse CSV files that contain batch metadata operations on files here", - "admin.metadata-import.page.help": "Zum Importieren von Metadaten im Batch-Verfahren, wählen Sie eine CSV-Datei zum Hochladen aus, oder ziehen Sie diese in das Browser-Fenster", + "admin.metadata-import.page.help": "Um Metadaten im Batch-Verfahren zu importieren, wählen Sie bitte eine CSV-Datei zum Hochladen aus oder ziehen Sie diese ins Browser-Fenster.", // "admin.metadata-import.page.dropMsg": "Drop a metadata CSV to import", - "admin.metadata-import.page.dropMsg": "Ziehen Sie eine CSV-Datei mit Metadaten zum Importieren in das Browser-Fenster", + "admin.metadata-import.page.dropMsg": "Ziehen Sie eine CSV-Datei mit Metadaten zum Importieren in das Browser-Fenster.", // "admin.metadata-import.page.dropMsgReplace": "Drop to replace the metadata CSV to import", - "admin.metadata-import.page.dropMsgReplace": "Legen Sie ab, um die CSV-Datei für den Import zu ersetzen.", + "admin.metadata-import.page.dropMsgReplace": "Legen Sie eine neue CSV-Datei hier ab, um die Importdatei zu ersetzen.", // "admin.metadata-import.page.button.return": "Return", "admin.metadata-import.page.button.return": "Zurück", @@ -742,7 +742,7 @@ "admin.metadata-import.page.button.proceed": "Fortfahren", // "admin.metadata-import.page.error.addFile": "Select file first!", - "admin.metadata-import.page.error.addFile": "Zuerst Datei auswählen!", + "admin.metadata-import.page.error.addFile": "Bitte wählen Sie zuerst eine Datei aus.", @@ -751,7 +751,7 @@ "auth.errors.invalid-user": "Passwort oder E-Mail-Adresse ungültig.", // "auth.messages.expired": "Your session has expired. Please log in again.", - "auth.messages.expired": "Ihre Sitzung ist abgelaufen, bitte melden Sie sich erneut an.", + "auth.messages.expired": "Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an.", @@ -759,7 +759,7 @@ "bitstream.edit.bitstream": "Bitstream: ", // "bitstream.edit.form.description.hint": "Optionally, provide a brief description of the file, for example \"Main article\" or \"Experiment data readings\".", - "bitstream.edit.form.description.hint": "Optional können Sie eine kurze Beschreibung der Datei angeben, zum Beispiel \"Main article\" oder \"Experiment data readings\".", + "bitstream.edit.form.description.hint": "Hier können Sie eine kurze Beschreibung der Datei angeben, zum Beispiel \"Artikel\" oder \"Tabellenhanhang\".", // "bitstream.edit.form.description.label": "Description", "bitstream.edit.form.description.label": "Beschreibung", @@ -769,7 +769,7 @@ // "bitstream.edit.form.embargo.label": "Embargo until specific date", - "bitstream.edit.form.embargo.label": "Embargo bis zu einem bestimmten Datum", + "bitstream.edit.form.embargo.label": "Sperrfrist", // "bitstream.edit.form.fileName.hint": "Change the filename for the bitstream. Note that this will change the display bitstream URL, but old links will still resolve as long as the sequence ID does not change.", "bitstream.edit.form.fileName.hint": "Ändern Sie den Dateinamen für die Datei. Beachten Sie, dass sich dadurch die angezeigte Datei-URL ändert, aber alte Links weiterhin funktionieren, solange sich die Sequenz-ID nicht ändert.", @@ -793,7 +793,7 @@ "bitstream.edit.form.selectedFormat.label": "Ausgewähltes Format", // "bitstream.edit.form.selectedFormat.unknown": "Format not in list", - "bitstream.edit.form.selectedFormat.unknown": "Format nicht in der Liste", + "bitstream.edit.form.selectedFormat.unknown": "Anderes Format", // "bitstream.edit.notifications.error.format.title": "An error occurred saving the bitstream's format", "bitstream.edit.notifications.error.format.title": "Beim Speichern des Dateiformats ist ein Fehler aufgetreten", @@ -846,10 +846,10 @@ "browse.metadata.dateissued.breadcrumbs": "Auflistung nach Datum", // "browse.metadata.subject.breadcrumbs": "Browse by Subject", - "browse.metadata.subject.breadcrumbs": "Auflistung nach Schlagwort", + "browse.metadata.subject.breadcrumbs": "Schlagwörter", // "browse.metadata.title.breadcrumbs": "Browse by Title", - "browse.metadata.title.breadcrumbs": "Auflistung nach Titel", + "browse.metadata.title.breadcrumbs": "Titel", // "browse.startsWith.choose_start": "(Choose start)", "browse.startsWith.choose_start": "(Startpunkt wählen)", @@ -1023,7 +1023,7 @@ "collection.edit.logo.label": "Sammlungslogo", // "collection.edit.logo.notifications.add.error": "Uploading Collection logo failed. Please verify the content before retrying.", - "collection.edit.logo.notifications.add.error": "Hochladen des Sammlungslogos fehlgeschlagen. Bitte überprüfen Sie den Inhalt, bevor Sie es nochmal versuchen.", + "collection.edit.logo.notifications.add.error": "Hochladen des Sammlungslogos fehlgeschlagen. Bitte überprüfen Sie den Inhalt, bevor Sie es erneut versuchen.", // "collection.edit.logo.notifications.add.success": "Upload Collection logo successful.", "collection.edit.logo.notifications.add.success": "Sammlungslogo erfolgreich hochgeladen.", @@ -1038,7 +1038,7 @@ "collection.edit.logo.notifications.delete.error.title": "Fehler beim Löschen des Logos", // "collection.edit.logo.upload": "Drop a Collection Logo to upload", - "collection.edit.logo.upload": "Ziehen Sie ein Logo herüber, um es hochzuladen", + "collection.edit.logo.upload": "Ziehen Sie ein Logo herüber, um es hochzuladen.", @@ -1090,10 +1090,10 @@ "collection.edit.tabs.source.form.metadataConfigId": "Metadatenformat", // "collection.edit.tabs.source.form.oaiSetId": "OAI specific set id", - "collection.edit.tabs.source.form.oaiSetId": "OAI spezifische Set-ID", + "collection.edit.tabs.source.form.oaiSetId": "OAI-spezifische Set-ID", // "collection.edit.tabs.source.form.oaiSource": "OAI Provider", - "collection.edit.tabs.source.form.oaiSource": "OAI Anbieter", + "collection.edit.tabs.source.form.oaiSource": "OAI-Anbieter", // "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_BITSTREAMS": "Harvest metadata and bitstreams (requires ORE support)", "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_BITSTREAMS": "Bezieht Metadaten und Dateien (ORE-Schnittstelle erforderlich)", @@ -1108,7 +1108,7 @@ "collection.edit.tabs.source.head": "Herkunft des Inhalts", // "collection.edit.tabs.source.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - "collection.edit.tabs.source.notifications.discarded.content": "Die Änderungen wurden verworfen. Um die Änderungen wieder einzusetzen klicken Sie auf den 'Rückgängig' Knopf", + "collection.edit.tabs.source.notifications.discarded.content": "Die Änderungen wurden verworfen. Bitte klicken Sie auf \"Rückgängig\", um sie wieder einzusetzen.", // "collection.edit.tabs.source.notifications.discarded.title": "Changed discarded", "collection.edit.tabs.source.notifications.discarded.title": "Änderungen verworfen", @@ -1120,7 +1120,7 @@ "collection.edit.tabs.source.notifications.invalid.title": "Metadaten ungültig", // "collection.edit.tabs.source.notifications.saved.content": "Your changes to this collection's content source were saved.", - "collection.edit.tabs.source.notifications.saved.content": "Ihre Änderunge bezüglich der Quelle für den Inhalt der Sammlung wurden gespeichert.", + "collection.edit.tabs.source.notifications.saved.content": "Die Quelle für den Inhalt der Sammlung wurde geändert.", // "collection.edit.tabs.source.notifications.saved.title": "Content Source saved", "collection.edit.tabs.source.notifications.saved.title": "Bezugsquelle für den Inhalt gespeichert", @@ -1287,7 +1287,7 @@ "community.edit.logo.label": "Bereichslogo", // "community.edit.logo.notifications.add.error": "Uploading Community logo failed. Please verify the content before retrying.", - "community.edit.logo.notifications.add.error": "Hochladen des Bereichslogos fehlgeschlagen. Bitte überprüfen Sie den Inhalt bevor Sie es noch einmal versuchen.", + "community.edit.logo.notifications.add.error": "Hochladen des Bereichslogos fehlgeschlagen. Bitte überprüfen Sie den Inhalt bevor Sie es erneut versuchen.", // "community.edit.logo.notifications.add.success": "Upload Community logo successful.", "community.edit.logo.notifications.add.success": "Hochladen des Bereichslogos erfolgreich.", @@ -1469,10 +1469,10 @@ // "cookies.consent.accept-all": "Accept all", - "cookies.consent.accept-all": "Alle annehmen", + "cookies.consent.accept-all": "Alle Cookies akzeptieren", // "cookies.consent.accept-selected": "Accept selected", - "cookies.consent.accept-selected": "Ausgewählte annehmen", + "cookies.consent.accept-selected": "Nur ausgewählte Cookies akzeptieren", // "cookies.consent.app.opt-out.description": "This app is loaded by default (but you can opt out)", "cookies.consent.app.opt-out.description": "Diese App wird standardmäßig geladen (Sie können dies jedoch deaktivieren)", @@ -1868,16 +1868,16 @@ "form.group-collapse-help": "Zum Zusammenfalten bitte hier klicken", // "form.group-expand": "Expand", - "form.group-expand": "Auffalten", + "form.group-expand": "Ausklappen", // "form.group-expand-help": "Click here to expand and add more elements", - "form.group-expand-help": "Zum Ausklappen und Hinzufügen von weiteren Elementen klicken Sie hier", + "form.group-expand-help": "Zum Ausklappen und Hinzufügen weiterer Elemente klicken Sie bitte hier.", // "form.last-name": "Last name", "form.last-name": "Nachname", // "form.loading": "Loading...", - "form.loading": "Am Laden ...", + "form.loading": "Lädt...", // "form.lookup": "Lookup", "form.lookup": "Nachschlagen", @@ -1986,7 +1986,7 @@ // "item.badge.private": "Private", - "item.badge.private": "Privat", + "item.badge.private": "Verborgen", // "item.badge.withdrawn": "Withdrawn", "item.badge.withdrawn": "Zurückgezogen", @@ -2080,7 +2080,7 @@ "item.edit.bitstreams.headers.name": "Name", // "item.edit.bitstreams.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - "item.edit.bitstreams.notifications.discarded.content": "Ihre Änderungen wurden verworfen. Um Ihre Änderungen wiederherzustellen, klicken Sie auf die Schaltfläche 'Rückgängig'", + "item.edit.bitstreams.notifications.discarded.content": "Ihre Änderungen wurden verworfen. Um sie wiederherzustellen, klicken Sie bitte auf \"Rückgängig\".", // "item.edit.bitstreams.notifications.discarded.title": "Changes discarded", "item.edit.bitstreams.notifications.discarded.title": "Änderungen verworfen", @@ -2241,7 +2241,7 @@ "item.edit.metadata.metadatafield.invalid": "Bitte wählen Sie ein gültiges Metadatenfeld", // "item.edit.metadata.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - "item.edit.metadata.notifications.discarded.content": "Ihre Änderungen wurden verworfen. Um diese wieder anzuwenden, klicken Sie auf den 'Rückgängig machen' Knopf", + "item.edit.metadata.notifications.discarded.content": "Ihre Änderungen wurden verworfen. Um sie wiederherzustellen, klicken Sie bitte auf \"Rückgängig\".", // "item.edit.metadata.notifications.discarded.title": "Changed discarded", "item.edit.metadata.notifications.discarded.title": "Änderungen verworfen", @@ -2325,7 +2325,7 @@ "item.edit.private.cancel": "Abbrechen", // "item.edit.private.confirm": "Make it Private", - "item.edit.private.confirm": "Privat machen", + "item.edit.private.confirm": "Verbergen", // "item.edit.private.description": "Are you sure this item should be made private in the archive?", "item.edit.private.description": "Wollen Sie dieses Item als privat markieren.", @@ -2365,7 +2365,7 @@ "item.edit.reinstate.cancel": "Abbrechen", // "item.edit.reinstate.confirm": "Reinstate", - "item.edit.reinstate.confirm": "Reinstantiieren", + "item.edit.reinstate.confirm": "Wiederherstellen", // "item.edit.reinstate.description": "Are you sure this item should be reinstated to the archive?", "item.edit.reinstate.description": "Sind Sie sicher, dass das Item reinstantiiert werden soll?", @@ -2397,7 +2397,7 @@ "item.edit.relationships.no-relationships": "Keine Beziehungen", // "item.edit.relationships.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", - "item.edit.relationships.notifications.discarded.content": "Ihre Änderungen wurden verworfen. Um sie dennoch anzuwenden klicken Sie auf den 'Rückgängig machen' Knopf", + "item.edit.relationships.notifications.discarded.content": "Ihre Änderungen wurden verworfen. Um sie wiederherzustellen, klicken Sie bitte auf \"Rückgängig\".", // "item.edit.relationships.notifications.discarded.title": "Changes discarded", "item.edit.relationships.notifications.discarded.title": "Änderungen verworfen", @@ -2477,7 +2477,7 @@ "item.edit.tabs.status.buttons.move.label": "Item in eine andere Sammlung verschieben", // "item.edit.tabs.status.buttons.private.button": "Make it private...", - "item.edit.tabs.status.buttons.private.button": "Privat machen...", + "item.edit.tabs.status.buttons.private.button": "Verbergen", // "item.edit.tabs.status.buttons.private.label": "Make item private", "item.edit.tabs.status.buttons.private.label": "Item privat machen", @@ -2489,7 +2489,7 @@ "item.edit.tabs.status.buttons.public.label": "Item öffentlich machen", // "item.edit.tabs.status.buttons.reinstate.button": "Reinstate...", - "item.edit.tabs.status.buttons.reinstate.button": "Reinstantiieren...", + "item.edit.tabs.status.buttons.reinstate.button": "Wiederherstellen...", // "item.edit.tabs.status.buttons.reinstate.label": "Reinstate item into the repository", "item.edit.tabs.status.buttons.reinstate.label": "Item wieder ins Repositorium einsetzen", @@ -2780,7 +2780,7 @@ "journal.page.titleprefix": "Zeitschrift: ", // "journal.search.results.head": "Journal Search Results", - "journal.search.results.head": "Zeitschrift Suchergebenisse", + "journal.search.results.head": "Suchergebnisse für Zeitschriften", // "journal.search.title": "DSpace Angular :: Journal Search", "journal.search.title": "DSpace Angular :: Zeitschriftensuche", @@ -2788,7 +2788,7 @@ // "journalissue.listelement.badge": "Journal Issue", - "journalissue.listelement.badge": "Zeitschriftenausgabe", + "journalissue.listelement.badge": "Zeitschriftenheft", // "journalissue.page.description": "Description", "journalissue.page.description": "Beschreibeung", @@ -2812,7 +2812,7 @@ "journalissue.page.number": "Zählung", // "journalissue.page.titleprefix": "Journal Issue: ", - "journalissue.page.titleprefix": "Zeitschriftenausgabe: ", + "journalissue.page.titleprefix": "Zeitschriftenheft:", @@ -2925,7 +2925,7 @@ // "logout.form.header": "Log out from DSpace", - "logout.form.header": "Aus dem Repositorium abmelden", + "logout.form.header": "Abmelden", // "logout.form.submit": "Log out", "logout.form.submit": "Abmelden", @@ -2969,7 +2969,7 @@ "menu.section.browse_community_by_author": "Nach Autor:in", // "menu.section.browse_community_by_issue_date": "By Issue Date", - "menu.section.browse_community_by_issue_date": "Nach Erscheinungsdateum", + "menu.section.browse_community_by_issue_date": "Nach Erscheinungsdatum", // "menu.section.browse_community_by_title": "By Title", "menu.section.browse_community_by_title": "Nach Titel", @@ -3200,7 +3200,7 @@ "mydspace.messages.no-content": "Kein Inhalt.", // "mydspace.messages.no-messages": "No messages yet.", - "mydspace.messages.no-messages": "Noch keine Nachrichten.", + "mydspace.messages.no-messages": "Es sind noch keine Nachrichten vorhanden.", // "mydspace.messages.send-btn": "Send", "mydspace.messages.send-btn": "Senden", @@ -3359,7 +3359,7 @@ // "pagination.results-per-page": "Results Per Page", - "pagination.results-per-page": "Anzeige pro Seite", + "pagination.results-per-page": "Treffer pro Seite", // "pagination.showing.detail": "{{ range }} of {{ total }}", "pagination.showing.detail": "{{ range }} von {{ total }}", @@ -3587,10 +3587,10 @@ "profile.metadata.form.label.lastname": "Nachname", // "profile.metadata.form.label.phone": "Contact Telephone", - "profile.metadata.form.label.phone": "Kontakt Telefon", + "profile.metadata.form.label.phone": "Telefonnummer", // "profile.metadata.form.notifications.success.content": "Your changes to the profile were saved.", - "profile.metadata.form.notifications.success.content": "Ihre Änderungen am Profil wurden gespeichert.", + "profile.metadata.form.notifications.success.content": "Ihre Profiländerungen wurden gespeichert.", // "profile.metadata.form.notifications.success.title": "Profile saved", "profile.metadata.form.notifications.success.title": "Profil gespeichert", @@ -3617,10 +3617,10 @@ "profile.security.form.label.passwordrepeat": "Zum Bestätigen erneut eingeben", // "profile.security.form.notifications.success.content": "Your changes to the password were saved.", - "profile.security.form.notifications.success.content": "Ihre Änderungen am Passwort wurden gespeichert.", + "profile.security.form.notifications.success.content": "Ihr geändertes Passwort wurde gespeichert.", // "profile.security.form.notifications.success.title": "Password saved", - "profile.security.form.notifications.success.title": "Password gespeichert", + "profile.security.form.notifications.success.title": "Passwort gespeichert", // "profile.security.form.notifications.error.title": "Error changing passwords", "profile.security.form.notifications.error.title": "Fehler beim Ändern von Passwörtern", @@ -3727,7 +3727,7 @@ "register-page.create-profile.identification.last-name.error": "Bitte geben Sie einen Nachnamen ein", // "register-page.create-profile.identification.contact": "Contact Telephone", - "register-page.create-profile.identification.contact": "Kontakt Telefon", + "register-page.create-profile.identification.contact": "Telefonnummer", // "register-page.create-profile.identification.language": "Language", "register-page.create-profile.identification.language": "Sprache", @@ -3760,7 +3760,7 @@ "register-page.create-profile.submit.error.content": "Bei der Registrierung eines neuen Accounts ist ein Fehler aufgetreten.", // "register-page.create-profile.submit.error.head": "Registration failed", - "register-page.create-profile.submit.error.head": "Registrierung fehlgeschlagen.", + "register-page.create-profile.submit.error.head": "Registrierung fehlgeschlagen", // "register-page.create-profile.submit.success.content": "The registration was successful. You have been logged in as the created user.", "register-page.create-profile.submit.success.content": "Die Registrierung war erfolgreich. Sie wurden als der:die angelegte Benutzer:in angemeldet.", @@ -3817,16 +3817,16 @@ "relationships.isAuthorOf": "Autor:innen", // "relationships.isAuthorOf.Person": "Authors (persons)", - "relationships.isAuthorOf.Person": "AutorInnen (Personen)", + "relationships.isAuthorOf.Person": "Autor*innen (Personen)", // "relationships.isAuthorOf.OrgUnit": "Authors (organizational units)", "relationships.isAuthorOf.OrgUnit": "Autor:innen (Organisationseinheiten)", // "relationships.isIssueOf": "Journal Issues", - "relationships.isIssueOf": "Zeitschriftenausgaben", + "relationships.isIssueOf": "Zeitschriftenhefte", // "relationships.isJournalIssueOf": "Journal Issue", - "relationships.isJournalIssueOf": "Zeitschriftenausgabe", + "relationships.isJournalIssueOf": "Zeitschriftenheft", // "relationships.isJournalOf": "Journals", "relationships.isJournalOf": "Zeitschriften", @@ -3894,7 +3894,7 @@ "resource-policies.create.page.title": "Eine neue Ressourcen-Richtlinie erstellen", // "resource-policies.delete.btn": "Delete selected", - "resource-policies.delete.btn": "Ausgewählte löschen", + "resource-policies.delete.btn": "Markierte löschen", // "resource-policies.delete.btn.title": "Delete selected resource policies", "resource-policies.delete.btn.title": "Ausgewählte Ressourcen-Richtlinien löschen", @@ -4040,13 +4040,13 @@ "search.filters.applied.f.dateSubmitted": "Datum der Einreichung", // "search.filters.applied.f.discoverable": "Private", - "search.filters.applied.f.discoverable": "Privat", + "search.filters.applied.f.discoverable": "Verborgen", // "search.filters.applied.f.entityType": "Item Type", "search.filters.applied.f.entityType": "Item-Typ", // "search.filters.applied.f.has_content_in_original_bundle": "Has files", - "search.filters.applied.f.has_content_in_original_bundle": "Hat Dateien", + "search.filters.applied.f.has_content_in_original_bundle": "Dateien dazu vorhanden?", // "search.filters.applied.f.itemtype": "Type", "search.filters.applied.f.itemtype": "Typ", @@ -4126,7 +4126,7 @@ "search.filters.filter.dateSubmitted.placeholder": "Datum der Einreichung", // "search.filters.filter.discoverable.head": "Private", - "search.filters.filter.discoverable.head": "Privat", + "search.filters.filter.discoverable.head": "Verborgen", // "search.filters.filter.withdrawn.head": "Withdrawn", "search.filters.filter.withdrawn.head": "Zurückgezogen", @@ -4215,7 +4215,7 @@ // "search.filters.entityType.JournalIssue": "Journal Issue", - "search.filters.entityType.JournalIssue": "Zeitschriftenausgabe", + "search.filters.entityType.JournalIssue": "Zeitschriftenheft", // "search.filters.entityType.JournalVolume": "Journal Volume", "search.filters.entityType.JournalVolume": "Zeitschriftenband", @@ -4302,10 +4302,10 @@ "search.view-switch.show-detail": "Detailanzeige", // "search.view-switch.show-grid": "Show as grid", - "search.view-switch.show-grid": "Anzeige als Raster", + "search.view-switch.show-grid": "Als Raster anzeigen", // "search.view-switch.show-list": "Show as list", - "search.view-switch.show-list": "Anzeige als Liste", + "search.view-switch.show-list": "Als Liste anzeigen", @@ -4465,7 +4465,7 @@ "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal": "Zeitschrift importieren", // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Issue": "Import remote journal issue", - "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Issue": "Zeitschriftenausgabe importieren", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Issue": "Zeitschriftenheft importieren", // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "Import remote journal volume", "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "Zeitschriftenband importieren", @@ -4489,7 +4489,7 @@ "submission.sections.describe.relationship-lookup.external-source.import-modal.cancel": "Abbrechen", // "submission.sections.describe.relationship-lookup.external-source.import-modal.collection": "Select a collection to import new entries to", - "submission.sections.describe.relationship-lookup.external-source.import-modal.collection": "Wählen Sie eine Sammlung, um neue Einträge dorthin zu importieren", + "submission.sections.describe.relationship-lookup.external-source.import-modal.collection": "Wählen Sie eine Sammlung, um neue Einträge dorthin zu importieren.", // "submission.sections.describe.relationship-lookup.external-source.import-modal.entities": "Entities", "submission.sections.describe.relationship-lookup.external-source.import-modal.entities": "Entitäten", @@ -4519,7 +4519,7 @@ "submission.sections.describe.relationship-lookup.external-source.import-modal.import": "Import", // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.title": "Import Remote Journal", - "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.title": "Zeitschrift von externer Quelle importieren", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.title": "Zeitschrift aus externer Quelle importieren", // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.local-entity": "Successfully added local journal to the selection", "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.local-entity": "Lokale Zeitschrift wurde erfolgreich zur Auswahl hinzugefügt", @@ -4549,7 +4549,7 @@ "submission.sections.describe.relationship-lookup.external-source.import-modal.select": "Wählen Sie einen lokalen Treffer aus:", // "submission.sections.describe.relationship-lookup.search-tab.deselect-all": "Deselect all", - "submission.sections.describe.relationship-lookup.search-tab.deselect-all": "Alle abwählen", + "submission.sections.describe.relationship-lookup.search-tab.deselect-all": "Nichts auswählen", // "submission.sections.describe.relationship-lookup.search-tab.deselect-page": "Deselect page", "submission.sections.describe.relationship-lookup.search-tab.deselect-page": "Seite abwählen", @@ -4642,9 +4642,9 @@ "submission.sections.describe.relationship-lookup.selection-tab.tab-title": "Aktuelle Auswahl ({{ count }})", // "submission.sections.describe.relationship-lookup.title.isJournalIssueOfPublication": "Journal Issues", - "submission.sections.describe.relationship-lookup.title.isJournalIssueOfPublication": "Zeitschriftenausgaben", + "submission.sections.describe.relationship-lookup.title.isJournalIssueOfPublication": "Zeitschriftenhefte", // "submission.sections.describe.relationship-lookup.title.JournalIssue": "Journal Issues", - "submission.sections.describe.relationship-lookup.title.JournalIssue": "Zeitschriftenausgaben", + "submission.sections.describe.relationship-lookup.title.JournalIssue": "Zeitschriftenhefte", // "submission.sections.describe.relationship-lookup.title.isJournalVolumeOfPublication": "Journal Volumes", "submission.sections.describe.relationship-lookup.title.isJournalVolumeOfPublication": "Zeitschriftenbände", @@ -4765,7 +4765,7 @@ "submission.sections.describe.relationship-lookup.selection-tab.title.arxiv": "Suchergebnisse", // "submission.sections.describe.relationship-lookup.name-variant.notification.content": "Would you like to save \"{{ value }}\" as a name variant for this person so you and others can reuse it for future submissions? If you don\'t you can still use it for this submission.", - "submission.sections.describe.relationship-lookup.name-variant.notification.content": "Möchten Sie \"{{ value }}\" als Namesvariante für diese Person speichern? So können Sie und andere diese bei zukünftigen Veröffentlichungen verwenden. Wenn Sie das nicht tun, können Sie die Variante immer noch für diese Veröffentlichung verwenden.", + "submission.sections.describe.relationship-lookup.name-variant.notification.content": "Möchten Sie die Namensvariante \"{{ value }}\" speichern, damit sie bei zukünftigen Veröffentlichungen erneut verwendet werden kann? Sie können die Variante bei dieser Veröffentlichung auch verwenden, ohne sie zu speichern.", // "submission.sections.describe.relationship-lookup.name-variant.notification.confirm": "Save a new name variant", "submission.sections.describe.relationship-lookup.name-variant.notification.confirm": "Als Namensvariante speichern", @@ -4813,7 +4813,7 @@ "submission.sections.general.discard_success_notice": "Einreichung erfolgreich verworfen.", // "submission.sections.general.metadata-extracted": "New metadata have been extracted and added to the {{sectionId}} section.", - "submission.sections.general.metadata-extracted": "Neue Metainformation wurden extrahier unt dem Bereich {{sectionId}} zugeordnet.", + "submission.sections.general.metadata-extracted": "Neue Metadaten wurden extrahiert und dem Bereich {{sectionId}} zugeordnet.", // "submission.sections.general.metadata-extracted-new-section": "New {{sectionId}} section has been added to submission.", "submission.sections.general.metadata-extracted-new-section": "Neuer Bereich {{sectionId}} wurde zur Einreichung hinzugefügt.", @@ -4854,7 +4854,7 @@ "submission.sections.submit.progressbar.describe.steptwo": "Beschreiben", // "submission.sections.submit.progressbar.detect-duplicate": "Potential duplicates", - "submission.sections.submit.progressbar.detect-duplicate": "Mögliche Dubletten", + "submission.sections.submit.progressbar.detect-duplicate": "Doppelter Eintrag?", // "submission.sections.submit.progressbar.license": "Deposit license", "submission.sections.submit.progressbar.license": "Einreichlizenz", @@ -4898,7 +4898,7 @@ "submission.sections.upload.form.group-label": "Gruppe", // "submission.sections.upload.form.group-required": "Group is required.", - "submission.sections.upload.form.group-required": "Gruppe ist erforderlich", + "submission.sections.upload.form.group-required": "Bitte geben Sie eine Gruppe an.", // "submission.sections.upload.form.until-label": "Grant access until", "submission.sections.upload.form.until-label": "Zugriff gewährt bis", @@ -4994,7 +4994,7 @@ "submission.workflow.tasks.claimed.return": "Zurück in den gemeinsamen Aufgabenbereich", // "submission.workflow.tasks.claimed.return_help": "Return the task to the pool so that another user may perform the task.", - "submission.workflow.tasks.claimed.return_help": "Aufgabe in den gemeinsamen Aufgabenbereich überführen, so dass ein anderer Bearbeiter die Aufgabe übernehmen kann.", + "submission.workflow.tasks.claimed.return_help": "Aufgabe in den Aufgabenpool zurückgeben, so dass jemand Anderes die Aufgabe übernehmen kann", @@ -5016,7 +5016,7 @@ "submission.workflow.tasks.pool.claim": "Übernehmen", // "submission.workflow.tasks.pool.claim_help": "Assign this task to yourself.", - "submission.workflow.tasks.pool.claim_help": "Aufgabe übernehmen.", + "submission.workflow.tasks.pool.claim_help": "Aufgabe übernehmen", // "submission.workflow.tasks.pool.hide-detail": "Hide detail", "submission.workflow.tasks.pool.hide-detail": "Details verbergen", @@ -5058,13 +5058,13 @@ "uploader.browse": "stöbern", // "uploader.drag-message": "Drag & Drop your files here", - "uploader.drag-message": "Ziehen Sie Ihre Dateien hierhin", + "uploader.drag-message": "Bitte ziehen Sie Ihre Dateien hierhin.", // "uploader.or": ", or ", "uploader.or": ", oder", // "uploader.processing": "Processing", - "uploader.processing": "Bearbeitung läuft", + "uploader.processing": "In Arbeit...", // "uploader.queue-length": "Queue length", "uploader.queue-length": "Länge der Warteschlange", From 304b6226abf64b47d698f3db711d5812fa4d395a Mon Sep 17 00:00:00 2001 From: louiserumpf <101128103+louiserumpf@users.noreply.github.com> Date: Tue, 22 Mar 2022 11:23:39 +0100 Subject: [PATCH 0096/2129] typo --- src/assets/i18n/de.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index bf7df7619a9..1d7640ccf27 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -3817,7 +3817,7 @@ "relationships.isAuthorOf": "Autor:innen", // "relationships.isAuthorOf.Person": "Authors (persons)", - "relationships.isAuthorOf.Person": "Autor*innen (Personen)", + "relationships.isAuthorOf.Person": "Autor:innen (Personen)", // "relationships.isAuthorOf.OrgUnit": "Authors (organizational units)", "relationships.isAuthorOf.OrgUnit": "Autor:innen (Organisationseinheiten)", From 9600bacf46b1c92110e33e2382e01cfd0edf6368 Mon Sep 17 00:00:00 2001 From: raihantopu Date: Tue, 22 Mar 2022 16:29:42 +0600 Subject: [PATCH 0097/2129] adding bn.json5 for 'Bengali Language Transalation' and language code, label, active (all commented) to environment.test.ts file --- src/assets/i18n/bn.json5 | 6129 ++++++++++++++++++++++++++ src/environments/environment.test.ts | 8 +- 2 files changed, 6136 insertions(+), 1 deletion(-) create mode 100644 src/assets/i18n/bn.json5 diff --git a/src/assets/i18n/bn.json5 b/src/assets/i18n/bn.json5 new file mode 100644 index 00000000000..1bc26d2da40 --- /dev/null +++ b/src/assets/i18n/bn.json5 @@ -0,0 +1,6129 @@ +{ + + // "401.help": "You're not authorized to access this page. You can use the button below to get back to the home page.", + "401.help": "আপনি এই পৃষ্ঠাটি অ্যাক্সেস করার জন্য অনুমোদিত নন। আপনি হোম পেজে ফিরে যেতে নীচের বোতামটি ব্যবহার করতে পারেন।", + + // "401.link.home-page": "Take me to the home page", + "401.link.home-page": "আমাকে হোম পেজে নিয়ে যাও", + + // "401.unauthorized": "unauthorized", + "401.unauthorized": "অননুমোদিত", + + + + // "403.help": "You don't have permission to access this page. You can use the button below to get back to the home page.", + "403.help": "আপনার এই পৃষ্ঠাটি অ্যাক্সেস করার অনুমতি নেই। আপনি হোম পেজে ফিরে যেতে নীচের বোতামটি ব্যবহার করতে পারেন।", + + // "403.link.home-page": "Take me to the home page", + "403.link.home-page": "আমাকে হোম পেজে নিয়ে যাও", + + // "403.forbidden": "forbidden", + "403.forbidden": "নিষিদ্ধ", + + // "500.page-internal-server-error": "Service Unavailable", + "500.page-internal-server-error": "সেবা প্রদান করা যাচ্ছে না", + + // "500.help": "The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.", + "500.help": "সার্ভারটি অস্থায়ীভাবে রক্ষণাবেক্ষণ ডাউনটাইম বা ক্ষমতা সমস্যার কারণে আপনার অনুরোধ পরিসেবা করতে অক্ষম। পরে আবার চেষ্টা করুন.", + + // "500.link.home-page": "Take me to the home page", + "500.link.home-page": "আমাকে হোম পেজে নিয়ে যাও", + + + // "404.help": "We can't find the page you're looking for. The page may have been moved or deleted. You can use the button below to get back to the home page. ", + "404.help": "আপনি যে পৃষ্ঠাটি খুঁজছেন তা আমরা খুঁজে পাচ্ছি না। পৃষ্ঠাটি সরানো বা মুছে ফেলা হতে পারে। আপনি হোম পেজে ফিরে যেতে নীচের বোতামটি ব্যবহার করতে পারেন।", + + // "404.link.home-page": "Take me to the home page", + "404.link.home-page": "আমাকে হোম পেজে নিয়ে যাও", + + // "404.page-not-found": "page not found", + "404.page-not-found": "পৃষ্ঠা খুঁজে পাওয়া যায়নি", + + // "admin.curation-tasks.breadcrumbs": "System curation tasks", + "admin.curation-tasks.breadcrumbs": "সিস্টেম নিরাময়ের কাজ", + + // "admin.curation-tasks.title": "System curation tasks", + "admin.curation-tasks.title": "সিস্টেম নিরাময়ের কাজ", + + // "admin.curation-tasks.header": "System curation tasks", + "admin.curation-tasks.header": "সিস্টেম নিরাময়ের কাজ", + + // "admin.registries.bitstream-formats.breadcrumbs": "Format registry", + "admin.registries.bitstream-formats.breadcrumbs": "বিন্যাস রেজিস্ট্রি", + + // "admin.registries.bitstream-formats.create.breadcrumbs": "Bitstream format", + "admin.registries.bitstream-formats.create.breadcrumbs": "বিটস্ট্রিম বিন্যাস", + + // "admin.registries.bitstream-formats.create.failure.content": "An error occurred while creating the new bitstream format.", + "admin.registries.bitstream-formats.create.failure.content": "নতুন বিটস্ট্রিম বিন্যাস তৈরি করার সময় একটি ত্রুটি ঘটেছে।", + + // "admin.registries.bitstream-formats.create.failure.head": "Failure", + "admin.registries.bitstream-formats.create.failure.head": "ব্যর্থতা", + + // "admin.registries.bitstream-formats.create.head": "Create Bitstream format", + "admin.registries.bitstream-formats.create.head": "বিটস্ট্রিম বিন্যাস তৈরি করুন", + + // "admin.registries.bitstream-formats.create.new": "Add a new bitstream format", + "admin.registries.bitstream-formats.create.new": "একটি নতুন বিটস্ট্রিম বিন্যাস যোগ করুন", + + // "admin.registries.bitstream-formats.create.success.content": "The new bitstream format was successfully created.", + "admin.registries.bitstream-formats.create.success.content": "নতুন বিটস্ট্রিম বিন্যাস সফলভাবে তৈরি করা হয়েছিল।", + + // "admin.registries.bitstream-formats.create.success.head": "Success", + "admin.registries.bitstream-formats.create.success.head": "সাফল্য", + + // "admin.registries.bitstream-formats.delete.failure.amount": "Failed to remove {{ amount }} format(s)", + "admin.registries.bitstream-formats.delete.failure.amount": "{{ amount }} বিন্যাস (গুলি) অপসারণ করতে ব্যর্থ", + + // "admin.registries.bitstream-formats.delete.failure.head": "Failure", + "admin.registries.bitstream-formats.delete.failure.head": "ব্যর্থতা", + + // "admin.registries.bitstream-formats.delete.success.amount": "Successfully removed {{ amount }} format(s)", + "admin.registries.bitstream-formats.delete.success.amount": "সফলভাবে সরানো {{ amount }} বিন্যাস (গুলি)", + + // "admin.registries.bitstream-formats.delete.success.head": "Success", + "admin.registries.bitstream-formats.delete.success.head": "সাফল্য", + + // "admin.registries.bitstream-formats.description": "This list of bitstream formats provides information about known formats and their support level.", + "admin.registries.bitstream-formats.description": "বিটস্ট্রিম ফরম্যাটের এই তালিকা পরিচিত ফরম্যাট এবং তাদের সমর্থন স্তর সম্পর্কে তথ্য সরবরাহ করে।", + + // "admin.registries.bitstream-formats.edit.breadcrumbs": "Bitstream format", + "admin.registries.bitstream-formats.edit.breadcrumbs": "বিটস্ট্রিম বিন্যাস", + + // "admin.registries.bitstream-formats.edit.description.hint": "", + // TODO New key - Add a translation + "admin.registries.bitstream-formats.edit.description.hint": "", + + // "admin.registries.bitstream-formats.edit.description.label": "Description", + "admin.registries.bitstream-formats.edit.description.label": "বর্ণনা", + + // "admin.registries.bitstream-formats.edit.extensions.hint": "Extensions are file extensions that are used to automatically identify the format of uploaded files. You can enter several extensions for each format.", + "admin.registries.bitstream-formats.edit.extensions.hint": "এক্সটেনশানগুলি হল ফাইল এক্সটেনশান যা স্বয়ংক্রিয়ভাবে আপলোড করা ফাইলগুলির বিন্যাস সনাক্ত করতে ব্যবহৃত হয়। আপনি প্রতিটি বিন্যাসের জন্য বিভিন্ন এক্সটেনশন লিখতে পারেন।", + + // "admin.registries.bitstream-formats.edit.extensions.label": "File extensions", + "admin.registries.bitstream-formats.edit.extensions.label": "ফাইল এক্সটেনশান", + + // "admin.registries.bitstream-formats.edit.extensions.placeholder": "Enter a file extension without the dot", + "admin.registries.bitstream-formats.edit.extensions.placeholder": "ডট ছাড়া একটি ফাইল এক্সটেনশান লিখুন", + + // "admin.registries.bitstream-formats.edit.failure.content": "An error occurred while editing the bitstream format.", + "admin.registries.bitstream-formats.edit.failure.content": "বিটস্ট্রিম বিন্যাস সম্পাদনা করার সময় একটি ত্রুটি ঘটেছে।", + + // "admin.registries.bitstream-formats.edit.failure.head": "Failure", + "admin.registries.bitstream-formats.edit.failure.head": "ব্যর্থতা", + + // "admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}", + "admin.registries.bitstream-formats.edit.head": "বিটস্ট্রিম বিন্যাস: {{ format }}", + + // "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.", + "admin.registries.bitstream-formats.edit.internal.hint": "অভ্যন্তরীণ হিসাবে চিহ্নিত ফর্ম্যাট ব্যবহারকারী থেকে লুকানো এবং প্রশাসনিক উদ্দেশ্যে ব্যবহার করা হয়।", + + // "admin.registries.bitstream-formats.edit.internal.label": "Internal", + "admin.registries.bitstream-formats.edit.internal.label": "অভ্যন্তরীণ", + + // "admin.registries.bitstream-formats.edit.mimetype.hint": "The MIME type associated with this format, does not have to be unique.", + "admin.registries.bitstream-formats.edit.mimetype.hint": "এই বিন্যাসের সাথে যুক্ত মিম টাইপ ইউনিক হতে হবে না।", + + // "admin.registries.bitstream-formats.edit.mimetype.label": "MIME Type", + "admin.registries.bitstream-formats.edit.mimetype.label": "মিম টাইপ", + + // "admin.registries.bitstream-formats.edit.shortDescription.hint": "A unique name for this format, (e.g. Microsoft Word XP or Microsoft Word 2000)", + "admin.registries.bitstream-formats.edit.shortDescription.hint": "এই বিন্যাসের জন্য একটি ইউনিক নাম (উদাহরণ সরূপঃ মাইক্রোসফ্ট ওয়ার্ড এক্সপি বা মাইক্রোসফ্ট ওয়ার্ড 2000)", + + // "admin.registries.bitstream-formats.edit.shortDescription.label": "Name", + "admin.registries.bitstream-formats.edit.shortDescription.label": "নাম", + + // "admin.registries.bitstream-formats.edit.success.content": "The bitstream format was successfully edited.", + "admin.registries.bitstream-formats.edit.success.content": "বিটস্ট্রিম বিন্যাস সফলভাবে সম্পাদিত হয়।", + + // "admin.registries.bitstream-formats.edit.success.head": "Success", + "admin.registries.bitstream-formats.edit.success.head": "সাফল্য", + + // "admin.registries.bitstream-formats.edit.supportLevel.hint": "The level of support your institution pledges for this format.", + "admin.registries.bitstream-formats.edit.supportLevel.hint": "এই বিন্যাসের জন্য আপনার প্রতিষ্ঠানের প্রতিশ্রুতি সমর্থনের স্তর", + + // "admin.registries.bitstream-formats.edit.supportLevel.label": "Support level", + "admin.registries.bitstream-formats.edit.supportLevel.label": "সমর্থন স্তর", + + // "admin.registries.bitstream-formats.head": "Bitstream Format Registry", + "admin.registries.bitstream-formats.head": "বিটস্ট্রিম ফরম্যাট রেজিস্ট্রি", + + // "admin.registries.bitstream-formats.no-items": "No bitstream formats to show.", + "admin.registries.bitstream-formats.no-items": "প্রদর্শন করার মত কোন বিটস্ট্রিম ফর্ম্যাট নেই।", + + // "admin.registries.bitstream-formats.table.delete": "Delete selected", + "admin.registries.bitstream-formats.table.delete": "নির্বাচিতটা মুছুন", + + // "admin.registries.bitstream-formats.table.deselect-all": "Deselect all", + "admin.registries.bitstream-formats.table.deselect-all": "সব গুলো অনির্বাচিত কর", + + // "admin.registries.bitstream-formats.table.internal": "internal", + "admin.registries.bitstream-formats.table.internal": "অভ্যন্তরীণ", + + // "admin.registries.bitstream-formats.table.mimetype": "MIME Type", + "admin.registries.bitstream-formats.table.mimetype": "মিম টাইপ", + + // "admin.registries.bitstream-formats.table.name": "Name", + "admin.registries.bitstream-formats.table.name": "নাম", + + // "admin.registries.bitstream-formats.table.return": "Back", + "admin.registries.bitstream-formats.table.return": "পেছনে", + + // "admin.registries.bitstream-formats.table.supportLevel.KNOWN": "Known", + "admin.registries.bitstream-formats.table.supportLevel.KNOWN": "পরিচিত", + + // "admin.registries.bitstream-formats.table.supportLevel.SUPPORTED": "Supported", + "admin.registries.bitstream-formats.table.supportLevel.SUPPORTED": "সমর্থিত", + + // "admin.registries.bitstream-formats.table.supportLevel.UNKNOWN": "Unknown", + "admin.registries.bitstream-formats.table.supportLevel.UNKNOWN": "অজানা", + + // "admin.registries.bitstream-formats.table.supportLevel.head": "Support Level", + "admin.registries.bitstream-formats.table.supportLevel.head": "সমর্থন স্তর", + + // "admin.registries.bitstream-formats.title": "Bitstream Format Registry", + "admin.registries.bitstream-formats.title": "বিটস্ট্রিম রেজিস্ট্রি ফরম্যাট", + + + + // "admin.registries.metadata.breadcrumbs": "Metadata registry", + "admin.registries.metadata.breadcrumbs": "মেটাডেটা রেজিস্ট্রি", + + // "admin.registries.metadata.description": "The metadata registry maintains a list of all metadata fields available in the repository. These fields may be divided amongst multiple schemas. However, DSpace requires the qualified Dublin Core schema.", + "admin.registries.metadata.description": "মেটাডেটা রেজিস্ট্রি রিপোজিটরিতে উপলব্ধ সমস্ত মেটাডেটা ক্ষেত্রের একটি তালিকা বজায় রাখে। এই ক্ষেত্রগুলি একাধিক স্কিমাসের মধ্যে বিভক্ত করা যেতে পারে। তবে ডিস্পেস যোগ্য ডাবলিন কোর স্কিমা প্রয়োজন।", + + // "admin.registries.metadata.form.create": "Create metadata schema", + "admin.registries.metadata.form.create": "মেটাডাটা স্কিমা তৈরি করুন", + + // "admin.registries.metadata.form.edit": "Edit metadata schema", + "admin.registries.metadata.form.edit": "মেটাডাটা স্কিমা সম্পাদনা করুন", + + // "admin.registries.metadata.form.name": "Name", + "admin.registries.metadata.form.name": "নাম", + + // "admin.registries.metadata.form.namespace": "Namespace", + "admin.registries.metadata.form.namespace": "নামস্থান", + + // "admin.registries.metadata.head": "Metadata Registry", + "admin.registries.metadata.head": "মেটাডেটা রেজিস্ট্রি", + + // "admin.registries.metadata.schemas.no-items": "No metadata schemas to show.", + "admin.registries.metadata.schemas.no-items": "প্রদর্শন করার মত কোন মেটাডেটা স্কিমা নেই", + + // "admin.registries.metadata.schemas.table.delete": "Delete selected", + "admin.registries.metadata.schemas.table.delete": "নির্বাচিতটা মুছুন", + + // "admin.registries.metadata.schemas.table.id": "ID", + "admin.registries.metadata.schemas.table.id": "আইডি", + + // "admin.registries.metadata.schemas.table.name": "Name", + "admin.registries.metadata.schemas.table.name": "নাম", + + // "admin.registries.metadata.schemas.table.namespace": "Namespace", + "admin.registries.metadata.schemas.table.namespace": "নামস্থান", + + // "admin.registries.metadata.title": "Metadata Registry", + "admin.registries.metadata.title": "মেটাডেটা রেজিস্ট্রি", + + + + // "admin.registries.schema.breadcrumbs": "Metadata schema", + "admin.registries.schema.breadcrumbs": "মেটাডাটা স্কিমা", + + // "admin.registries.schema.description": "This is the metadata schema for \"{{namespace}}\".", + "admin.registries.schema.description": "এটি \"{{ namespace }}\" এর জন্য মেটাডেটা স্কিমা।", + + // "admin.registries.schema.fields.head": "Schema metadata fields", + "admin.registries.schema.fields.head": "স্কিমা মেটাডেটা ক্ষেত্র", + + // "admin.registries.schema.fields.no-items": "No metadata fields to show.", + "admin.registries.schema.fields.no-items": "প্রদর্শন করার মত কোন মেটাডেটা ক্ষেত্র নেই", + + // "admin.registries.schema.fields.table.delete": "Delete selected", + "admin.registries.schema.fields.table.delete": "নির্বাচিতটা মুছুন", + + // "admin.registries.schema.fields.table.field": "Field", + "admin.registries.schema.fields.table.field": "ক্ষেত্র", + + // "admin.registries.schema.fields.table.scopenote": "Scope Note", + "admin.registries.schema.fields.table.scopenote": "স্কোপ নোট", + + // "admin.registries.schema.form.create": "Create metadata field", + "admin.registries.schema.form.create": "মেটাডেটা ক্ষেত্র তৈরি করুন", + + // "admin.registries.schema.form.edit": "Edit metadata field", + "admin.registries.schema.form.edit": "মেটাডেটা ফিল্ড সম্পাদনা করুন", + + // "admin.registries.schema.form.element": "Element", + "admin.registries.schema.form.element": "উপাদান", + + // "admin.registries.schema.form.qualifier": "Qualifier", + "admin.registries.schema.form.qualifier": "কোয়ালিফায়ার", + + // "admin.registries.schema.form.scopenote": "Scope Note", + "admin.registries.schema.form.scopenote": "স্কোপ নোট", + + // "admin.registries.schema.head": "Metadata Schema", + "admin.registries.schema.head": "মেটাডাটা স্কিমা", + + // "admin.registries.schema.notification.created": "Successfully created metadata schema \"{{prefix}}\"", + "admin.registries.schema.notification.created": "সফলভাবে তৈরি মেটাডেটা স্কিমা \"{{prefix}}\"।", + + // "admin.registries.schema.notification.deleted.failure": "Failed to delete {{amount}} metadata schemas", + "admin.registries.schema.notification.deleted.failure": "মেটাডেটা স্কিমা গুলো মুছে ফেলতে ব্যর্থ হয়েছে {{ amount }} মেটাডাটা স্কিমাস", + + // "admin.registries.schema.notification.deleted.success": "Successfully deleted {{amount}} metadata schemas", + "admin.registries.schema.notification.deleted.success": "সফলভাবে মুছে ফেলা {{ amount }} মেটাডাটা স্কিমাস", + + // "admin.registries.schema.notification.edited": "Successfully edited metadata schema \"{{prefix}}\"", + "admin.registries.schema.notification.edited": "সফলভাবে সম্পাদিত মেটাডেটা স্কিমা \"{{prefix}}\"।", + + // "admin.registries.schema.notification.failure": "Error", + "admin.registries.schema.notification.failure": "ত্রুটি", + + // "admin.registries.schema.notification.field.created": "Successfully created metadata field \"{{field}}\"", + "admin.registries.schema.notification.field.created": "সফলভাবে মেটাডেটা ক্ষেত্র তৈরি করা \"{{ field }}\"", + + // "admin.registries.schema.notification.field.deleted.failure": "Failed to delete {{amount}} metadata fields", + "admin.registries.schema.notification.field.deleted.failure": "{{ amount }} মেটাডেটা ক্ষেত্র মুছে ফেলতে ব্যর্থ হয়েছে", + + // "admin.registries.schema.notification.field.deleted.success": "Successfully deleted {{amount}} metadata fields", + "admin.registries.schema.notification.field.deleted.success": "সফলভাবে মুছে ফেলা {{ amount }} মেটাডেটা ক্ষেত্র", + + // "admin.registries.schema.notification.field.edited": "Successfully edited metadata field \"{{field}}\"", + "admin.registries.schema.notification.field.edited": "সফলভাবে সম্পাদিত মেটাডেটা ক্ষেত্র \"{{ field }}\"।", + + // "admin.registries.schema.notification.success": "Success", + "admin.registries.schema.notification.success": "সাফল্য", + + // "admin.registries.schema.return": "Back", + "admin.registries.schema.return": "পেছনে", + + // "admin.registries.schema.title": "Metadata Schema Registry", + "admin.registries.schema.title": "মেটাডাটা স্কিমা রেজিস্ট্রি", + + + + // "admin.access-control.epeople.actions.delete": "Delete EPerson", + "admin.access-control.epeople.actions.delete": "ই-পারসন মুছে দিন", + + // "admin.access-control.epeople.actions.impersonate": "Impersonate EPerson", + "admin.access-control.epeople.actions.impersonate": "ছদ্মবেশী ই-পারসন", + + // "admin.access-control.epeople.actions.reset": "Reset password", + "admin.access-control.epeople.actions.reset": "পাসওয়ার্ড রিসেট করুন", + + // "admin.access-control.epeople.actions.stop-impersonating": "Stop impersonating EPerson", + "admin.access-control.epeople.actions.stop-impersonating": "ছদ্মবেশী ই-পারসন বন্ধ করুন", + + // "admin.access-control.epeople.breadcrumbs": "EPeople", + "admin.access-control.epeople.breadcrumbs": "ই-পারসন", + + // "admin.access-control.epeople.title": "EPeople", + "admin.access-control.epeople.title": "ই-পারসন", + + // "admin.access-control.epeople.head": "EPeople", + "admin.access-control.epeople.head": "ই-পারসন", + + // "admin.access-control.epeople.search.head": "Search", + "admin.access-control.epeople.search.head": "অনুসন্ধান করুন", + + // "admin.access-control.epeople.button.see-all": "Browse All", + "admin.access-control.epeople.button.see-all": "সব ব্রাউজ করুন", + + // "admin.access-control.epeople.search.scope.metadata": "Metadata", + "admin.access-control.epeople.search.scope.metadata": "মেটাডেটা", + + // "admin.access-control.epeople.search.scope.email": "E-mail (exact)", + "admin.access-control.epeople.search.scope.email": "ই-মেইল (সঠিক)", + + // "admin.access-control.epeople.search.button": "Search", + "admin.access-control.epeople.search.button": "অনুসন্ধান করুন", + + // "admin.access-control.epeople.search.placeholder": "Search people...", + "admin.access-control.epeople.search.placeholder": "ব্যাক্তি অনুসন্ধান করুন ...", + + // "admin.access-control.epeople.button.add": "Add EPerson", + "admin.access-control.epeople.button.add": "ই-পারসন যোগ করুন", + + // "admin.access-control.epeople.table.id": "ID", + "admin.access-control.epeople.table.id": "আইডি", + + // "admin.access-control.epeople.table.name": "Name", + "admin.access-control.epeople.table.name": "নাম", + + // "admin.access-control.epeople.table.email": "E-mail (exact)", + "admin.access-control.epeople.table.email": "ই-মেইল (সঠিক)", + + // "admin.access-control.epeople.table.edit": "Edit", + "admin.access-control.epeople.table.edit": "সম্পাদনা করুন", + + // "admin.access-control.epeople.table.edit.buttons.edit": "Edit \"{{name}}\"", + "admin.access-control.epeople.table.edit.buttons.edit": "\"{{ name }}\" সম্পাদনা কর", + + // "admin.access-control.epeople.table.edit.buttons.edit-disabled": "You are not authorized to edit this group", + "admin.access-control.epeople.table.edit.buttons.edit-disabled": "আপনি এই গ্রুপ সম্পাদনা করার জন্য অনুমোদিত নয়", + + // "admin.access-control.epeople.table.edit.buttons.remove": "Delete \"{{name}}\"", + "admin.access-control.epeople.table.edit.buttons.remove": "\"{{ name }}\" মুছে ফেলুন", + + // "admin.access-control.epeople.no-items": "No EPeople to show.", + "admin.access-control.epeople.no-items": "কোন ই-পারসিওন প্রদর্শন করার জন্যে নেই।", + + // "admin.access-control.epeople.form.create": "Create EPerson", + "admin.access-control.epeople.form.create": "ই-পারসন তৈরি করুন", + + // "admin.access-control.epeople.form.edit": "Edit EPerson", + "admin.access-control.epeople.form.edit": "ই-পারসন সম্পাদনা করুন", + + // "admin.access-control.epeople.form.firstName": "First name", + "admin.access-control.epeople.form.firstName": "নামের প্রথম অংশ", + + // "admin.access-control.epeople.form.lastName": "Last name", + "admin.access-control.epeople.form.lastName": "নামের শেষাংশ", + + // "admin.access-control.epeople.form.email": "E-mail", + "admin.access-control.epeople.form.email": "ই-মেইল", + + // "admin.access-control.epeople.form.emailHint": "Must be valid e-mail address", + "admin.access-control.epeople.form.emailHint": "বৈধ ইমেইল ঠিকানা হতে হবে", + + // "admin.access-control.epeople.form.canLogIn": "Can log in", + "admin.access-control.epeople.form.canLogIn": "লগ ইন করতে পারেন", + + // "admin.access-control.epeople.form.requireCertificate": "Requires certificate", + "admin.access-control.epeople.form.requireCertificate": "সার্টিফিকেট প্রয়োজন", + + // "admin.access-control.epeople.form.return": "Back", + "admin.access-control.epeople.form.return": "পেছনে", + + // "admin.access-control.epeople.form.notification.created.success": "Successfully created EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.created.success": "সফলভাবে তৈরি ই-পারসন \"{{ name }}\"।", + + // "admin.access-control.epeople.form.notification.created.failure": "Failed to create EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.created.failure": "ই-পারসন তৈরি করতে ব্যর্থ \"{{ name }}\"।" , + + // "admin.access-control.epeople.form.notification.created.failure.emailInUse": "Failed to create EPerson \"{{name}}\", email \"{{email}}\" already in use.", + "admin.access-control.epeople.form.notification.created.failure.emailInUse": "ই-পারসন \"{{ name }}\" তৈরি করতে ব্যর্থ। ইমেল \"{{ email }}\" ইতিমধ্যে ব্যবহার করা হয়েছে।", + + // "admin.access-control.epeople.form.notification.edited.failure.emailInUse": "Failed to edit EPerson \"{{name}}\", email \"{{email}}\" already in use.", + "admin.access-control.epeople.form.notification.edited.failure.emailInUse": "ই-পারসন \"{{ name }}\" সম্পাদনা করতে ব্যর্থ। ইমেল \"{{ email }}\" ইতিমধ্যে ব্যবহার করা হয়েছে।", + + // "admin.access-control.epeople.form.notification.edited.success": "Successfully edited EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.edited.success": "সফলভাবে সম্পাদিত ই-পারসন \"{{ name }}\"।", + + // "admin.access-control.epeople.form.notification.edited.failure": "Failed to edit EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.edited.failure": "ই-পারসন সম্পাদনা করতে ব্যর্থ \"{{ name }}\"।", + + // "admin.access-control.epeople.form.notification.deleted.success": "Successfully deleted EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.deleted.success": "সফলভাবে মুছে ফেলা ই-পারসন \"{{ name }}\"।", + + // "admin.access-control.epeople.form.notification.deleted.failure": "Failed to delete EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.deleted.failure": "ই-পারসন মুছে ফেলতে ব্যর্থ হয়েছে \"{{ name }}\"।", + + // "admin.access-control.epeople.form.groupsEPersonIsMemberOf": "Member of these groups:", + "admin.access-control.epeople.form.groupsEPersonIsMemberOf": "এই দলের সদস্য:", + + // "admin.access-control.epeople.form.table.id": "ID", + "admin.access-control.epeople.form.table.id": "আইডি", + + // "admin.access-control.epeople.form.table.name": "Name", + "admin.access-control.epeople.form.table.name": "নাম", + + // "admin.access-control.epeople.form.table.collectionOrCommunity": "Collection/Community", + "admin.access-control.epeople.form.table.collectionOrCommunity": "সংগ্রহ / সম্প্রদায়", + + // "admin.access-control.epeople.form.memberOfNoGroups": "This EPerson is not a member of any groups", + "admin.access-control.epeople.form.memberOfNoGroups": "এই ই-পারসন কোন দলের সদস্য নয়", + + // "admin.access-control.epeople.form.goToGroups": "Add to groups", + "admin.access-control.epeople.form.goToGroups": "গ্রুপে যোগ করুন", + + // "admin.access-control.epeople.notification.deleted.failure": "Failed to delete EPerson: \"{{name}}\"", + "admin.access-control.epeople.notification.deleted.failure": "ই-পারসন মুছে ফেলতে ব্যর্থ হয়েছে: \"{{name}}\"", + + // "admin.access-control.epeople.notification.deleted.success": "Successfully deleted EPerson: \"{{name}}\"", + "admin.access-control.epeople.notification.deleted.success": "সফলভাবে ই-পারসন মুছে ফেলা হয়েছে: \"{{name}}\"", + + + + // "admin.access-control.groups.title": "Groups", + "admin.access-control.groups.title": "গ্রুপ", + + // "admin.access-control.groups.breadcrumbs": "Groups", + "admin.access-control.groups.breadcrumbs": "গ্রুপ", + + // "admin.access-control.groups.singleGroup.breadcrumbs": "Edit Group", + "admin.access-control.groups.singleGroup.breadcrumbs": "গ্রুপ সম্পাদনা করুন", + + // "admin.access-control.groups.title.singleGroup": "Edit Group", + "admin.access-control.groups.title.singleGroup": "গ্রুপ সম্পাদনা করুন", + + // "admin.access-control.groups.title.addGroup": "New Group", + "admin.access-control.groups.title.addGroup": "নতুন দল", + + // "admin.access-control.groups.addGroup.breadcrumbs": "New Group", + "admin.access-control.groups.addGroup.breadcrumbs": "নতুন দল", + + // "admin.access-control.groups.head": "Groups", + "admin.access-control.groups.head": "গ্রুপ", + + // "admin.access-control.groups.button.add": "Add group", + "admin.access-control.groups.button.add": "গ্রুপ যোগ করুন", + + // "admin.access-control.groups.search.head": "Search groups", + "admin.access-control.groups.search.head": "অনুসন্ধান গ্রুপ", + + // "admin.access-control.groups.button.see-all": "Browse all", + "admin.access-control.groups.button.see-all": "সব ব্রাউজ করুন", + + // "admin.access-control.groups.search.button": "Search", + "admin.access-control.groups.search.button": "অনুসন্ধান করুন", + + // "admin.access-control.groups.search.placeholder": "Search groups...", + "admin.access-control.groups.search.placeholder": "গ্রুপ অনুসন্ধান করুন...", + + // "admin.access-control.groups.table.id": "ID", + "admin.access-control.groups.table.id": "আইডি", + + // "admin.access-control.groups.table.name": "Name", + "admin.access-control.groups.table.name": "নাম", + + // "admin.access-control.groups.table.collectionOrCommunity": "Collection/Community", + "admin.access-control.groups.table.collectionOrCommunity": "সংগ্রহ / সম্প্রদায়", + + // "admin.access-control.groups.table.members": "Members", + "admin.access-control.groups.table.members": "সদস্যগণ", + + // "admin.access-control.groups.table.edit": "Edit", + "admin.access-control.groups.table.edit": "সম্পাদনা করুন", + + // "admin.access-control.groups.table.edit.buttons.edit": "Edit \"{{name}}\"", + "admin.access-control.groups.table.edit.buttons.edit": "\"{{ name }}\" সম্পাদনা করুন।", + + // "admin.access-control.groups.table.edit.buttons.remove": "Delete \"{{name}}\"", + "admin.access-control.groups.table.edit.buttons.remove": "\"{{ name }}\" মুছে ফেলুন ।", + + // "admin.access-control.groups.no-items": "No groups found with this in their name or this as UUID", + "admin.access-control.groups.no-items": "তাদের নাম বা এই UUID হিসাবে কোন গ্রুপ পাওয়া যায় নি", + + // "admin.access-control.groups.notification.deleted.success": "Successfully deleted group \"{{name}}\"", + "admin.access-control.groups.notification.deleted.success": "সফলভাবে মুছে ফেলা গ্রুপ \"{{ name }}\"।", + + // "admin.access-control.groups.notification.deleted.failure.title": "Failed to delete group \"{{name}}\"", + "admin.access-control.groups.notification.deleted.failure.title": "গ্রুপ \"{{ name }}\" মুছে ফেলতে ব্যর্থ হয়েছে", + + // "admin.access-control.groups.notification.deleted.failure.content": "Cause: \"{{cause}}\"", + "admin.access-control.groups.notification.deleted.failure.content": "কারণ: \"{{cause}}\"", + + + + // "admin.access-control.groups.form.alert.permanent": "This group is permanent, so it can't be edited or deleted. You can still add and remove group members using this page.", + "admin.access-control.groups.form.alert.permanent": "এই গ্রুপটি স্থায়ী হয় তাই এটি সম্পাদনা বা মুছে ফেলা যাবে না। আপনি এখনও এই পৃষ্ঠাটি ব্যবহার করে গ্রুপ সদস্যদের যোগ এবং অপসারণ করতে পারেন।", + + // "admin.access-control.groups.form.alert.workflowGroup": "This group can’t be modified or deleted because it corresponds to a role in the submission and workflow process in the \"{{name}}\" {{comcol}}. You can delete it from the \"assign roles\" tab on the edit {{comcol}} page. You can still add and remove group members using this page.", + "admin.access-control.groups.form.alert.workflowGroup": "এই গোষ্ঠীটি সংশোধন করা বা মুছে ফেলা যাবে না কারণ এটি \"{{ name }}\" \"{{ comcol }}\" -এ জমা এবং ওয়ার্কফ্লো প্রক্রিয়াতে ভূমিকা অনুসারে। আপনি এটি মুছে ফেলতে পারেন from the \"assign roles\" tab on the edit {{comcol}} page। আপনি এখনও এই পৃষ্ঠাটি ব্যবহার করে গ্রুপ সদস্যদের যোগ এবং অপসারণ করতে পারেন।", + + // "admin.access-control.groups.form.head.create": "Create group", + "admin.access-control.groups.form.head.create": "দল গঠন", + + // "admin.access-control.groups.form.head.edit": "Edit group", + "admin.access-control.groups.form.head.edit": "গ্রুপ সম্পাদনা করুন", + + // "admin.access-control.groups.form.groupName": "Group name", + "admin.access-control.groups.form.groupName": "দলের নাম", + + // "admin.access-control.groups.form.groupCommunity": "Community or Collection", + "admin.access-control.groups.form.groupCommunity": "সম্প্রদায় বা সংগ্রহ", + + // "admin.access-control.groups.form.groupDescription": "Description", + "admin.access-control.groups.form.groupDescription": "বর্ণনা", + + // "admin.access-control.groups.form.notification.created.success": "Successfully created Group \"{{name}}\"", + "admin.access-control.groups.form.notification.created.success": "সফলভাবে তৈরিকৃত গ্রুপ \"{{ name }}\"।", + + // "admin.access-control.groups.form.notification.created.failure": "Failed to create Group \"{{name}}\"", + "admin.access-control.groups.form.notification.created.failure": "গ্রুপ তৈরি করতে ব্যর্থ \"{{ name }}\"", + + // "admin.access-control.groups.form.notification.created.failure.groupNameInUse": "Failed to create Group with name: \"{{name}}\", make sure the name is not already in use.", + "admin.access-control.groups.form.notification.created.failure.groupNameInUse": "নামের সাথে গ্রুপ তৈরি করতে ব্যর্থ হয়েছে: \"{{name}}\", নিশ্চিত করুন যে নামটি ইতিমধ্যে ব্যবহার করা হচ্ছে না।", + + // "admin.access-control.groups.form.notification.edited.failure": "Failed to edit Group \"{{name}}\"", + "admin.access-control.groups.form.notification.edited.failure": "গ্রুপ সম্পাদনা করতে ব্যর্থ \"{{ name }}\"।", + + // "admin.access-control.groups.form.notification.edited.failure.groupNameInUse": "Name \"{{name}}\" already in use!", + "admin.access-control.groups.form.notification.edited.failure.groupNameInUse": "নাম \"{{ name }}\" ইতিমধ্যে ব্যবহার হয়েছে!", + + // "admin.access-control.groups.form.notification.edited.success": "Successfully edited Group \"{{name}}\"", + "admin.access-control.groups.form.notification.edited.success": "সফলভাবে সম্পাদনা করা গ্রুপ \"{{ name }}\"।", + + // "admin.access-control.groups.form.actions.delete": "Delete Group", + "admin.access-control.groups.form.actions.delete": "গ্রুপ মুছুন", + + // "admin.access-control.groups.form.delete-group.modal.header": "Delete Group \"{{ dsoName }}\"", + "admin.access-control.groups.form.delete-group.modal.header": "গ্রুপ মুছে ফেলুন \"{{ dsoName }}\"", + + // "admin.access-control.groups.form.delete-group.modal.info": "Are you sure you want to delete Group \"{{ dsoName }}\"", + "admin.access-control.groups.form.delete-group.modal.info": "আপনি কি গ্রুপ \"{{ dsoName }}\" মুছে ফেলতে চান তা নিশ্চিত করুন।", + + // "admin.access-control.groups.form.delete-group.modal.cancel": "Cancel", + "admin.access-control.groups.form.delete-group.modal.cancel": "বাতিল করুন", + + // "admin.access-control.groups.form.delete-group.modal.confirm": "Delete", + "admin.access-control.groups.form.delete-group.modal.confirm": "মুছে ফেলা", + + // "admin.access-control.groups.form.notification.deleted.success": "Successfully deleted group \"{{ name }}\"", + "admin.access-control.groups.form.notification.deleted.success": "সফলভাবে মুছে ফেলা গ্রুপ \"{{ name }}\"।", + + // "admin.access-control.groups.form.notification.deleted.failure.title": "Failed to delete group \"{{ name }}\"", + "admin.access-control.groups.form.notification.deleted.failure.title": "গ্রুপ \"{{ name }}\" মুছে ফেলতে ব্যর্থ হয়েছে", + + // "admin.access-control.groups.form.notification.deleted.failure.content": "Cause: \"{{ cause }}\"", + "admin.access-control.groups.form.notification.deleted.failure.content": "কারণঃ \"{{ cause }}\"", + + // "admin.access-control.groups.form.members-list.head": "EPeople", + "admin.access-control.groups.form.members-list.head": "ই-পারসন", + + // "admin.access-control.groups.form.members-list.search.head": "Add EPeople", + "admin.access-control.groups.form.members-list.search.head": "ই-পারসন যোগ করুন", + + // "admin.access-control.groups.form.members-list.button.see-all": "Browse All", + "admin.access-control.groups.form.members-list.button.see-all": "সব ব্রাউজ করুন", + + // "admin.access-control.groups.form.members-list.headMembers": "Current Members", + "admin.access-control.groups.form.members-list.headMembers": "বর্তমান সদস্যগণ", + + // "admin.access-control.groups.form.members-list.search.scope.metadata": "Metadata", + "admin.access-control.groups.form.members-list.search.scope.metadata": "মেটাডেটা", + + // "admin.access-control.groups.form.members-list.search.scope.email": "E-mail (exact)", + "admin.access-control.groups.form.members-list.search.scope.email": "ই-মেইল (সঠিক)", + + // "admin.access-control.groups.form.members-list.search.button": "Search", + "admin.access-control.groups.form.members-list.search.button": "অনুসন্ধান করুন", + + // "admin.access-control.groups.form.members-list.table.id": "ID", + "admin.access-control.groups.form.members-list.table.id": "আইডি", + + // "admin.access-control.groups.form.members-list.table.name": "Name", + "admin.access-control.groups.form.members-list.table.name": "নামকরণ", + + // "admin.access-control.groups.form.members-list.table.identity": "Identity", + "admin.access-control.groups.form.members-list.table.identity": "পরিচয়", + + // "admin.access-control.groups.form.members-list.table.email": "Email", + "admin.access-control.groups.form.members-list.table.email": "ইমেইল.", + + // "admin.access-control.groups.form.members-list.table.netid": "NetID", + "admin.access-control.groups.form.members-list.table.netid": "নেটআইডি", + + // "admin.access-control.groups.form.members-list.table.edit": "Remove / Add", + "admin.access-control.groups.form.members-list.table.edit": "অপসারণ / যোগ করুন", + + // "admin.access-control.groups.form.members-list.table.edit.buttons.remove": "Remove member with name \"{{name}}\"", + "admin.access-control.groups.form.members-list.table.edit.buttons.remove": "নাম দিয়ে সদস্য অপসারণ করুন \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.notification.success.addMember": "Successfully added member: \"{{name}}\"", + "admin.access-control.groups.form.members-list.notification.success.addMember": "সফলভাবে সদস্য যোগ করা হয়েছে: \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.notification.failure.addMember": "Failed to add member: \"{{name}}\"", + "admin.access-control.groups.form.members-list.notification.failure.addMember": "সদস্য যোগ করতে ব্যর্থ: \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.notification.success.deleteMember": "Successfully deleted member: \"{{name}}\"", + "admin.access-control.groups.form.members-list.notification.success.deleteMember": "সদস্য সফলভাবে মুছে ফেলা হয়েছে: \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.notification.failure.deleteMember": "Failed to delete member: \"{{name}}\"", + "admin.access-control.groups.form.members-list.notification.failure.deleteMember": "সদস্য মুছে ফেলতে ব্যর্থ: \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.table.edit.buttons.add": "Add member with name \"{{name}}\"", + "admin.access-control.groups.form.members-list.table.edit.buttons.add": "নাম দিয়ে সদস্য যোগ করুন \"{{name}}\"", + + // "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", + "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "কোন সক্রিয় গ্রুপ নেই, প্রথমে একটি নাম জমা দিন।", + + // "admin.access-control.groups.form.members-list.no-members-yet": "No members in group yet, search and add.", + "admin.access-control.groups.form.members-list.no-members-yet": "গ্রুপ এখনো কোন সদস্য নেই, যোগ করতে অনুসন্ধান করুন।", + + // "admin.access-control.groups.form.members-list.no-items": "No EPeople found in that search", + "admin.access-control.groups.form.members-list.no-items": "ওই অনুসন্ধান কোন ই-পারসন পাওয়া যায় নি", + + // "admin.access-control.groups.form.subgroups-list.notification.failure": "Something went wrong: \"{{cause}}\"", + "admin.access-control.groups.form.subgroups-list.notification.failure": "কিছু ভুল হয়েছে: \"{{cause}}\"", + + // "admin.access-control.groups.form.subgroups-list.head": "Groups", + "admin.access-control.groups.form.subgroups-list.head": "গ্রুপ", + + // "admin.access-control.groups.form.subgroups-list.search.head": "Add Subgroup", + "admin.access-control.groups.form.subgroups-list.search.head": "সাবগ্রুপ যোগ করুন", + + // "admin.access-control.groups.form.subgroups-list.button.see-all": "Browse All", + "admin.access-control.groups.form.subgroups-list.button.see-all": "সব ব্রাউজ করুন", + + // "admin.access-control.groups.form.subgroups-list.headSubgroups": "Current Subgroups", + "admin.access-control.groups.form.subgroups-list.headSubgroups": "বর্তমান সাবগ্রুপ", + + // "admin.access-control.groups.form.subgroups-list.search.button": "Search", + "admin.access-control.groups.form.subgroups-list.search.button": "অনুসন্ধান করুন", + + // "admin.access-control.groups.form.subgroups-list.table.id": "ID", + "admin.access-control.groups.form.subgroups-list.table.id": "আইডি", + + // "admin.access-control.groups.form.subgroups-list.table.name": "Name", + "admin.access-control.groups.form.subgroups-list.table.name": "নাম", + + // "admin.access-control.groups.form.subgroups-list.table.collectionOrCommunity": "Collection/Community", + "admin.access-control.groups.form.subgroups-list.table.collectionOrCommunity": "সংগ্রহ / সম্প্রদায়", + + // "admin.access-control.groups.form.subgroups-list.table.edit": "Remove / Add", + "admin.access-control.groups.form.subgroups-list.table.edit": "অপসারণ / যোগ করুন", + + // "admin.access-control.groups.form.subgroups-list.table.edit.buttons.remove": "Remove subgroup with name \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.table.edit.buttons.remove": "নাম দিয়ে উপগোষ্ঠী সরান \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.table.edit.buttons.add": "Add subgroup with name \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.table.edit.buttons.add": "নাম দিয়ে উপগোষ্ঠী যোগ করুন \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.table.edit.currentGroup": "Current group", + "admin.access-control.groups.form.subgroups-list.table.edit.currentGroup": "বর্তমান গ্রুপ", + + // "admin.access-control.groups.form.subgroups-list.notification.success.addSubgroup": "Successfully added subgroup: \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.notification.success.addSubgroup": "সফলভাবে সাবগ্রুপ যোগ করা হয়েছে: \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.notification.failure.addSubgroup": "Failed to add subgroup: \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.notification.failure.addSubgroup": "সাবগ্রুপ যোগ করতে ব্যর্থ হয়েছে: \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.notification.success.deleteSubgroup": "Successfully deleted subgroup: \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.notification.success.deleteSubgroup": "সাবগ্রুপ সফলভাবে মোছা হয়েছে: \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.notification.failure.deleteSubgroup": "Failed to delete subgroup: \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.notification.failure.deleteSubgroup": "সাবগ্রুপ মুছে ফেলতে ব্যর্থ হয়েছে: \"{{name}}\"", + + // "admin.access-control.groups.form.subgroups-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", + "admin.access-control.groups.form.subgroups-list.notification.failure.noActiveGroup": "কোন সক্রিয় গ্রুপ নেই, প্রথমে একটি নাম জমা দিন।", + + // "admin.access-control.groups.form.subgroups-list.notification.failure.subgroupToAddIsActiveGroup": "This is the current group, can't be added.", + "admin.access-control.groups.form.subgroups-list.notification.failure.subgroupToAddIsActiveGroup": "এই বর্তমান গ্রুপ যোগ করা যাবে না।", + + // "admin.access-control.groups.form.subgroups-list.no-items": "No groups found with this in their name or this as UUID", + "admin.access-control.groups.form.subgroups-list.no-items": "তাদের নাম বা এই UUID হিসাবে কোন গ্রুপ পাওয়া যায় নি", + + // "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "No subgroups in group yet.", + "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "গ্রুপে এখন কোন সাবগ্রুপ নেই", + + // "admin.access-control.groups.form.return": "Back", + "admin.access-control.groups.form.return": "পেছনে", + + + + // "admin.search.breadcrumbs": "Administrative Search", + "admin.search.breadcrumbs": "প্রশাসনিক অনুসন্ধান", + + // "admin.search.collection.edit": "Edit", + "admin.search.collection.edit": "সম্পাদনা করুন", + + // "admin.search.community.edit": "Edit", + "admin.search.community.edit": "সম্পাদনা করুন", + + // "admin.search.item.delete": "Delete", + "admin.search.item.delete": "মুছে ফেলা", + + // "admin.search.item.edit": "Edit", + "admin.search.item.edit": "সম্পাদনা করুন", + + // "admin.search.item.make-private": "Make Private", + "admin.search.item.make-private": "প্রাইভেট করুন", + + // "admin.search.item.make-public": "Make Public", + "admin.search.item.make-public": "জনসাধারণের জন্য উন্মুক্ত করুন", + + // "admin.search.item.move": "Move", + "admin.search.item.move": "সরানো", + + // "admin.search.item.reinstate": "Reinstate", + "admin.search.item.reinstate": "পুনঃস্থাপন", + + // "admin.search.item.withdraw": "Withdraw", + "admin.search.item.withdraw": "প্রত্যাহার করুন", + + // "admin.search.title": "Administrative Search", + "admin.search.title": "প্রশাসনিক অনুসন্ধান", + + // "administrativeView.search.results.head": "Administrative Search", + "administrativeView.search.results.head": "প্রশাসনিক অনুসন্ধান", + + + + + // "admin.workflow.breadcrumbs": "Administer Workflow", + "admin.workflow.breadcrumbs": "প্রশাসনিক কর্মধারা", + + // "admin.workflow.title": "Administer Workflow", + "admin.workflow.title": "প্রশাসনিক কর্মধারা", + + // "admin.workflow.item.workflow": "Workflow", + "admin.workflow.item.workflow": "কর্মধারা", + + // "admin.workflow.item.delete": "Delete", + "admin.workflow.item.delete": "মুছে ফেলা", + + // "admin.workflow.item.send-back": "Send back", + "admin.workflow.item.send-back": "ফেরত পাঠাও", + + + + // "admin.metadata-import.breadcrumbs": "Import Metadata", + "admin.metadata-import.breadcrumbs": "মেটাডেটা আমদানি করুন", + + // "admin.metadata-import.title": "Import Metadata", + "admin.metadata-import.title": "মেটাডেটা আমদানি করুন", + + // "admin.metadata-import.page.header": "Import Metadata", + "admin.metadata-import.page.header": "মেটাডেটা আমদানি করুন", + + // "admin.metadata-import.page.help": "You can drop or browse CSV files that contain batch metadata operations on files here", + "admin.metadata-import.page.help": "আপনি এখানে ফাইলগুলিতে ব্যাচ মেটাডেটা অপারেশন ধারণ করে এমন সিএসভি ফাইলগুলি ড্রপ বা ব্রাউজ করতে পারেন৷", + + // "admin.metadata-import.page.dropMsg": "Drop a metadata CSV to import", + "admin.metadata-import.page.dropMsg": "আমদানি করতে একটি মেটাডেটা সিএসভি ড্রপ করুন", + + // "admin.metadata-import.page.dropMsgReplace": "Drop to replace the metadata CSV to import", + "admin.metadata-import.page.dropMsgReplace": "মেটাডেটা সিএসভি আমদানি করতে ড্রপ করুন", + + // "admin.metadata-import.page.button.return": "Back", + "admin.metadata-import.page.button.return": "পেছনে", + + // "admin.metadata-import.page.button.proceed": "Proceed", + "admin.metadata-import.page.button.proceed": "এগিয়ে যান", + + // "admin.metadata-import.page.error.addFile": "Select file first!", + "admin.metadata-import.page.error.addFile": "প্রথম ফাইল নির্বাচন করুন!", + + + + + // "auth.errors.invalid-user": "Invalid email address or password.", + "auth.errors.invalid-user": "অবৈধ ইমেইল ঠিকানা বা পাসওয়ার্ড.", + + // "auth.messages.expired": "Your session has expired. Please log in again.", + "auth.messages.expired": "আপনার অধিবেশন মেয়াদ শেষ হয়ে গেছে। অনুগ্রহ পূর্বক আবার প্রবেশ করুন.", + + // "auth.messages.token-refresh-failed": "Refreshing your session token failed. Please log in again.", + "auth.messages.token-refresh-failed": "আপনার সেশন টোকেন রিফ্রেশ ব্যর্থ হয়েছে। অনুগ্রহ পূর্বক আবার প্রবেশ করুন.", + + + + // "bitstream.download.page": "Now downloading {{bitstream}}..." , + "bitstream.download.page": "এখন ডাউনলোড হচ্ছে {{bitstream}}...", + + // "bitstream.download.page.back": "Back" , + "bitstream.download.page.back": "ফিরে যান" , + + + // "bitstream.edit.authorizations.link": "Edit bitstream's Policies", + "bitstream.edit.authorizations.link": "বিটস্ট্রিম এর নীতি সম্পাদনা করুন", + + // "bitstream.edit.authorizations.title": "Edit bitstream's Policies", + "bitstream.edit.authorizations.title": "বিটস্ট্রিম এর নীতি সম্পাদনা করুন", + + // "bitstream.edit.return": "Back", + "bitstream.edit.return": "পেছনে", + + // "bitstream.edit.bitstream": "Bitstream: ", + "bitstream.edit.bitstream": "বিটস্ট্রিম: ", + + // "bitstream.edit.form.description.hint": "Optionally, provide a brief description of the file, for example \"Main article\" or \"Experiment data readings\".", + "bitstream.edit.form.description.hint": "বিকল্পভাবে ফাইলটির সংক্ষিপ্ত বিবরণ প্রদান করুন উদাহরণস্বরূপ \" মূল নিবন্ধ \" অথবা \" পরীক্ষা ডেটা রিডিং \"।", + + // "bitstream.edit.form.description.label": "Description", + "bitstream.edit.form.description.label": "বর্ণনা", + + // "bitstream.edit.form.embargo.hint": "The first day from which access is allowed. This date cannot be modified on this form. To set an embargo date for a bitstream, go to the Item Status tab, click Authorizations..., create or edit the bitstream's READ policy, and set the Start Date as desired.", + "bitstream.edit.form.embargo.hint": "প্রথম দিন থেকে অ্যাক্সেস অনুমতি দেওয়া হয়। এই তারিখটি এই ফর্মটি সংশোধন করা যাবে না। বিটস্ট্রিমের জন্য একটি নিষেধাজ্ঞা নির্ধারণ করতে আইটেমের স্থিতি ট্যাবটিতে যান অনুমোদন ..., তৈরি করুন বা বিটস্ট্রিমের পড়ুন নীতিটি, এবং সম্পাদনা করুন শুরু তারিখ সেট করুন।", + + // "bitstream.edit.form.embargo.label": "Embargo until specific date", + "bitstream.edit.form.embargo.label": "নির্দিষ্ট তারিখ পর্যন্ত নিষেধাজ্ঞা", + + // "bitstream.edit.form.fileName.hint": "Change the filename for the bitstream. Note that this will change the display bitstream URL, but old links will still resolve as long as the sequence ID does not change.", + "bitstream.edit.form.fileName.hint": "বিটস্ট্রিমের জন্য ফাইলের নাম পরিবর্তন করুন। মনে রাখবেন যে এটি প্রদর্শন বিটস্ট্রিম URL টি পরিবর্তন করবে তবে পুরোনো লিঙ্কগুলি এখনও ক্রমটি সমাধান করবে না যতক্ষণ না ক্রম আইডিটি পরিবর্তন হয় না।", + + // "bitstream.edit.form.fileName.label": "Filename", + "bitstream.edit.form.fileName.label": "ফাইলের নাম", + + // "bitstream.edit.form.newFormat.label": "Describe new format", + "bitstream.edit.form.newFormat.label": "নতুন বিন্যাস বর্ণনা করুন", + + // "bitstream.edit.form.newFormat.hint": "The application you used to create the file, and the version number (for example, \"ACMESoft SuperApp version 1.5\").", + "bitstream.edit.form.newFormat.hint": "আপনি যে ফাইলটি ফাইল এবং সংস্করণ নম্বর তৈরি করতে ব্যবহৃত হয়েছিল তা হল (উদাহরণস্বরূপ, \"ACMESoft SuperApp version 1.5\")।", + + // "bitstream.edit.form.primaryBitstream.label": "Primary bitstream", + "bitstream.edit.form.primaryBitstream.label": "প্রাথমিক বিটস্ট্রিম", + + // "bitstream.edit.form.selectedFormat.hint": "If the format is not in the above list, select \"format not in list\" above and describe it under \"Describe new format\".", + "bitstream.edit.form.selectedFormat.hint": "যদি ফর্ম্যাটটি উপরের তালিকাতে না থাকে তবে তালিকাটি \"ফর্ম্যাটটি নির্বাচন করুন \" এবং এটির অধীনে এটি বর্ণনা করুন \"নতুন বিন্যাস বর্ণনা করুন\"।", + + // "bitstream.edit.form.selectedFormat.label": "Selected Format", + "bitstream.edit.form.selectedFormat.label": "নির্বাচিত বিন্যাস", + + // "bitstream.edit.form.selectedFormat.unknown": "Format not in list", + "bitstream.edit.form.selectedFormat.unknown": "তালিকার ভিতরে ফরম্যাট নেই", + + // "bitstream.edit.notifications.error.format.title": "An error occurred saving the bitstream's format", + "bitstream.edit.notifications.error.format.title": "বিটস্ট্রিম এর বিন্যাস সংরক্ষণ করার সময় একটি ত্রুটি হয়েছে", + + // "bitstream.edit.form.iiifLabel.label": "IIIF Label", + "bitstream.edit.form.iiifLabel.label": "IIIF লেবেল", + + // "bitstream.edit.form.iiifLabel.hint": "Canvas label for this image. If not provided default label will be used.", + "bitstream.edit.form.iiifLabel.hint": "এই ছবির জন্য ক্যানভাস লেবেল। যদি প্রদান না হয় ডিফল্ট লেবেল ব্যবহার করা হবে।", + + // "bitstream.edit.form.iiifToc.label": "IIIF Table of Contents", + "bitstream.edit.form.iiifToc.label": "IIIF বিষয়বস্তু টেবিল", + + // "bitstream.edit.form.iiifToc.hint": "Adding text here makes this the start of a new table of contents range.", + "bitstream.edit.form.iiifToc.hint": "এখানে টেক্সট যোগ করা এটিকে বিষয়বস্তুর পরিসরের একটি নতুন টেবিলের সূচনা করে", + + // "bitstream.edit.form.iiifWidth.label": "IIIF Canvas Width", + "bitstream.edit.form.iiifWidth.label": "IIIF ক্যানভাস প্রস্থ", + + // "bitstream.edit.form.iiifWidth.hint": "The canvas width should usually match the image width.", + "bitstream.edit.form.iiifWidth.hint": "ক্যানভাস প্রস্থ সাধারণত ইমেজ প্রস্থের সাথে মেলা উচিত।", + + // "bitstream.edit.form.iiifHeight.label": "IIIF Canvas Height", + "bitstream.edit.form.iiifHeight.label": "IIIF ক্যানভাস উচ্চতা", + + // "bitstream.edit.form.iiifHeight.hint": "The canvas height should usually match the image height.", + "bitstream.edit.form.iiifHeight.hint": "ক্যানভাস উচ্চতা সাধারণত ইমেজের উচ্চতার সাথে মেলে উচিত।", + + + // "bitstream.edit.notifications.saved.content": "Your changes to this bitstream were saved.", + "bitstream.edit.notifications.saved.content": "এই বিটস্ট্রিমে আপনার পরিবর্তন সংরক্ষিত করা হয়েছে।", + + // "bitstream.edit.notifications.saved.title": "Bitstream saved", + "bitstream.edit.notifications.saved.title": "বিটস্ট্রিম সংরক্ষিত", + + // "bitstream.edit.title": "Edit bitstream", + "bitstream.edit.title": "বিটস্ট্রিম সম্পাদনা করুন", + + // "bitstream-request-a-copy.alert.canDownload1": "You already have access to this file. If you want to download the file, click ", + "bitstream-request-a-copy.alert.canDownload1": "ইতিমধ্যে এই ফাইল আপনার অ্যাক্সেস আছে। আপনি যদি ফাইলটি ডাউনলোড করতে চান তবে ক্লিক করুন", + + // "bitstream-request-a-copy.alert.canDownload2": "here", + "bitstream-request-a-copy.alert.canDownload2": "এখানে", + + // "bitstream-request-a-copy.header": "Request a copy of the file", + "bitstream-request-a-copy.header": "ফাইলের একটি কপি অনুরোধ করুন", + + // "bitstream-request-a-copy.intro": "Enter the following information to request a copy for the following item: ", + "bitstream-request-a-copy.intro": "নিম্নলিখিত আইটেমটির জন্য একটি অনুলিপি অনুরোধ করতে নিম্নলিখিত তথ্য লিখুন: ", + + // "bitstream-request-a-copy.intro.bitstream.one": "Requesting the following file: ", + "bitstream-request-a-copy.intro.bitstream.one": "নিম্নলিখিত ফাইল অনুরোধ করা হচ্ছে: ", + // "bitstream-request-a-copy.intro.bitstream.all": "Requesting all files. ", + "bitstream-request-a-copy.intro.bitstream.all": "সব ফাইল অনুরোধ করা হচ্ছে।", + + // "bitstream-request-a-copy.name.label": "Name *", + "bitstream-request-a-copy.name.label": "নাম *", + + // "bitstream-request-a-copy.name.error": "The name is required", + "bitstream-request-a-copy.name.error": "নাম প্রয়োজন", + + // "bitstream-request-a-copy.email.label": "Your e-mail address *", + "bitstream-request-a-copy.email.label": "আপনার ইমেইল ঠিকানা *", + + // "bitstream-request-a-copy.email.hint": "This email address is used for sending the file.", + "bitstream-request-a-copy.email.hint": "এই ইমেল ঠিকানা ফাইল পাঠানোর জন্য ব্যবহার করা হয়।", + + // "bitstream-request-a-copy.email.error": "Please enter a valid email address.", + "bitstream-request-a-copy.email.error": "একটি বৈধ ইমেইল ঠিকানা লিখুন।", + + // "bitstream-request-a-copy.allfiles.label": "Files", + "bitstream-request-a-copy.allfiles.label": "নথি পত্র", + + // "bitstream-request-a-copy.files-all-false.label": "Only the requested file", + "bitstream-request-a-copy.files-all-false.label": "শুধুমাত্র অনুরোধকৃত ফাইল", + + // "bitstream-request-a-copy.files-all-true.label": "All files (of this item) in restricted access", + "bitstream-request-a-copy.files-all-true.label": "সমস্ত ফাইল (এই আইটেমটির) সীমাবদ্ধ অ্যাক্সেসে", + + // "bitstream-request-a-copy.message.label": "Message", + "bitstream-request-a-copy.message.label": "বার্তা", + + // "bitstream-request-a-copy.return": "Back", + "bitstream-request-a-copy.return": "পেছনে", + + // "bitstream-request-a-copy.submit": "Request copy", + "bitstream-request-a-copy.submit": "অনুরোধ কপি", + + // "bitstream-request-a-copy.submit.success": "The item request was submitted successfully.", + "bitstream-request-a-copy.submit.success": "আইটেমের অনুরোধ সফলভাবে পাঠানো দেওয়া হয়েছে।", + + // "bitstream-request-a-copy.submit.error": "Something went wrong with submitting the item request.", + "bitstream-request-a-copy.submit.error": "আইটেমের অনুরোধ পাঠাতে দিয়ে গিয়ে কিছু ভুল হয়েছে।", + + + + // "browse.comcol.by.author": "By Author", + "browse.comcol.by.author": "লেখক দ্বারা", + + // "browse.comcol.by.dateissued": "By Issue Date", + "browse.comcol.by.dateissued": "ইস্যু তারিখ দ্বারা", + + // "browse.comcol.by.subject": "By Subject", + "browse.comcol.by.subject": "বিষয় দ্বারা", + + // "browse.comcol.by.title": "By Title", + "browse.comcol.by.title": "শিরোনাম দ্বারা", + + // "browse.comcol.head": "Browse", + "browse.comcol.head": "ব্রাউজ করুন", + + // "browse.empty": "No items to show.", + "browse.empty": "দেখানোর মত কোন আইটেম নেই।", + + // "browse.metadata.author": "Author", + "browse.metadata.author": "লেখক", + + // "browse.metadata.dateissued": "Issue Date", + "browse.metadata.dateissued": "প্রদানের তারিখ", + + // "browse.metadata.subject": "Subject", + "browse.metadata.subject": "বিষয়", + + // "browse.metadata.title": "Title", + "browse.metadata.title": "শিরোনাম", + + // "browse.metadata.author.breadcrumbs": "Browse by Author", + "browse.metadata.author.breadcrumbs": "লেখক দ্বারা ব্রাউজ করুন", + + // "browse.metadata.dateissued.breadcrumbs": "Browse by Date", + "browse.metadata.dateissued.breadcrumbs": "তারিখ দ্বারা ব্রাউজ করুন", + + // "browse.metadata.subject.breadcrumbs": "Browse by Subject", + "browse.metadata.subject.breadcrumbs": "বিষয় দ্বারা ব্রাউজ করুন", + + // "browse.metadata.title.breadcrumbs": "Browse by Title", + "browse.metadata.title.breadcrumbs": "শিরোনাম দ্বারা ব্রাউজ করুন", + + // "browse.next.button": "Next", + "browse.next.button": "পরবর্তী", + + // "browse.previous.button": "Previous", + "browse.previous.button": "পূর্ববর্তী", + + // "browse.startsWith.choose_start": "(Choose start)", + "browse.startsWith.choose_start": "(শুরু নির্বাচন করুন)", + + // "browse.startsWith.choose_year": "(Choose year)", + "browse.startsWith.choose_year": "(বছর নির্বাচন করুন)", + + // "browse.startsWith.choose_year.label": "Choose the issue year", + "browse.startsWith.choose_year.label": "ইস্যুর বছর নির্বাচন করুন", + + // "browse.startsWith.jump": "Jump to a point in the index:", + "browse.startsWith.jump": "সূচকের একটি পয়েন্টে যান:", + + // "browse.startsWith.months.april": "April", + "browse.startsWith.months.april": "এপ্রিল", + + // "browse.startsWith.months.august": "August", + "browse.startsWith.months.august": "আগস্ট", + + // "browse.startsWith.months.december": "December", + "browse.startsWith.months.december": "ডিসেম্বর", + + // "browse.startsWith.months.february": "February", + "browse.startsWith.months.february": "ফেব্রুয়ারি.", + + // "browse.startsWith.months.january": "January", + "browse.startsWith.months.january": "জানুয়ারি", + + // "browse.startsWith.months.july": "July", + "browse.startsWith.months.july": "জুলাই", + + // "browse.startsWith.months.june": "June", + "browse.startsWith.months.june": "জুন", + + // "browse.startsWith.months.march": "March", + "browse.startsWith.months.march": "মার্চ", + + // "browse.startsWith.months.may": "May", + "browse.startsWith.months.may": "মে", + + // "browse.startsWith.months.none": "(Choose month)", + "browse.startsWith.months.none": "(মাস নির্বাচন করুন)", + + // "browse.startsWith.months.none.label": "Choose the issue month", + "browse.startsWith.months.none.label": "ইস্যু মাস নির্বাচন করুন", + + // "browse.startsWith.months.november": "November", + "browse.startsWith.months.november": "নভেম্বর", + + // "browse.startsWith.months.october": "October", + "browse.startsWith.months.october": "অক্টোবর", + + // "browse.startsWith.months.september": "September", + "browse.startsWith.months.september": "সেপ্টেম্বর", + + // "browse.startsWith.submit": "Browse", + "browse.startsWith.submit": "ব্রাউজ", + + // "browse.startsWith.type_date": "Or type in a date (year-month) and click 'Browse'", + "browse.startsWith.type_date": "অথবা একটি তারিখ (বছরের-মাস) টাইপ করুন এবং 'ব্রাউজ' ক্লিক করুন", + + // "browse.startsWith.type_date.label": "Or type in a date (year-month) and click on the Browse button", + "browse.startsWith.type_date.label": "অথবা একটি তারিখ (বছরের-মাস) টাইপ করুন এবং ব্রাউজ বোতামে ক্লিক করুন", + + // "browse.startsWith.type_text": "Type the first few letters and click on the Browse button", + "browse.startsWith.type_text": "প্রথম কয়েকটি অক্ষর টাইপ করুন এবং ব্রাউজ বোতামে ক্লিক করুন", + + // "browse.title": "Browsing {{ collection }} by {{ field }} {{ value }}", + "browse.title": "ব্রাউজিং {{collection}} এর {{field}} {{value}}", + + + // "chips.remove": "Remove chip", + "chips.remove": "চিপ সরান", + + + + // "collection.create.head": "Create a Collection", + "collection.create.head": "একটি সংগ্রহ তৈরি করুন", + + // "collection.create.notifications.success": "Successfully created the Collection", + "collection.create.notifications.success": "সফলভাবে সংগ্রহ তৈরি", + + // "collection.create.sub-head": "Create a Collection for Community {{ parent }}", + "collection.create.sub-head": "সম্প্রদায়ের জন্য একটি সংগ্রহ তৈরি করুন {{praent}}", + + // "collection.curate.header": "Curate Collection: {{collection}}", + "collection.curate.header": "কিউরেট সংগ্রহ: {{collection}}", + + // "collection.delete.cancel": "Cancel", + "collection.delete.cancel": "বাতিল করুন", + + // "collection.delete.confirm": "Confirm", + "collection.delete.confirm": "নিশ্চিত করুন", + + // "collection.delete.processing": "Deleting", + "collection.delete.processing": "মুছে ফেলা হচ্ছে", + + // "collection.delete.head": "Delete Collection", + "collection.delete.head": "সংগ্রহ মুছে ফেলুন", + + // "collection.delete.notification.fail": "Collection could not be deleted", + "collection.delete.notification.fail": "সংগ্রহ মুছে ফেলা যাবে না", + + // "collection.delete.notification.success": "Successfully deleted collection", + "collection.delete.notification.success": "সফলভাবে মুছে ফেলা সংগ্রহ", + + // "collection.delete.text": "Are you sure you want to delete collection \"{{ dso }}\"", + "collection.delete.text": "আপনি কি আপনি সংগ্রহের মুছতে চান \"{{dos}}\"", + + + + // "collection.edit.delete": "Delete this collection", + "collection.edit.delete": "এই সংগ্রহ মুছে দিন", + + // "collection.edit.head": "Edit Collection", + "collection.edit.head": "সংগ্রহ সম্পাদনা", + + // "collection.edit.breadcrumbs": "Edit Collection", + "collection.edit.breadcrumbs": "সংগ্রহ সম্পাদনা", + + + + // "collection.edit.tabs.mapper.head": "Item Mapper", + "collection.edit.tabs.mapper.head": "আইটেম ম্যাপার", + + // "collection.edit.tabs.item-mapper.title": "Collection Edit - Item Mapper", + "collection.edit.tabs.item-mapper.title": "সংগ্রহ সম্পাদনা - আইটেম ম্যাপার", + + // "collection.edit.item-mapper.cancel": "Cancel", + "collection.edit.item-mapper.cancel": "বাতিল করুন", + + // "collection.edit.item-mapper.collection": "Collection: \"{{name}}\"", + "collection.edit.item-mapper.collection": "সংগ্রহ: \"{{name}}\"", + + // "collection.edit.item-mapper.confirm": "Map selected items", + "collection.edit.item-mapper.confirm": "নির্বাচিত আইটেম সমন্বয় করুন", + + // "collection.edit.item-mapper.description": "This is the item mapper tool that allows collection administrators to map items from other collections into this collection. You can search for items from other collections and map them, or browse the list of currently mapped items.", + "collection.edit.item-mapper.description": "এটি আইটেম ম্যাপার টুল যা সংগ্রহের অ্যাডমিনিস্ট্রেটররা এই সংগ্রহে অন্যান্য সংগ্রহ থেকে আইটেমগুলি মানচিত্রের অনুমতি দেয়। আপনি অন্যান্য সংগ্রহ থেকে আইটেমগুলি অনুসন্ধান করতে এবং তাদের মানচিত্র বা বর্তমানে ম্যাপযুক্ত আইটেমগুলির তালিকা ব্রাউজ করতে পারেন।", + + // "collection.edit.item-mapper.head": "Item Mapper - Map Items from Other Collections", + "collection.edit.item-mapper.head": "আইটেম ম্যাপার - অন্যান্য সংগ্রহ থেকে সমন্নয়কৃত আইটেম", + + // "collection.edit.item-mapper.no-search": "Please enter a query to search", + "collection.edit.item-mapper.no-search": "দয়া করে অনুসন্ধানের জন্য একটি কুয়েরি লিখুন ", + + // "collection.edit.item-mapper.notifications.map.error.content": "Errors occurred for mapping of {{amount}} items.", + "collection.edit.item-mapper.notifications.map.error.content": "{{amount}} আইটেমগুলির সমন্নয়য়ের জন্য ত্রুটি ঘটেছে।", + + // "collection.edit.item-mapper.notifications.map.error.head": "Mapping errors", + "collection.edit.item-mapper.notifications.map.error.head": "সমন্নয় ত্রুটি", + + // "collection.edit.item-mapper.notifications.map.success.content": "Successfully mapped {{amount}} items.", + "collection.edit.item-mapper.notifications.map.success.content": "সফলভাবে {{amount}} আইটেমগুলি ম্যাপ করা হয়েছে।", + + // "collection.edit.item-mapper.notifications.map.success.head": "Mapping completed", + "collection.edit.item-mapper.notifications.map.success.head": "সমন্নয় সম্পন্ন", + + // "collection.edit.item-mapper.notifications.unmap.error.content": "Errors occurred for removing the mappings of {{amount}} items.", + "collection.edit.item-mapper.notifications.unmap.error.content": "ত্রুটি {{amount}} আইটেমগুলির mappings অপসারণের জন্য ঘটেছে।", + + // "collection.edit.item-mapper.notifications.unmap.error.head": "Remove mapping errors", + "collection.edit.item-mapper.notifications.unmap.error.head": "সমন্নয় ত্রুটি মুছে ফেলুন", + + // "collection.edit.item-mapper.notifications.unmap.success.content": "Successfully removed the mappings of {{amount}} items.", + "collection.edit.item-mapper.notifications.unmap.success.content": "সফলভাবে {{amount}} আইটেমগুলির সমন্বয় সরানো হয়েছে।", + + // "collection.edit.item-mapper.notifications.unmap.success.head": "Remove mapping completed", + "collection.edit.item-mapper.notifications.unmap.success.head": "সমন্বয় সরানো সম্পন্ন হয়েছে", + + // "collection.edit.item-mapper.remove": "Remove selected item mappings", + "collection.edit.item-mapper.remove": "নির্বাচিত আইটেমের সমন্নয় মুছে ফেলুন", + + // "collection.edit.item-mapper.search-form.placeholder": "Search items...", + "collection.edit.item-mapper.search-form.placeholder": "অনুসন্ধান আইটেম ...", + + // "collection.edit.item-mapper.tabs.browse": "Browse mapped items", + "collection.edit.item-mapper.tabs.browse": "সমন্বিত আইটেম ব্রাউজ করুন", + + // "collection.edit.item-mapper.tabs.map": "Map new items", + "collection.edit.item-mapper.tabs.map": "নতুন আইটেম সমন্বয় করুন", + + + // "collection.edit.logo.delete.title": "Delete logo", + "collection.edit.logo.delete.title": "লোগো মুছে দিন", + + // "collection.edit.logo.delete-undo.title": "Undo delete", + "collection.edit.logo.delete-undo.title": "মুছে ফেলা মুছে ফেলুন", + + // "collection.edit.logo.label": "Collection logo", + "collection.edit.logo.label": "সংগ্রহ লোগো", + + // "collection.edit.logo.notifications.add.error": "Uploading Collection logo failed. Please verify the content before retrying.", + "collection.edit.logo.notifications.add.error": "সংগ্রহ লোগো আপলোডিং ব্যর্থ হয়েছে। পুনরায় চেষ্টা করার আগে কন্টেন্ট যাচাই করুন।", + + // "collection.edit.logo.notifications.add.success": "Upload Collection logo successful.", + "collection.edit.logo.notifications.add.success": "সংগ্রহের লোগো আপলোড সফল হয়েছে", + + // "collection.edit.logo.notifications.delete.success.title": "Logo deleted", + "collection.edit.logo.notifications.delete.success.title": "লোগো মুছে ফেলা হয়েছে", + + // "collection.edit.logo.notifications.delete.success.content": "Successfully deleted the collection's logo", + "collection.edit.logo.notifications.delete.success.content": "সফলভাবে সংগ্রহের লোগো মুছে ফেলা হয়েছে", + + // "collection.edit.logo.notifications.delete.error.title": "Error deleting logo", + "collection.edit.logo.notifications.delete.error.title": "লোগো মুছেতে ত্রুটি হয়েছে", + + // "collection.edit.logo.upload": "Drop a Collection Logo to upload", + "collection.edit.logo.upload": "আপলোড করার জন্য একটি সংগ্রহ লোগো ড্রপ করুন", + + + + // "collection.edit.notifications.success": "Successfully edited the Collection", + "collection.edit.notifications.success": "সফলভাবে সংগ্রহ সম্পাদনা", + + // "collection.edit.return": "Back", + "collection.edit.return": "পেছনে", + + + + // "collection.edit.tabs.curate.head": "Curate", + "collection.edit.tabs.curate.head": "কিউরেট", + + // "collection.edit.tabs.curate.title": "Collection Edit - Curate", + "collection.edit.tabs.curate.title": "সংগ্রহ সম্পাদনা - কিউরেট", + + // "collection.edit.tabs.authorizations.head": "Authorizations", + "collection.edit.tabs.authorizations.head": "অনুমোদনগুলো", + + // "collection.edit.tabs.authorizations.title": "Collection Edit - Authorizations", + "collection.edit.tabs.authorizations.title": "সংগ্রহ সম্পাদনা - অনুমোদনগুলো", + + // "collection.edit.tabs.metadata.head": "Edit Metadata", + "collection.edit.tabs.metadata.head": "মেটাডেটা সম্পাদনা করুন", + + // "collection.edit.tabs.metadata.title": "Collection Edit - Metadata", + "collection.edit.tabs.metadata.title": "সংগ্রহ সম্পাদনা - মেটাডাটা", + + // "collection.edit.tabs.roles.head": "Assign Roles", + "collection.edit.tabs.roles.head": "ভূমিকা (রোল) বরাদ্দ করুন", + + // "collection.edit.tabs.roles.title": "Collection Edit - Roles", + "collection.edit.tabs.roles.title": "সংগ্রহ সম্পাদনা - ভূমিকা", + + // "collection.edit.tabs.source.external": "This collection harvests its content from an external source", + "collection.edit.tabs.source.external": "এই সংগ্রহটি একটি বহিরাগত উৎস থেকে তার কন্টেন্ট সংগ্রহ করে", + + // "collection.edit.tabs.source.form.errors.oaiSource.required": "You must provide a set id of the target collection.", + "collection.edit.tabs.source.form.errors.oaiSource.required": "আপনার লক্ষ্যবস্তু সংগ্রহের একটি সেট আইডি প্রদান করতে হবে।", + + // "collection.edit.tabs.source.form.harvestType": "Content being harvested", + "collection.edit.tabs.source.form.harvestType": "বিষয়বস্তু সংগ্রহীত হয়েছে", + + // "collection.edit.tabs.source.form.head": "Configure an external source", + "collection.edit.tabs.source.form.head": "একটি বহিরাগত উৎস কনফিগার করুন", + + // "collection.edit.tabs.source.form.metadataConfigId": "Metadata Format", + "collection.edit.tabs.source.form.metadataConfigId": "মেটাডেটা বিন্যাস", + + // "collection.edit.tabs.source.form.oaiSetId": "OAI specific set id", + "collection.edit.tabs.source.form.oaiSetId": "OAI নির্দিষ্ট সেট আইডি", + + // "collection.edit.tabs.source.form.oaiSource": "OAI Provider", + "collection.edit.tabs.source.form.oaiSource": "OAI প্রদানকারী", + + // "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_BITSTREAMS": "Harvest metadata and bitstreams (requires ORE support)", + "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_BITSTREAMS": "সংগ্রহীত মেটাডাটা এবং বিটস্ট্রিমস (ORE সমর্থন প্রয়োজন)", + + // "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_REF": "Harvest metadata and references to bitstreams (requires ORE support)", + "collection.edit.tabs.source.form.options.harvestType.METADATA_AND_REF": "মেটাডাটা সংগ্রহ এবং বিটস্ট্রিমের রেফারেন্স (ORE সমর্থন প্রয়োজন)", + + // "collection.edit.tabs.source.form.options.harvestType.METADATA_ONLY": "Harvest metadata only", + "collection.edit.tabs.source.form.options.harvestType.METADATA_ONLY": "শুধুমাত্র মেটাডেটা সংগ্রহ করুন", + + // "collection.edit.tabs.source.head": "Content Source", + "collection.edit.tabs.source.head": "বিষয়বস্তু উৎস", + + // "collection.edit.tabs.source.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + "collection.edit.tabs.source.notifications.discarded.content": "আপনার পরিবর্তন বাতিল করা হয়েছে। আপনার পরিবর্তনগুলি পুনঃস্থাপন করতে 'পূর্বাবস্থায় ফিরুন' বাটনে ক্লিক করুন", + + // "collection.edit.tabs.source.notifications.discarded.title": "Changed discarded", + "collection.edit.tabs.source.notifications.discarded.title": "বাতিলকৃত পরিবর্তন", + + // "collection.edit.tabs.source.notifications.invalid.content": "Your changes were not saved. Please make sure all fields are valid before you save.", + "collection.edit.tabs.source.notifications.invalid.content": "আপনার পরিবর্তন সংরক্ষিত ছিল না। আপনি সংরক্ষণ করার আগে সমস্ত ক্ষেত্রের বৈধতা নিশ্চিত করুন দয়া করে।", + + // "collection.edit.tabs.source.notifications.invalid.title": "Metadata invalid", + "collection.edit.tabs.source.notifications.invalid.title": "মেটাডেটা অবৈধ", + + // "collection.edit.tabs.source.notifications.saved.content": "Your changes to this collection's content source were saved.", + "collection.edit.tabs.source.notifications.saved.content": "সংগ্রহগুলোর কন্টেন্টের উৎসে আপনার পরিবর্তনগুলো সংরক্ষিত ছিল।", + + // "collection.edit.tabs.source.notifications.saved.title": "Content Source saved", + "collection.edit.tabs.source.notifications.saved.title": "বিষয়বস্তু উৎস সংরক্ষিত হয়েছে", + + // "collection.edit.tabs.source.title": "Collection Edit - Content Source", + "collection.edit.tabs.source.title": "সংগ্রহ সম্পাদনা - কন্টেন্ট উৎস", + + + + // "collection.edit.template.add-button": "Add", + "collection.edit.template.add-button": "যোগ করুন", + + // "collection.edit.template.breadcrumbs": "Item template", + "collection.edit.template.breadcrumbs": "আইটেম টেমপ্লেট", + + // "collection.edit.template.cancel": "Cancel", + "collection.edit.template.cancel": "বাতিল করুন", + + // "collection.edit.template.delete-button": "Delete", + "collection.edit.template.delete-button": "মুছে ফেলা", + + // "collection.edit.template.edit-button": "Edit", + "collection.edit.template.edit-button": "সম্পাদনা করুন", + + // "collection.edit.template.error": "An error occurred retrieving the template item", + "collection.edit.template.error": "টেমপ্লেট আইটেম পুনরুদ্ধার করার সময় একটি ত্রুটি ঘটেছে৷", + + // "collection.edit.template.head": "Edit Template Item for Collection \"{{ collection }}\"", + "collection.edit.template.head": "সংগ্রহের জন্য টেমপ্লেট আইটেমটি সম্পাদনা করুন \"{{ collection }}\"", + + // "collection.edit.template.label": "Template item", + "collection.edit.template.label": "টেমপ্লেট আইটেম", + + // "collection.edit.template.loading": "Loading template item...", + "collection.edit.template.loading": "টেমপ্লেট আইটেম লোড হচ্ছে ...", + + // "collection.edit.template.notifications.delete.error": "Failed to delete the item template", + "collection.edit.template.notifications.delete.error": "আইটেম টেমপ্লেট মুছে ফেলতে ব্যর্থ হয়েছে", + + // "collection.edit.template.notifications.delete.success": "Successfully deleted the item template", + "collection.edit.template.notifications.delete.success": "সফলভাবে আইটেম টেমপ্লেট মুছে ফেলা হয়েছে", + + // "collection.edit.template.title": "Edit Template Item", + "collection.edit.template.title": "টেমপ্লেট আইটেম সম্পাদনা করুন", + + + + // "collection.form.abstract": "Short Description", + "collection.form.abstract": "ছোট বিবরণ", + + // "collection.form.description": "Introductory text (HTML)", + "collection.form.description": "প্রারম্ভিক টেক্সট (এইচটিএমএল)", + + // "collection.form.errors.title.required": "Please enter a collection name", + "collection.form.errors.title.required": "দয়া করে একটি সংগ্রহ নাম লিখুন", + + // "collection.form.license": "License", + "collection.form.license": "লাইসেন্স", + + // "collection.form.provenance": "Provenance", + "collection.form.provenance": "উদ্ভব", + + // "collection.form.rights": "Copyright text (HTML)", + "collection.form.rights": "কপিরাইট টেক্সট (এইচটিএমএল)", + + // "collection.form.tableofcontents": "News (HTML)", + "collection.form.tableofcontents": "সংবাদ (এইচটিএমএল)", + + // "collection.form.title": "Name", + "collection.form.title": "নাম", + + // "collection.form.entityType": "Entity Type", + "collection.form.entityType": "এনটিটির (সত্তা) ধরন", + + + + // "collection.listelement.badge": "Collection", + "collection.listelement.badge": "সংগ্রহ", + + + + // "collection.page.browse.recent.head": "Recent Submissions", + "collection.page.browse.recent.head": "সাম্প্রতিক জমা", + + // "collection.page.browse.recent.empty": "No items to show", + "collection.page.browse.recent.empty": "দেখানোর মত কোন আইটেম নেই", + + // "collection.page.edit": "Edit this collection", + "collection.page.edit": "এই সংগ্রহটি সম্পাদনা করুন", + + // "collection.page.handle": "Permanent URI for this collection", + "collection.page.handle": "এই সংগ্রহের জন্য স্থায়ী URI", + + // "collection.page.license": "License", + "collection.page.license": "লাইসেন্স", + + // "collection.page.news": "News", + "collection.page.news": "সংবাদ", + + + + // "collection.select.confirm": "Confirm selected", + "collection.select.confirm": "সিলেকশন নিশ্চিত করুন", + + // "collection.select.empty": "No collections to show", + "collection.select.empty": "দেখানোর মত কোন সংগ্রহ নেই", + + // "collection.select.table.title": "Title", + "collection.select.table.title": "শিরোনাম", + + + // "collection.source.controls.head": "Harvest Controls", + "collection.source.controls.head": "সংগ্রহের নিয়ন্ত্রণ", + // "collection.source.controls.test.submit.error": "Something went wrong with initiating the testing of the settings", + "collection.source.controls.test.submit.error": "সেটিংসের পরীক্ষা শুরু করার সময় কিছু ভুল হয়েছে", + // "collection.source.controls.test.failed": "The script to test the settings has failed", + "collection.source.controls.test.failed": "সেটিংস পরীক্ষা করার জন্য স্ক্রিপ্ট ব্যর্থ হয়েছে", + // "collection.source.controls.test.completed": "The script to test the settings has successfully finished", + "collection.source.controls.test.completed": "সেটিংস পরীক্ষা করার জন্য স্ক্রিপ্ট সফলভাবে শেষ হয়েছে", + // "collection.source.controls.test.submit": "Test configuration", + "collection.source.controls.test.submit": "পরীক্ষা কনফিগারেশন", + // "collection.source.controls.test.running": "Testing configuration...", + "collection.source.controls.test.running": "কনফিগারেশন পরীক্ষা করা হচ্ছে...", + // "collection.source.controls.import.submit.success": "The import has been successfully initiated", + "collection.source.controls.import.submit.success": "আমদানি সফলভাবে শুরু করা হয়েছে", + // "collection.source.controls.import.submit.error": "Something went wrong with initiating the import", + "collection.source.controls.import.submit.error": "আমদানি শুরু সময় কিছু ভুল হয়েছে", + // "collection.source.controls.import.submit": "Import now", + "collection.source.controls.import.submit": "এখন আমদানি করুন", + // "collection.source.controls.import.running": "Importing...", + "collection.source.controls.import.running": "আমদানি করা হচ্ছে ...", + // "collection.source.controls.import.failed": "An error occurred during the import", + "collection.source.controls.import.failed": "আমদানি সময় একটি ত্রুটি ঘটেছে", + // "collection.source.controls.import.completed": "The import completed", + "collection.source.controls.import.completed": "আমদানি সম্পন্ন হয়েছে", + // "collection.source.controls.reset.submit.success": "The reset and reimport has been successfully initiated", + "collection.source.controls.reset.submit.success": "রিসেট এবং পুনরাই আমদানি সফলভাবে শুরু করা হয়েছে", + // "collection.source.controls.reset.submit.error": "Something went wrong with initiating the reset and reimport", + "collection.source.controls.reset.submit.error": "রিসেট এবং পুনরাই আমদানি শুরু সময় কিছু ভুল হয়েছে", + // "collection.source.controls.reset.failed": "An error occurred during the reset and reimport", + "collection.source.controls.reset.failed": "রিসেট এবং পুনরাই আমদানি সময় কিছু ভুল হয়েছে", + // "collection.source.controls.reset.completed": "The reset and reimport completed", + "collection.source.controls.reset.completed": "রিসেট এবং পুনরাই আমদানি সম্পন্ন", + // "collection.source.controls.reset.submit": "Reset and reimport", + "collection.source.controls.reset.submit": "রিসেট এবং পুনরাই আমদানি সম্পন্ন.", + // "collection.source.controls.reset.running": "Resetting and reimporting...", + "collection.source.controls.reset.running": "রিসেটিং এবং পুনরাই আমদানি চলছে...", + // "collection.source.controls.harvest.status": "Harvest status:", + "collection.source.controls.harvest.status": "সংগ্রহের অবস্থা:", + // "collection.source.controls.harvest.start": "Harvest start time:", + "collection.source.controls.harvest.start": "সংগ্রহ শুরুর সময়:", + // "collection.source.controls.harvest.last": "Last time harvested:", + "collection.source.controls.harvest.last": "শেশবারের মত সংগ্রহীত:", + // "collection.source.controls.harvest.message": "Harvest info:", + "collection.source.controls.harvest.message": "সংগ্রহের তথ্য:", + // "collection.source.controls.harvest.no-information": "N/A", + "collection.source.controls.harvest.no-information": "এন/এ", + + + // "collection.source.update.notifications.error.content": "The provided settings have been tested and didn't work.", + "collection.source.update.notifications.error.content": "প্রদত্ত সেটিংস পরীক্ষা করা হয়েছে এবং কাজ করে না।", + + // "collection.source.update.notifications.error.title": "Server Error", + "collection.source.update.notifications.error.title": "সার্ভার সমস্যা", + + + + // "communityList.breadcrumbs": "Community List", + "communityList.breadcrumbs": "কমিউনিটির তালিকা", + + // "communityList.tabTitle": "Community List", + "communityList.tabTitle": "কমিউনিটির তালিকা", + + // "communityList.title": "List of Communities", + "communityList.title": "সম্প্রদায়ের তালিকা", + + // "communityList.showMore": "Show More", + "communityList.showMore": "আরো দেখুন", + + + + // "community.create.head": "Create a Community", + "community.create.head": "একটি সম্প্রদায় তৈরি করুন", + + // "community.create.notifications.success": "Successfully created the Community", + "community.create.notifications.success": "সফলভাবে সম্প্রদায় তৈরি হয়েছে", + + // "community.create.sub-head": "Create a Sub-Community for Community {{ parent }}", + "community.create.sub-head": "সম্প্রদায়ের জন্য একটি উপ-সম্প্রদায় তৈরি করুন {{praent}}", + + // "community.curate.header": "Curate Community: {{community}}", + "community.curate.header": "কিউরেট সম্প্রদায়: {{community}}", + + // "community.delete.cancel": "Cancel", + "community.delete.cancel": "বাতিল করুন", + + // "community.delete.confirm": "Confirm", + "community.delete.confirm": "নিশ্চিত করুন", + + // "community.delete.processing": "Deleting...", + "community.delete.processing": "মুছে ফেলা হচ্ছে ...", + + // "community.delete.head": "Delete Community", + "community.delete.head": "কমিউনিটি মুছুন", + + // "community.delete.notification.fail": "Community could not be deleted", + "community.delete.notification.fail": "সম্প্রদায় মুছে ফেলা যাবে না", + + // "community.delete.notification.success": "Successfully deleted community", + "community.delete.notification.success": "সফলভাবে মুছে ফেলা সম্প্রদায়", + + // "community.delete.text": "Are you sure you want to delete community \"{{ dso }}\"", + "community.delete.text": "আপনি কি নিশ্চিত যে আপনি কমিউনিটি মুছে ফেলতে চান \"{{dso}}}\"", + + // "community.edit.delete": "Delete this community", + "community.edit.delete": "এই সম্প্রদায় মুছে ফেলুন", + + // "community.edit.head": "Edit Community", + "community.edit.head": "সম্প্রদায় সম্পাদনা করুন", + + // "community.edit.breadcrumbs": "Edit Community", + "community.edit.breadcrumbs": "সম্প্রদায় সম্পাদনা করুন", + + + // "community.edit.logo.delete.title": "Delete logo", + "community.edit.logo.delete.title": "লোগো মুছে ফেলুন", + + // "community.edit.logo.delete-undo.title": "Undo delete", + "community.edit.logo.delete-undo.title": "মুছে ফেলা বাতিল করুন", + + // "community.edit.logo.label": "Community logo", + "community.edit.logo.label": "কমিউনিটি লোগো", + + // "community.edit.logo.notifications.add.error": "Uploading Community logo failed. Please verify the content before retrying.", + "community.edit.logo.notifications.add.error": "কমিউনিটি লোগো আপলোড ব্যর্থ হয়েছে। পুনরায় চেষ্টা করার আগে কন্টেন্ট যাচাই করুন।", + + // "community.edit.logo.notifications.add.success": "Upload Community logo successful.", + "community.edit.logo.notifications.add.success": "কমিউনিটি লোগো সফল আপলোড করুন।", + + // "community.edit.logo.notifications.delete.success.title": "Logo deleted", + "community.edit.logo.notifications.delete.success.title": "লোগো মুছে ফেলা হয়েছে", + + // "community.edit.logo.notifications.delete.success.content": "Successfully deleted the community's logo", + "community.edit.logo.notifications.delete.success.content": "সফলভাবে সম্প্রদায়ের লোগো মুছে ফেলা হয়েছে", + + // "community.edit.logo.notifications.delete.error.title": "Error deleting logo", + "community.edit.logo.notifications.delete.error.title": "লোগো মুছে ফেলতে ত্রুটি হয়েছে", + + // "community.edit.logo.upload": "Drop a Community Logo to upload", + "community.edit.logo.upload": "আপলোড করার জন্য একটি কমিউনিটি লোগো ড্রপ করুন", + + + + // "community.edit.notifications.success": "Successfully edited the Community", + "community.edit.notifications.success": "সফলভাবে সম্প্রদায় সম্পাদনা", + + // "community.edit.notifications.unauthorized": "You do not have privileges to make this change", + "community.edit.notifications.unauthorized": "এই পরিবর্তন করতে আপনার বিশেষাধিকার নেই", + + // "community.edit.notifications.error": "An error occured while editing the Community", + "community.edit.notifications.error": "সম্প্রদায় সম্পাদনা করার সময় একটি ত্রুটি ঘটেছে", + + // "community.edit.return": "Back", + "community.edit.return": "পেছনে", + + + + // "community.edit.tabs.curate.head": "Curate", + "community.edit.tabs.curate.head": "কিউরেট", + + // "community.edit.tabs.curate.title": "Community Edit - Curate", + "community.edit.tabs.curate.title": "কমিউনিটি সম্পাদনা - কিউরেট", + + // "community.edit.tabs.metadata.head": "Edit Metadata", + "community.edit.tabs.metadata.head": "মেটাডেটা সম্পাদনা করুন", + + // "community.edit.tabs.metadata.title": "Community Edit - Metadata", + "community.edit.tabs.metadata.title": "কমিউনিটি সম্পাদনা - মেটাডাটা", + + // "community.edit.tabs.roles.head": "Assign Roles", + "community.edit.tabs.roles.head": "ভূমিকা (রোল) বরাদ্দ করুন", + + // "community.edit.tabs.roles.title": "Community Edit - Roles", + "community.edit.tabs.roles.title": "কমিউনিটি সম্পাদনা - ভূমিকা (রোল)", + + // "community.edit.tabs.authorizations.head": "Authorizations", + "community.edit.tabs.authorizations.head": "অনুমোদনসমূহ", + + // "community.edit.tabs.authorizations.title": "Community Edit - Authorizations", + "community.edit.tabs.authorizations.title": "কমিউনিটি সম্পাদনা - অনুমোদনসমূহ", + + + + // "community.listelement.badge": "Community", + "community.listelement.badge": "সম্প্রদায়", + + + + // "comcol-role.edit.no-group": "None", + "comcol-role.edit.no-group": "কেউ না", + + // "comcol-role.edit.create": "Create", + "comcol-role.edit.create": "সৃষ্টি", + + // "comcol-role.edit.restrict": "Restrict", + "comcol-role.edit.restrict": "সীমাবদ্ধতা", + + // "comcol-role.edit.delete": "Delete", + "comcol-role.edit.delete": "মুছে ফেলা", + + + // "comcol-role.edit.community-admin.name": "Administrators", + "comcol-role.edit.community-admin.name": "প্রশাসক", + + // "comcol-role.edit.collection-admin.name": "Administrators", + "comcol-role.edit.collection-admin.name": "প্রশাসক", + + + // "comcol-role.edit.community-admin.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", + "comcol-role.edit.community-admin.description": "কমিউনিটি অ্যাডমিনিস্ট্রেটররা উপ-সম্প্রদায়গুলি বা সংগ্রহগুলি তৈরি করতে পারে এবং সেই উপ-সম্প্রদায়গুলির বা সংগ্রহগুলির জন্য পরিচালনা বা পরিচালনা করতে পারে। উপরন্তু তারা যে কোনও উপ-সংগ্রহগুলিতে আইটেম জমা দিতে পারে তা মেটাডেটা (জমা দেওয়ার পরে) এবং অন্যান্য সংগ্রহগুলির (মানচিত্র) বিদ্যমান আইটেমগুলি (অনুমোদন সাপেক্ষে) যোগ করতে পারে তা নির্ধারণ করে।", + + // "comcol-role.edit.collection-admin.description": "Collection administrators decide who can submit items to the collection, edit item metadata (after submission), and add (map) existing items from other collections to this collection (subject to authorization for that collection).", + "comcol-role.edit.collection-admin.description": "সংগ্রহ অ্যাডমিনিস্ট্রেটররা সিদ্ধান্ত নেয় কে আইটেমটি মেটাডেটা (জমা দেওয়ার পরে) সম্পাদনা করতে এবং এই সংগ্রহে অন্যান্য সংগ্রহ থেকে বিদ্যমান আইটেমগুলি যোগ করুন (মানচিত্র) বিদ্যমান আইটেমগুলি হতে অন্নে সংগ্রহওগুলো (অনুমোদন সাপেক্ষে)।", + + + // "comcol-role.edit.submitters.name": "Submitters", + "comcol-role.edit.submitters.name": "জমাকারীরা", + + // "comcol-role.edit.submitters.description": "The E-People and Groups that have permission to submit new items to this collection.", + "comcol-role.edit.submitters.description": "এই সংগ্রহে নতুন আইটেম জমা দেওয়ার অনুমতি আছে এমন ই-ব্যাক্তি এবং গোষ্ঠী।", + + + // "comcol-role.edit.item_read.name": "Default item read access", + "comcol-role.edit.item_read.name": "ডিফল্ট আইটেম পড়ার অ্যাক্সেস", + + // "comcol-role.edit.item_read.description": "E-People and Groups that can read new items submitted to this collection. Changes to this role are not retroactive. Existing items in the system will still be viewable by those who had read access at the time of their addition.", + "comcol-role.edit.item_read.description": "ই-ব্যাক্তি এবং গোষ্ঠী যা এই সংগ্রহে জমা দেওয়া নতুন আইটেমগুলি পড়তে পারে। এই ভূমিকা পরিবর্তন retroactive হয় না। সিস্টেমের বিদ্যমান আইটেমগুলি এখনও তাদের সংযোজনের সময় অ্যাক্সেস পড়তে যারা দ্বারা দর্শনীয় হবে।", + + // "comcol-role.edit.item_read.anonymous-group": "Default read for incoming items is currently set to Anonymous.", + "comcol-role.edit.item_read.anonymous-group": "ইনকামিং আইটেম জন্য ডিফল্ট পড়ুন বর্তমানে বেনামী সেট করা হয়।", + + + // "comcol-role.edit.bitstream_read.name": "Default bitstream read access", + "comcol-role.edit.bitstream_read.name": "ডিফল্ট বিটস্ট্রিম পড়ার অ্যাক্সেস", + + // "comcol-role.edit.bitstream_read.description": "Community administrators can create sub-communities or collections, and manage or assign management for those sub-communities or collections. In addition, they decide who can submit items to any sub-collections, edit item metadata (after submission), and add (map) existing items from other collections (subject to authorization).", + "comcol-role.edit.bitstream_read.description": "কমিউনিটি অ্যাডমিনিস্ট্রেটররা উপ-সম্প্রদায়গুলি বা সংগ্রহগুলি তৈরি করতে পারে এবং সেই উপ-সম্প্রদায়গুলির বা সংগ্রহগুলির জন্য পরিচালনা বা পরিচালনা করতে পারে। উপরন্তু তারা যে কোনও উপ-সংগ্রহগুলিতে আইটেম জমা দিতে পারে তা মেটাডেটা (জমা দেওয়ার পরে) এবং অন্যান্য সংগ্রহগুলির (মানচিত্র) বিদ্যমান আইটেমগুলি (অনুমোদন সাপেক্ষে) যোগ করতে পারে তা নির্ধারণ করে।", + + // "comcol-role.edit.bitstream_read.anonymous-group": "Default read for incoming bitstreams is currently set to Anonymous.", + "comcol-role.edit.bitstream_read.anonymous-group": "ইনকামিং বিটস্ট্রিমের জন্য ডিফল্ট রিড বর্তমানে বেনামীতে সেট করা আছে", + + + // "comcol-role.edit.editor.name": "Editors", + "comcol-role.edit.editor.name": "সম্পাদক", + + // "comcol-role.edit.editor.description": "Editors are able to edit the metadata of incoming submissions, and then accept or reject them.", + "comcol-role.edit.editor.description": "সম্পাদকগণ ইনকামিং জমা মেটাডেটা সম্পাদনা করতে সক্ষম এবং তারপর তাদের গ্রহণ বা প্রত্যাখ্যান করতে পারবেন।", + + + // "comcol-role.edit.finaleditor.name": "Final editors", + "comcol-role.edit.finaleditor.name": "চূড়ান্ত সম্পাদক", + + // "comcol-role.edit.finaleditor.description": "Final editors are able to edit the metadata of incoming submissions, but will not be able to reject them.", + "comcol-role.edit.finaleditor.description": "চূড়ান্ত সম্পাদকরা ইনকামিং জমা মেটাডেটা সম্পাদনা করতে সক্ষম কিন্তু তাদের প্রত্যাখ্যান করতে সক্ষম হবে না।", + + + // "comcol-role.edit.reviewer.name": "Reviewers", + "comcol-role.edit.reviewer.name": "সমালোচকগন", + + // "comcol-role.edit.reviewer.description": "Reviewers are able to accept or reject incoming submissions. However, they are not able to edit the submission's metadata.", + "comcol-role.edit.reviewer.description": "সমালোচকরা ইনকামিং জমা গ্রহণ বা প্রত্যাখ্যান করতে পারবেন। তবে তারা জমা দেওয়া মেটাডেটা সম্পাদনা করতে পারবেন না।", + + + + // "community.form.abstract": "Short Description", + "community.form.abstract": "ছোট বিবরণ", + + // "community.form.description": "Introductory text (HTML)", + "community.form.description": "প্রারম্ভিক টেক্সট (এইচটিএমএল)", + + // "community.form.errors.title.required": "Please enter a community name", + "community.form.errors.title.required": "একটি সম্প্রদায়ের নাম লিখুন দয়া করে", + + // "community.form.rights": "Copyright text (HTML)", + "community.form.rights": "কপিরাইট টেক্সট (এইচটিএমএল)", + + // "community.form.tableofcontents": "News (HTML)", + "community.form.tableofcontents": "সংবাদ (এইচটিএমএল)", + + // "community.form.title": "Name", + "community.form.title": "নাম", + + // "community.page.edit": "Edit this community", + "community.page.edit": "এই সম্প্রদায়টি সম্পাদনা করুন", + + // "community.page.handle": "Permanent URI for this community", + "community.page.handle": "এই সম্প্রদায়ের জন্য স্থায়ী URI", + + // "community.page.license": "License", + "community.page.license": "লাইসেন্স", + + // "community.page.news": "News", + "community.page.news": "সংবাদ", + + // "community.all-lists.head": "Subcommunities and Collections", + "community.all-lists.head": "উপ-সম্প্রদায় এবং সংগ্রহ", + + // "community.sub-collection-list.head": "Collections of this Community", + "community.sub-collection-list.head": "এই সম্প্রদায়ের সংগ্রহ", + + // "community.sub-community-list.head": "Communities of this Community", + "community.sub-community-list.head": "এই সম্প্রদায়ের সম্প্রদায়", + + + + // "cookies.consent.accept-all": "Accept all", + "cookies.consent.accept-all": "সব গ্রহণ করুন", + + // "cookies.consent.accept-selected": "Accept selected", + "cookies.consent.accept-selected": "নির্বাচিতটা গ্রহণ করুন", + + // "cookies.consent.app.opt-out.description": "This app is loaded by default (but you can opt out)", + "cookies.consent.app.opt-out.description": "এই অ্যাপ্লিকেশনটি ডিফল্টরূপে লোড করা হয় (তবে আপনি অপ্ট আউট করতে পারেন)", + + // "cookies.consent.app.opt-out.title": "(opt-out)", + "cookies.consent.app.opt-out.title": "(অপ্ট আউট)", + + // "cookies.consent.app.purpose": "purpose", + "cookies.consent.app.purpose": "উদ্দেশ্য", + + // "cookies.consent.app.required.description": "This application is always required", + "cookies.consent.app.required.description": "এই অ্যাপ্লিকেশন সবসময় প্রয়োজন হয়", + + // "cookies.consent.app.required.title": "(always required)", + "cookies.consent.app.required.title": "(সর্বদা প্রয়োজন)", + + // "cookies.consent.update": "There were changes since your last visit, please update your consent.", + "cookies.consent.update": "আপনার শেষ পরিদর্শন থেকে পরিবর্তন হয়েছে দয়া করে আপনার সম্মতি আপডেট করুন।", + + // "cookies.consent.close": "Close", + "cookies.consent.close": "বন্ধ", + + // "cookies.consent.decline": "Decline", + "cookies.consent.decline": "পতন", + + // "cookies.consent.content-notice.description": "We collect and process your personal information for the following purposes: Authentication, Preferences, Acknowledgement and Statistics.
To learn more, please read our {privacyPolicy}.", + "cookies.consent.content-notice.description": "আমরা নিম্নলিখিত উদ্দেশ্যে আপনার ব্যক্তিগত তথ্য সংগ্রহ এবং প্রক্রিয়া করি: প্রমাণিকরণ, পছন্দ, স্বীকৃতি এবং পরিসংখ্যান
আরও জানতে, অনুগ্রহ করে আমাদের {privacyPolicy} পড়ুন.", + + // "cookies.consent.content-notice.learnMore": "Customize", + "cookies.consent.content-notice.learnMore": "কাস্টমাইজ করুন", + + // "cookies.consent.content-modal.description": "Here you can see and customize the information that we collect about you.", + "cookies.consent.content-modal.description": "এখানে আপনি আপনার সম্পর্কে সংগৃহীত তথ্যটি দেখতে এবং কাস্টমাইজ করতে পারেন।", + + // "cookies.consent.content-modal.privacy-policy.name": "privacy policy", + "cookies.consent.content-modal.privacy-policy.name": "গোপনীয়তা নীতি", + + // "cookies.consent.content-modal.privacy-policy.text": "To learn more, please read our {privacyPolicy}.", + "cookies.consent.content-modal.privacy-policy.text": "আরো জানতে, আমাদের {privacyPolicy} পড়ুন.", + + // "cookies.consent.content-modal.title": "Information that we collect", + "cookies.consent.content-modal.title": "আমরা যে তথ্য সংগ্রহ করি", + + + + // "cookies.consent.app.title.authentication": "Authentication", + "cookies.consent.app.title.authentication": "প্রমাণীকরণ", + + // "cookies.consent.app.description.authentication": "Required for signing you in", + "cookies.consent.app.description.authentication": "আপনার সাইন ইন করার জন্য প্রয়োজন", + + + // "cookies.consent.app.title.preferences": "Preferences", + "cookies.consent.app.title.preferences": "পছন্দসমূহ", + + // "cookies.consent.app.description.preferences": "Required for saving your preferences", + "cookies.consent.app.description.preferences": "আপনার পছন্দ সংরক্ষণের জন্য প্রয়োজন", + + + + // "cookies.consent.app.title.acknowledgement": "Acknowledgement", + "cookies.consent.app.title.acknowledgement": "স্বীকৃতি", + + // "cookies.consent.app.description.acknowledgement": "Required for saving your acknowledgements and consents", + "cookies.consent.app.description.acknowledgement": "আপনার স্বীকৃতি এবং সম্মতি সংরক্ষণের জন্য প্রয়োজন", + + + + // "cookies.consent.app.title.google-analytics": "Google Analytics", + "cookies.consent.app.title.google-analytics": "গুগল বিশ্লেষক", + + // "cookies.consent.app.description.google-analytics": "Allows us to track statistical data", + "cookies.consent.app.description.google-analytics": "আমাদের পরিসংখ্যানগত ডেটা ট্র্যাক করার অনুমতি দিন", + + + + // "cookies.consent.purpose.functional": "Functional", + "cookies.consent.purpose.functional": "কার্যকরী", + + // "cookies.consent.purpose.statistical": "Statistical", + "cookies.consent.purpose.statistical": "পরিসংখ্যানগত", + + + // "curation-task.task.checklinks.label": "Check Links in Metadata", + "curation-task.task.checklinks.label": "মেটাডেটা লিঙ্ক চেক করুন", + + // "curation-task.task.noop.label": "NOOP", + "curation-task.task.noop.label": "না", + + // "curation-task.task.profileformats.label": "Profile Bitstream Formats", + "curation-task.task.profileformats.label": "প্রোফাইলের বিটস্ট্রিম ফরম্যাট", + + // "curation-task.task.requiredmetadata.label": "Check for Required Metadata", + "curation-task.task.requiredmetadata.label": "প্রয়োজনীয় মেটাডেটা জন্য চেক করুন", + + // "curation-task.task.translate.label": "Microsoft Translator", + "curation-task.task.translate.label": "মাইক্রোসফ্ট অনুবাদক", + + // "curation-task.task.vscan.label": "Virus Scan", + "curation-task.task.vscan.label": "ভাইরাস স্ক্যান", + + + + // "curation.form.task-select.label": "Task:", + "curation.form.task-select.label": "টাস্ক:", + + // "curation.form.submit": "Start", + "curation.form.submit": "শুরু করুন", + + // "curation.form.submit.success.head": "The curation task has been started successfully", + "curation.form.submit.success.head": "কিউরেসনের কাজ সফলভাবে শুরু করা হয়েছে", + + // "curation.form.submit.success.content": "You will be redirected to the corresponding process page.", + "curation.form.submit.success.content": "আপনি সংশ্লিষ্ট প্রক্রিয়া পৃষ্ঠায় পুনঃনির্দেশিত করা হবে।", + + // "curation.form.submit.error.head": "Running the curation task failed", + "curation.form.submit.error.head": "চলমান কিউরেসনের কাজ ব্যর্থ হয়েছে", + + // "curation.form.submit.error.content": "An error occured when trying to start the curation task.", + "curation.form.submit.error.content": "কিউরেসনের কাজ শুরু করার চেষ্টা করার সময় একটি ত্রুটি ঘটেছে।", + + // "curation.form.handle.label": "Handle:", + "curation.form.handle.label": "হ্যান্ডেল:", + + // "curation.form.handle.hint": "Hint: Enter [your-handle-prefix]/0 to run a task across entire site (not all tasks may support this capability)", + "curation.form.handle.hint": "ইঙ্গিত: সমগ্র সাইট জুড়ে একটি টাস্ক চালানোর জন্য [your-handle-prefix]/0 লিখুন (সব কাজ এই ক্ষমতা সমর্থন করতে পারে না)", + + + + // "deny-request-copy.email.message": "Dear {{ recipientName }},\nIn response to your request I regret to inform you that it's not possible to send you a copy of the file(s) you have requested, concerning the document: \"{{ itemUrl }}\" ({{ itemName }}), of which I am an author.\n\nBest regards,\n{{ authorName }} <{{ authorEmail }}>", + "deny-request-copy.email.message": "প্রিয় {{ recipientName }},\nআপনার অনুরোধের জবাবে আমি আপনাকে জানাতে দুঃখিত যে নথির বিষয়ে আপনার অনুরোধ করা ফাইল(গুলি) এর একটি অনুলিপি পাঠানো সম্ভব নয়: \"{{itemUrl }}\" ({{ itemName }}), যার আমি একজন লেখক।\n\nশুভেচ্ছা,\n{{ authorName }} <{{ authorEmail }}>", + + // "deny-request-copy.email.subject": "Request copy of document", + "deny-request-copy.email.subject": "নথির কপি অনুরোধ", + + // "deny-request-copy.error": "An error occurred", + "deny-request-copy.error": "একটি ত্রুটি ঘটেছে", + + // "deny-request-copy.header": "Deny document copy request", + "deny-request-copy.header": "নথি অনুলিপি অনুরোধ অস্বীকার করুন", + + // "deny-request-copy.intro": "This message will be sent to the applicant of the request", + "deny-request-copy.intro": "এই বার্তাটি অনুরোধের আবেদনকারীর কাছে পাঠানো হবে", + + // "deny-request-copy.success": "Successfully denied item request", + "deny-request-copy.success": "সফলভাবে আইটেম অনুরোধ অস্বীকার", + + + + // "dso.name.untitled": "Untitled", + "dso.name.untitled": "শিরোনামহীন", + + + + // "dso-selector.create.collection.head": "New collection", + "dso-selector.create.collection.head": "নতুন সংগ্রহ", + + // "dso-selector.create.collection.sub-level": "Create a new collection in", + "dso-selector.create.collection.sub-level": "একটি নতুন সংগ্রহ তৈরি করুন", + + // "dso-selector.create.community.head": "New community", + "dso-selector.create.community.head": "নতুন সম্প্রদায়", + + // "dso-selector.create.community.sub-level": "Create a new community in", + "dso-selector.create.community.sub-level": "একটি নতুন সম্প্রদায় তৈরি করুন", + + // "dso-selector.create.community.top-level": "Create a new top-level community", + "dso-selector.create.community.top-level": "একটি নতুন শীর্ষ স্তরের সম্প্রদায় তৈরি করুন", + + // "dso-selector.create.item.head": "New item", + "dso-selector.create.item.head": "নতুন আইটেম", + + // "dso-selector.create.item.sub-level": "Create a new item in", + "dso-selector.create.item.sub-level": "একটি নতুন আইটেম তৈরি করুন", + + // "dso-selector.create.submission.head": "New submission", + "dso-selector.create.submission.head": "নতুন জমা", + + // "dso-selector.edit.collection.head": "Edit collection", + "dso-selector.edit.collection.head": "সংগ্রহ সম্পাদনা", + + // "dso-selector.edit.community.head": "Edit community", + "dso-selector.edit.community.head": "সম্প্রদায় সম্পাদনা করুন", + + // "dso-selector.edit.item.head": "Edit item", + "dso-selector.edit.item.head": "আইটেম সম্পাদনা করুন", + + // "dso-selector.error.title": "An error occurred searching for a {{ type }}", + "dso-selector.error.title": "একটি {{type}} অনুসন্ধানের জন্য একটি ত্রুটি হয়েছে", + + // "dso-selector.export-metadata.dspaceobject.head": "Export metadata from", + "dso-selector.export-metadata.dspaceobject.head": "রপ্তানি মেটাডেটা থেকে", + + // "dso-selector.no-results": "No {{ type }} found", + "dso-selector.no-results": "কোন {{type}} পাওয়া যায় নি", + + // "dso-selector.placeholder": "Search for a {{ type }}", + "dso-selector.placeholder": "একটি {{type}} এর জন্য অনুসন্ধান করুন", + + // "dso-selector.select.collection.head": "Select a collection", + "dso-selector.select.collection.head": "একটি সংগ্রহ নির্বাচন করুন", + + // "dso-selector.set-scope.community.head": "Select a search scope", + "dso-selector.set-scope.community.head": "একটি অনুসন্ধান লক্ষ্যবিণ্ডু নির্বাচন করুন", + + // "dso-selector.set-scope.community.button": "Search all of DSpace", + "dso-selector.set-scope.community.button": "ডিস্পেস সব অনুসন্ধান করুন", + + // "dso-selector.set-scope.community.input-header": "Search for a community or collection", + "dso-selector.set-scope.community.input-header": "একটি সম্প্রদায় বা সংগ্রহের জন্য অনুসন্ধান করুন", + + + + // "confirmation-modal.export-metadata.header": "Export metadata for {{ dsoName }}", + "confirmation-modal.export-metadata.header": "{{ dsoName }} এর জন্য মেটাডেটা রপ্তানি করুন", + + // "confirmation-modal.export-metadata.info": "Are you sure you want to export metadata for {{ dsoName }}", + "confirmation-modal.export-metadata.info": "আপনি কি নিশ্চিত যে আপনি {{ dsoName }} এর জন্য মেটাডাটা রপ্তানি করতে চান", + + // "confirmation-modal.export-metadata.cancel": "Cancel", + "confirmation-modal.export-metadata.cancel": "বাতিল করুন", + + // "confirmation-modal.export-metadata.confirm": "Export", + "confirmation-modal.export-metadata.confirm": "এক্সপোর্ট", + + // "confirmation-modal.delete-eperson.header": "Delete EPerson \"{{ dsoName }}\"", + "confirmation-modal.delete-eperson.header": "ই-পারসন \"{{ dsoName }}\" মুছুন", + + // "confirmation-modal.delete-eperson.info": "Are you sure you want to delete EPerson \"{{ dsoName }}\"", + "confirmation-modal.delete-eperson.info": "আপনি কি নিশ্চিত যে আপনি ই-পারসন \"{{ dsoName }}\" মুছে ফেলতে চান", + + // "confirmation-modal.delete-eperson.cancel": "Cancel", + "confirmation-modal.delete-eperson.cancel": "বাতিল করুন", + + // "confirmation-modal.delete-eperson.confirm": "Delete", + "confirmation-modal.delete-eperson.confirm": "মুছে ফেলা", + + + // "error.bitstream": "Error fetching bitstream", + "error.bitstream": "বিটস্ট্রিম নিয়ে আসতে ত্রুটি হচ্ছে", + + // "error.browse-by": "Error fetching items", + "error.browse-by": "আইটেম নিয়ে আসতে ত্রুটি হচ্ছে", + + // "error.collection": "Error fetching collection", + "error.collection": "সংগ্রহগুলো নিয়ে আসতে ত্রুটি হচ্ছে", + + // "error.collections": "Error fetching collections", + "error.collections": "সংগ্রহ নিয়ে আসতে ত্রুটি হচ্ছে", + + // "error.community": "Error fetching community", + "error.community": "সম্প্রদায় নিয়ে আসতে ত্রুটি হচ্ছে", + + // "error.identifier": "No item found for the identifier", + "error.identifier": "কোন আইটেম সনাক্তকারী জন্য পাওয়া যায় নি", + + // "error.default": "Error", + "error.default": "ত্রুটি", + + // "error.item": "Error fetching item", + "error.item": "আইটেম নিয়ে আসতে ত্রুটি হচ্ছে", + + // "error.items": "Error fetching items", + "error.items": "আইটেমগুলো নিয়ে আসতে ত্রুটি হচ্ছে", + + // "error.objects": "Error fetching objects", + "error.objects": "অবজেক্ট নিয়ে আসতে ত্রুটি হচ্ছে", + + // "error.recent-submissions": "Error fetching recent submissions", + "error.recent-submissions": "সাম্প্রতিক জমাগুলো আনতে ত্রুটি হচ্ছে", + + // "error.search-results": "Error fetching search results", + "error.search-results": "অনুসন্ধান ফলাফল ডাউনলোড ত্রুটি", + + // "error.invalid-search-query": "Search query is not valid. Please check Solr query syntax best practices for further information about this error.", + "error.invalid-search-query": "অনুসন্ধান ক্যোয়ারী বৈধ নয়. আরও জানতে অনুগ্রহ করে সোলার কোয়েরি সিনট্যাক্স সর্বোত্তম অনুশীলন দেখুন এই ত্রুটি সম্পর্কে তথ্য।", + + // "error.sub-collections": "Error fetching sub-collections", + "error.sub-collections": "উপ-সংগ্রহগুলো নিয়ে আসতে ত্রুটি হচ্ছে", + + // "error.sub-communities": "Error fetching sub-communities", + "error.sub-communities": "উপ-সম্প্রদায়গুলো নিয়ে আসতে ত্রুটি হচ্ছে", + + // "error.submission.sections.init-form-error": "An error occurred during section initialize, please check your input-form configuration. Details are below :

", + "error.submission.sections.init-form-error": "বিভাগ শুরু করার সময় একটি ত্রুটি ঘটেছে, অনুগ্রহ করে আপনার ইনপুট-ফর্ম কনফিগারেশন পরীক্ষা করুন। বিস্তারিত নিচে দেওয়া হল:

", + + // "error.top-level-communities": "Error fetching top-level communities", + "error.top-level-communities": "শীর্ষ-স্তরের সম্প্রদায়গুলো নিয়ে আসতে ত্রুটি হচ্ছে", + + // "error.validation.license.notgranted": "You must grant this license to complete your submission. If you are unable to grant this license at this time you may save your work and return later or remove the submission.", + "error.validation.license.notgranted": "আপনি আপনার জমা সম্পূর্ণ করার জন্য এই লাইসেন্স প্রদান করতে হবে। আপনি যদি এই লাইসেন্সটি অনুগ্রহ করতে অক্ষম হন তবে আপনি আপনার কাজটি সংরক্ষণ করতে এবং পরে ফিরে বা জমাটি সরাতে পারেন।", + + // "error.validation.pattern": "This input is restricted by the current pattern: {{ pattern }}.", + "error.validation.pattern": "এই ইনপুট বর্তমান প্যাটার্ন দ্বারা সীমাবদ্ধ: {{ pattern }}.", + + // "error.validation.filerequired": "The file upload is mandatory", + "error.validation.filerequired": "ফাইল আপলোড বাধ্যতামূলক", + + // "error.validation.required": "This field is required", + "error.validation.required": "ঘরটি অবশ্যই পূরণ করতে হবে", + + // "error.validation.NotValidEmail": "This E-mail is not a valid email", + "error.validation.NotValidEmail": "এই ইমেইল একটি বৈধ ইমেইল নয়", + + // "error.validation.emailTaken": "This E-mail is already taken", + "error.validation.emailTaken": "এই ইমেইলটি ইতিমধ্যে নেওয়া হয়েছে", + + // "error.validation.groupExists": "This group already exists", + "error.validation.groupExists": "এই গ্রুপ ইতিমধ্যে বিদ্যমান", + + + // "file-section.error.header": "Error obtaining files for this item", + "file-section.error.header": "এই আইটেমটি জন্য ফাইল প্রাপ্ত করার সময় ত্রুটি", + + + + // "footer.copyright": "copyright © 2002-{{ year }}", + "footer.copyright": "কপিরাইট © 2002 - {{year}}", + + // "footer.link.dspace": "DSpace software", + "footer.link.dspace": "ডিস্পেস সফটওয়্যার", + + // "footer.link.lyrasis": "LYRASIS", + "footer.link.lyrasis": "LYRASIS", + + // "footer.link.cookies": "Cookie settings", + "footer.link.cookies": "কুকি সেটিংস", + + // "footer.link.privacy-policy": "Privacy policy", + "footer.link.privacy-policy": "গোপনীয়তা নীতি", + + // "footer.link.end-user-agreement":"End User Agreement", + "footer.link.end-user-agreement": "ব্যবহারকারী সাথে চুক্তি", + + // "footer.link.feedback":"Send Feedback", + "footer.link.feedback": "মতামত পাঠানো", + + + + // "forgot-email.form.header": "Forgot Password", + "forgot-email.form.header": "পাসওয়ার্ড ভুলে গেছেন", + + // "forgot-email.form.info": "Enter Register an account to subscribe to collections for email updates, and submit new items to DSpace.", + "forgot-email.form.info": "ইমেল আপডেটের জন্য সংগ্রহে সাবস্ক্রাইব করার জন্য একটি অ্যাকাউন্ট নিবন্ধন করুন এবং ডিস্পেস এ নতুন আইটেম জমা দিন।", + + // "forgot-email.form.email": "Email Address *", + "forgot-email.form.email": "ইমেইল ঠিকানা *", + + // "forgot-email.form.email.error.required": "Please fill in an email address", + "forgot-email.form.email.error.required": "একটি ইমেইল ঠিকানা পূরণ করুন", + + // "forgot-email.form.email.error.pattern": "Please fill in a valid email address", + "forgot-email.form.email.error.pattern": "একটি বৈধ ইমেইল ঠিকানা পূরণ করুন", + + // "forgot-email.form.email.hint": "This address will be verified and used as your login name.", + "forgot-email.form.email.hint": "এই ঠিকানাটি যাচাই করা হবে এবং আপনার লগইন নাম হিসাবে ব্যবহার করা হবে।", + + // "forgot-email.form.submit": "Save", + "forgot-email.form.submit": "সংরক্ষণ", + + // "forgot-email.form.success.head": "Verification email sent", + "forgot-email.form.success.head": "যাচাই ইমেইল পাঠানো হয়েছে", + + // "forgot-email.form.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", + "forgot-email.form.success.content": "একটি বিশেষ ইউআরএল এবং আরও নির্দেশাবলী ধারণকারী {{email}} এ একটি ইমেল পাঠানো হয়েছে।", + + // "forgot-email.form.error.head": "Error when trying to register email", + "forgot-email.form.error.head": "ইমেল নিবন্ধন করার চেষ্টা করার সময় ত্রুটি", + + // "forgot-email.form.error.content": "An error occured when registering the following email address: {{ email }}", + "forgot-email.form.error.content": "নিম্নলিখিত ইমেল ঠিকানা নিবন্ধন করার সময় একটি ত্রুটি ঘটেছে:{{ email }}", + + + + // "forgot-password.title": "Forgot Password", + "forgot-password.title": "পাসওয়ার্ড ভুলে গেছেন", + + // "forgot-password.form.head": "Forgot Password", + "forgot-password.form.head": "পাসওয়ার্ড ভুলে গেছেন", + + // "forgot-password.form.info": "Enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", + "forgot-password.form.info": "নীচের বাক্সে একটি নতুন পাসওয়ার্ড লিখুন এবং এটি আবার দ্বিতীয় বাক্সে টাইপ করে এটি নিশ্চিত করুন। এটি অন্তত ছয় অক্ষর দীর্ঘ হতে হবে।", + + // "forgot-password.form.card.security": "Security", + "forgot-password.form.card.security": "নিরাপত্তা", + + // "forgot-password.form.identification.header": "Identify", + "forgot-password.form.identification.header": "চিহ্নিত করুন", + + // "forgot-password.form.identification.email": "Email address: ", + "forgot-password.form.identification.email": "ইমেইলের ঠিকানা: ", + + // "forgot-password.form.label.password": "Password", + "forgot-password.form.label.password": "পাসওয়ার্ড", + + // "forgot-password.form.label.passwordrepeat": "Retype to confirm", + "forgot-password.form.label.passwordrepeat": "নিশ্চিত করতে পুনরাই লিখুন", + + // "forgot-password.form.error.empty-password": "Please enter a password in the box below.", + "forgot-password.form.error.empty-password": "নীচের বাক্সে একটি পাসওয়ার্ড লিখুন দয়া করে।", + + // "forgot-password.form.error.matching-passwords": "The passwords do not match.", + "forgot-password.form.error.matching-passwords": "পাসওয়ার্ড মেলে না.", + + // "forgot-password.form.error.password-length": "The password should be at least 6 characters long.", + "forgot-password.form.error.password-length": "পাসওয়ার্ড অন্তত ৬ অক্ষর দীর্ঘ হওয়া উচিত।", + + // "forgot-password.form.notification.error.title": "Error when trying to submit new password", + "forgot-password.form.notification.error.title": "নতুন পাসওয়ার্ড জমা দেওয়ার চেষ্টা করার সময় ত্রুটি হচ্ছে", + + // "forgot-password.form.notification.success.content": "The password reset was successful. You have been logged in as the created user.", + "forgot-password.form.notification.success.content": "পাসওয়ার্ড রিসেট সফল ছিল। আপনি তৈরি ব্যবহারকারী হিসাবে লগ ইন করা হয়েছে।", + + // "forgot-password.form.notification.success.title": "Password reset completed", + "forgot-password.form.notification.success.title": "পাসওয়ার্ড রিসেট সম্পন্ন", + + // "forgot-password.form.submit": "Submit password", + "forgot-password.form.submit": "পাসওয়ার্ড জমা দিন", + + + + // "form.add": "Add more", + "form.add": "আরো যোগ করো", + + // "form.add-help": "Click here to add the current entry and to add another one", + "form.add-help": "বর্তমান এন্ট্রি যোগ করতে এবং অন্য একটি যোগ করার জন্য এখানে ক্লিক করুন", + + // "form.cancel": "Cancel", + "form.cancel": "বাতিল করুন", + + // "form.clear": "Clear", + "form.clear": "স্পষ্ট", + + // "form.clear-help": "Click here to remove the selected value", + "form.clear-help": "নির্বাচিত মান মুছে ফেলার জন্য এখানে ক্লিক করুন", + + // "form.discard": "Discard", + "form.discard": "বাতিল করা", + + // "form.drag": "Drag", + "form.drag": "টেনে আনুন", + + // "form.edit": "Edit", + "form.edit": "সম্পাদনা করুন", + + // "form.edit-help": "Click here to edit the selected value", + "form.edit-help": "নির্বাচিত মান সম্পাদনা করতে এখানে ক্লিক করুন", + + // "form.first-name": "First name", + "form.first-name": "নামের প্রথম অংশ", + + // "form.group-collapse": "Collapse", + "form.group-collapse": "ধৈর্য", + + // "form.group-collapse-help": "Click here to collapse", + "form.group-collapse-help": "ধসে পড়তে এখানে ক্লিক করুন", + + // "form.group-expand": "Expand", + "form.group-expand": "বিস্তৃত করা", + + // "form.group-expand-help": "Click here to expand and add more elements", + "form.group-expand-help": "প্রসারিত এবং আরো উপাদান যোগ করতে এখানে ক্লিক করুন", + + // "form.last-name": "Last name", + "form.last-name": "নামের শেষাংশ", + + // "form.loading": "Loading...", + "form.loading": "লোড হচ্ছে ...", + + // "form.lookup": "Lookup", + "form.lookup": "খুঁজে দেখো", + + // "form.lookup-help": "Click here to look up an existing relation", + "form.lookup-help": "একটি বিদ্যমান সম্পর্ক তাকান এখানে ক্লিক করুন", + + // "form.no-results": "No results found", + "form.no-results": "কোন ফলাফল পাওয়া যায়নি", + + // "form.no-value": "No value entered", + "form.no-value": "কোন মান প্রবেশ", + + // "form.other-information": {}, + "form.other-information": {}, + + // "form.remove": "Remove", + "form.remove": "অপসারণ", + + // "form.save": "Save", + "form.save": "সংরক্ষণ", + + // "form.save-help": "Save changes", + "form.save-help": "পরিবর্তনগুলোর সংরক্ষন", + + // "form.search": "Search", + "form.search": "অনুসন্ধান করুন", + + // "form.search-help": "Click here to look for an existing correspondence", + "form.search-help": "একটি বিদ্যমান চিঠিপত্রের জন্য এখানে ক্লিক করুন", + + // "form.submit": "Save", + "form.submit": "সংরক্ষণ", + + // "form.repeatable.sort.tip": "Drop the item in the new position", + "form.repeatable.sort.tip": "নতুন অবস্থানে আইটেম ড্রপ", + + + + // "grant-deny-request-copy.deny": "Don't send copy", + "grant-deny-request-copy.deny": "কপি পাঠান না", + + // "grant-deny-request-copy.email.back": "Back", + "grant-deny-request-copy.email.back": "পেছনে", + + // "grant-deny-request-copy.email.message": "Message", + "grant-deny-request-copy.email.message": "বার্তা", + + // "grant-deny-request-copy.email.message.empty": "Please enter a message", + "grant-deny-request-copy.email.message.empty": "একটি বার্তা লিখুন দয়া করে", + + // "grant-deny-request-copy.email.permissions.info": "You may use this occasion to reconsider the access restrictions on the document, to avoid having to respond to these requests. If you’d like to ask the repository administrators to remove these restrictions, please check the box below.", + "grant-deny-request-copy.email.permissions.info": "আপনি এই অনুরোধগুলি এই অনুরোধগুলি সাড়া দেওয়ার জন্য নথিতে অ্যাক্সেস সীমাবদ্ধতাগুলি পুনর্বিবেচনার জন্য ব্যবহার করতে পারেন। আপনি যদি এই সীমাবদ্ধতাগুলি সরানোর জন্য রিপোজিটরি প্রশাসকদের জিজ্ঞাসা করতে চান তবে নীচের বাক্সটি চেক করুন।", + + // "grant-deny-request-copy.email.permissions.label": "Change to open access", + "grant-deny-request-copy.email.permissions.label": "এক্সেস খুলতে পরিবর্তন করুন", + + // "grant-deny-request-copy.email.send": "Send", + "grant-deny-request-copy.email.send": "পাঠান", + + // "grant-deny-request-copy.email.subject": "Subject", + "grant-deny-request-copy.email.subject": "বিষয়", + + // "grant-deny-request-copy.email.subject.empty": "Please enter a subject", + "grant-deny-request-copy.email.subject.empty": "একটি বিষয় লিখুন দয়া করে", + + // "grant-deny-request-copy.grant": "Send copy", + "grant-deny-request-copy.grant": "কপি পাঠান", + + // "grant-deny-request-copy.header": "Document copy request", + "grant-deny-request-copy.header": "নথি কপি অনুরোধ", + + // "grant-deny-request-copy.home-page": "Take me to the home page", + "grant-deny-request-copy.home-page": "আমাকে হোম পেজে নিয়ে যাও", + + // "grant-deny-request-copy.intro1": "If you are one of the authors of the document {{ name }}, then please use one of the options below to respond to the user's request.", + "grant-deny-request-copy.intro1": "আপনি যদি নথির লেখক {{ name }} এর পরে ব্যবহারকারীর অনুরোধের প্রতি সাড়া দেওয়ার জন্য নীচের বিকল্পগুলির একটি ব্যবহার করুন।", + + // "grant-deny-request-copy.intro2": "After choosing an option, you will be presented with a suggested email reply which you may edit.", + "grant-deny-request-copy.intro2": "একটি বিকল্প নির্বাচন করার পরে আপনি একটি প্রস্তাবিত ইমেল উত্তর দিয়ে উপস্থাপন করা হবে যা আপনি সম্পাদনা করতে পারেন।", + + // "grant-deny-request-copy.processed": "This request has already been processed. You can use the button below to get back to the home page.", + "grant-deny-request-copy.processed": "এই অনুরোধ ইতিমধ্যে প্রক্রিয়া করা হয়েছে। আপনি হোম পেজে ফিরে পেতে নীচের বোতামটি ব্যবহার করতে পারেন।", + + + + // "grant-request-copy.email.message": "Dear {{ recipientName }},\nIn response to your request I have the pleasure to send you in attachment a copy of the file(s) concerning the document: \"{{ itemUrl }}\" ({{ itemName }}), of which I am an author.\n\nBest regards,\n{{ authorName }} <{{ authorEmail }}>", + "grant-request-copy.email.message": "প্রিয় {{ recipientName }},\nআপনার অনুরোধের জবাবে আমি আপনাকে নথি সংক্রান্ত ফাইল(গুলি) এর একটি অনুলিপি সংযুক্তিতে পাঠাতে পেরে আনন্দিত: \"{{ itemUrl }}\" ({{ itemName }}) , যার মধ্যে আমি একজন লেখক।\n\nশুভেচ্ছা,\n{{ authorName }} <{{ authorEmail }}>", + + // "grant-request-copy.email.subject": "Request copy of document", + "grant-request-copy.email.subject": "নথির কপি অনুরোধ", + + // "grant-request-copy.error": "An error occurred", + "grant-request-copy.error": "একটি ত্রুটি ঘটেছে", + + // "grant-request-copy.header": "Grant document copy request", + "grant-request-copy.header": "গ্রান্ট নথি কপি অনুরোধ", + + // "grant-request-copy.intro": "This message will be sent to the applicant of the request. The requested document(s) will be attached.", + "grant-request-copy.intro": "এই বার্তাটি অনুরোধের আবেদনকারীর কাছে পাঠানো হবে। অনুরোধকৃত নথি (গুলি) সংযুক্ত করা হবে।", + + // "grant-request-copy.success": "Successfully granted item request", + "grant-request-copy.success": "সফলভাবে আইটেম অনুরোধ দেওয়া", + + + + // "home.description": "", + "home.description": "অপসারণ করা আবশ্যক", + + // "home.breadcrumbs": "Home", + "home.breadcrumbs": "হোম", + + // "home.search-form.placeholder": "Search the repository ...", + "home.search-form.placeholder": "সংগ্রহস্থল অনুসন্ধান করুন ...", + + // "home.title": "Home", + "home.title": "হোম", + + // "home.top-level-communities.head": "Communities in DSpace", + "home.top-level-communities.head": "ডিস্পেস এর সম্প্রদায়", + + // "home.top-level-communities.help": "Select a community to browse its collections.", + "home.top-level-communities.help": "তার সংগ্রহ ব্রাউজ করতে একটি সম্প্রদায় নির্বাচন করুন।", + + + + // "info.end-user-agreement.accept": "I have read and I agree to the End User Agreement", + "info.end-user-agreement.accept": "আমি পড়েছি এবং আমি শেষ ব্যবহারকারী চুক্তির সাথে একমত", + + // "info.end-user-agreement.accept.error": "An error occurred accepting the End User Agreement", + "info.end-user-agreement.accept.error": "একটি ত্রুটি শেষ ব্যবহারকারী চুক্তি গ্রহণ ঘটেছে", + + // "info.end-user-agreement.accept.success": "Successfully updated the End User Agreement", + "info.end-user-agreement.accept.success": "সফলভাবে শেষ ব্যবহারকারী চুক্তি আপডেট", + + // "info.end-user-agreement.breadcrumbs": "End User Agreement", + "info.end-user-agreement.breadcrumbs": "শেষ ব্যবহারকারী চুক্তি", + + // "info.end-user-agreement.buttons.cancel": "Cancel", + "info.end-user-agreement.buttons.cancel": "বাতিল করুন", + + // "info.end-user-agreement.buttons.save": "Save", + "info.end-user-agreement.buttons.save": "সংরক্ষণ", + + // "info.end-user-agreement.head": "End User Agreement", + "info.end-user-agreement.head": "শেষ ব্যবহারকারী চুক্তি", + + // "info.end-user-agreement.title": "End User Agreement", + "info.end-user-agreement.title": "শেষ ব্যবহারকারী চুক্তি", + + // "info.privacy.breadcrumbs": "Privacy Statement", + "info.privacy.breadcrumbs": "গোপনীয়তা বিবৃতি", + + // "info.privacy.head": "Privacy Statement", + "info.privacy.head": "গোপনীয়তা বিবৃতি", + + // "info.privacy.title": "Privacy Statement", + "info.privacy.title": "গোপনীয়তা বিবৃতি", + + // "info.feedback.breadcrumbs": "Feedback", + "info.feedback.breadcrumbs": "প্রতিক্রিয়া", + + // "info.feedback.head": "Feedback", + "info.feedback.head": "প্রতিক্রিয়া", + + // "info.feedback.title": "Feedback", + "info.feedback.title": "প্রতিক্রিয়া", + + // "info.feedback.info": "Thanks for sharing your feedback about the DSpace system. Your comments are appreciated!", + "info.feedback.info": "ডিস্পেস সিস্টেম সম্পর্কে আপনার প্রতিক্রিয়া ভাগ করার জন্য ধন্যবাদ। আপনার মন্তব্য প্রশংসা করা হয়!", + + // "info.feedback.email_help": "This address will be used to follow up on your feedback.", + "info.feedback.email_help": "এই ঠিকানাটি আপনার প্রতিক্রিয়া অনুসরণ করতে ব্যবহার করা হবে।", + + // "info.feedback.send": "Send Feedback", + "info.feedback.send": "মতামত পাঠানো", + + // "info.feedback.comments": "Comments", + "info.feedback.comments": "মন্তব্য", + + // "info.feedback.email-label": "Your Email", + "info.feedback.email-label": "তোমার ইমেইল", + + // "info.feedback.create.success" : "Feedback Sent Successfully!", + "info.feedback.create.success" : "প্রতিক্রিয়া সফলভাবে পাঠানো হয়েছে!", + + // "info.feedback.error.email.required" : "A valid email address is required", + "info.feedback.error.email.required" : "একটি বৈধ ইমেইল ঠিকানা প্রয়োজন বোধ করা হয়", + + // "info.feedback.error.message.required" : "A comment is required", + "info.feedback.error.message.required" : "একটি মন্তব্য প্রয়োজন", + + // "info.feedback.page-label" : "Page", + "info.feedback.page-label" : "পৃষ্ঠা", + + // "info.feedback.page_help" : "Tha page related to your feedback", + "info.feedback.page_help" : "আপনার মতামত সম্পর্কিত পৃষ্ঠা", + + + + // "item.alerts.private": "This item is private", + "item.alerts.private": "এই আইটেমটি ব্যক্তিগত", + + // "item.alerts.withdrawn": "This item has been withdrawn", + "item.alerts.withdrawn": "এই আইটেমটি প্রত্যাহার করা হয়েছে", + + + + // "item.edit.authorizations.heading": "With this editor you can view and alter the policies of an item, plus alter policies of individual item components: bundles and bitstreams. Briefly, an item is a container of bundles, and bundles are containers of bitstreams. Containers usually have ADD/REMOVE/READ/WRITE policies, while bitstreams only have READ/WRITE policies.", + "item.edit.authorizations.heading": "এই সম্পাদকের সাহায্যে আপনি একটি আইটেমের নীতিগুলি দেখতে এবং পরিবর্তন করতে পারেন, এছাড়াও পৃথক আইটেমের উপাদানগুলির নীতিগুলি পরিবর্তন করতে পারেন: বান্ডেল এবং বিটস্ট্রিম৷ সংক্ষেপে, একটি আইটেম বান্ডিলের একটি ধারক, এবং বান্ডিলগুলি বিটস্ট্রিমের ধারক। কন্টেইনারগুলিতে সাধারণত ADD/REMOVE/READ/WRITE নীতি থাকে, যখন বিটস্ট্রিমগুলিতে শুধুমাত্র READ/WRITE নীতি থাকে৷", + + // "item.edit.authorizations.title": "Edit item's Policies", + "item.edit.authorizations.title": "আইটেম এর নীতি সম্পাদনা করুন", + + + + // "item.badge.private": "Private", + "item.badge.private": "ব্যক্তিগত", + + // "item.badge.withdrawn": "Withdrawn", + "item.badge.withdrawn": "প্রত্যাহার", + + + + // "item.bitstreams.upload.bundle": "Bundle", + "item.bitstreams.upload.bundle": "পাঁজা", + + // "item.bitstreams.upload.bundle.placeholder": "Select a bundle", + "item.bitstreams.upload.bundle.placeholder": "একটি বান্ডিল নির্বাচন করুন", + + // "item.bitstreams.upload.bundle.new": "Create bundle", + "item.bitstreams.upload.bundle.new": "বান্ডিল তৈরি করুন", + + // "item.bitstreams.upload.bundles.empty": "This item doesn\'t contain any bundles to upload a bitstream to.", + "item.bitstreams.upload.bundles.empty": "এই আইটেমটি একটি বিটস্ট্রিম আপলোড করার জন্য কোন bundles থাকে না।", + + // "item.bitstreams.upload.cancel": "Cancel", + "item.bitstreams.upload.cancel": "বাতিল করুন", + + // "item.bitstreams.upload.drop-message": "Drop a file to upload", + "item.bitstreams.upload.drop-message": "আপলোড করার জন্য একটি ফাইল ড্রপ", + + // "item.bitstreams.upload.item": "Item: ", + "item.bitstreams.upload.item": "আইটেম: ", + + // "item.bitstreams.upload.notifications.bundle.created.content": "Successfully created new bundle.", + "item.bitstreams.upload.notifications.bundle.created.content": "সফলভাবে নতুন বান্ডিল তৈরি।", + + // "item.bitstreams.upload.notifications.bundle.created.title": "Created bundle", + "item.bitstreams.upload.notifications.bundle.created.title": "তৈরি বান্ডিল", + + // "item.bitstreams.upload.notifications.upload.failed": "Upload failed. Please verify the content before retrying.", + "item.bitstreams.upload.notifications.upload.failed": "আপলোড ব্যর্থ হয়েছে. পুনরায় চেষ্টা করার আগে কন্টেন্ট যাচাই করুন।", + + // "item.bitstreams.upload.title": "Upload bitstream", + "item.bitstreams.upload.title": "বিটস্ট্রিম আপলোড করুন", + + + + // "item.edit.bitstreams.bundle.edit.buttons.upload": "Upload", + "item.edit.bitstreams.bundle.edit.buttons.upload": "আপলোড করুন", + + // "item.edit.bitstreams.bundle.displaying": "Currently displaying {{ amount }} bitstreams of {{ total }}.", + "item.edit.bitstreams.bundle.displaying": "বর্তমানে {{ amount }} এবং {{ total }} এর বিটস্ট্রিমগুলি প্রদর্শন করে।", + + // "item.edit.bitstreams.bundle.load.all": "Load all ({{ total }})", + "item.edit.bitstreams.bundle.load.all": "সব লোড করুন ({{ total }})", + + // "item.edit.bitstreams.bundle.load.more": "Load more", + "item.edit.bitstreams.bundle.load.more": "আর ঢুকাও", + + // "item.edit.bitstreams.bundle.name": "BUNDLE: {{ name }}", + "item.edit.bitstreams.bundle.name": "BUNDLE: {{ name }}", + + // "item.edit.bitstreams.discard-button": "Discard", + "item.edit.bitstreams.discard-button": "বাতিল করা", + + // "item.edit.bitstreams.edit.buttons.download": "Download", + "item.edit.bitstreams.edit.buttons.download": "ডাউনলোড করুন", + + // "item.edit.bitstreams.edit.buttons.drag": "Drag", + "item.edit.bitstreams.edit.buttons.drag": "Drag", + + // "item.edit.bitstreams.edit.buttons.edit": "Edit", + "item.edit.bitstreams.edit.buttons.edit": "সম্পাদনা করুন", + + // "item.edit.bitstreams.edit.buttons.remove": "Remove", + "item.edit.bitstreams.edit.buttons.remove": "অপসারণ", + + // "item.edit.bitstreams.edit.buttons.undo": "Undo changes", + "item.edit.bitstreams.edit.buttons.undo": "পূর্বাবস্থায় ফিরিয়ে আনুন", + + // "item.edit.bitstreams.empty": "This item doesn't contain any bitstreams. Click the upload button to create one.", + "item.edit.bitstreams.empty": "এই আইটেমটি কোন বিটস্ট্রিম ধারণ করে না। একটি তৈরি করতে আপলোড বাটনে ক্লিক করুন।", + + // "item.edit.bitstreams.headers.actions": "Actions", + "item.edit.bitstreams.headers.actions": "Actions", + + // "item.edit.bitstreams.headers.bundle": "Bundle", + "item.edit.bitstreams.headers.bundle": "Bundle", + + // "item.edit.bitstreams.headers.description": "Description", + "item.edit.bitstreams.headers.description": "বর্ণনা", + + // "item.edit.bitstreams.headers.format": "Format", + "item.edit.bitstreams.headers.format": "বিন্যাস", + + // "item.edit.bitstreams.headers.name": "Name", + "item.edit.bitstreams.headers.name": "নামকরণ", + + // "item.edit.bitstreams.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + "item.edit.bitstreams.notifications.discarded.content": "আপনার পরিবর্তন বাতিল করা হয়েছে। আপনার পরিবর্তনগুলি পুনঃস্থাপন করতে 'পূর্বাবস্থায় ফিরুন' বাটনে ক্লিক করুন", + + // "item.edit.bitstreams.notifications.discarded.title": "Changes discarded", + "item.edit.bitstreams.notifications.discarded.title": "পরিবর্তন বাতিল করা হয়েছে", + + // "item.edit.bitstreams.notifications.move.failed.title": "Error moving bitstreams", + "item.edit.bitstreams.notifications.move.failed.title": "বিটস্ট্রিম চলন্ত ত্রুটি", + + // "item.edit.bitstreams.notifications.move.saved.content": "Your move changes to this item's bitstreams and bundles have been saved.", + "item.edit.bitstreams.notifications.move.saved.content": "আপনার পদক্ষেপ এই আইটেমটি এর বিটস্ট্রিম এবং bundles পরিবর্তন করা হয়েছে।", + + // "item.edit.bitstreams.notifications.move.saved.title": "Move changes saved", + "item.edit.bitstreams.notifications.move.saved.title": "অপসারণ পরিবর্তন করুন", + + // "item.edit.bitstreams.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", + "item.edit.bitstreams.notifications.outdated.content": "আপনি বর্তমানে কাজ করছেন এমন আইটেমটি অন্য ব্যবহারকারী দ্বারা পরিবর্তিত হয়েছে। আপনার বর্তমান পরিবর্তন দ্বন্দ্ব প্রতিরোধ করতে বাতিল করা হয়", + + // "item.edit.bitstreams.notifications.outdated.title": "Changes outdated", + "item.edit.bitstreams.notifications.outdated.title": "পরিবর্তনগুলি পুরানো", + + // "item.edit.bitstreams.notifications.remove.failed.title": "Error deleting bitstream", + "item.edit.bitstreams.notifications.remove.failed.title": "বিটস্ট্রিম মুছে ফেলার সময় ত্রুটি", + + // "item.edit.bitstreams.notifications.remove.saved.content": "Your removal changes to this item's bitstreams have been saved.", + "item.edit.bitstreams.notifications.remove.saved.content": "এই আইটেমটির বিটস্ট্রিমগুলিতে আপনার অপসারণ পরিবর্তনগুলি সংরক্ষণ করা হয়েছে।", + + // "item.edit.bitstreams.notifications.remove.saved.title": "Removal changes saved", + "item.edit.bitstreams.notifications.remove.saved.title": "অপসারণ পরিবর্তন সংরক্ষিত", + + // "item.edit.bitstreams.reinstate-button": "Undo", + "item.edit.bitstreams.reinstate-button": "পূর্বাবস্থায় ফেরানো", + + // "item.edit.bitstreams.save-button": "Save", + "item.edit.bitstreams.save-button": "সংরক্ষণ", + + // "item.edit.bitstreams.upload-button": "Upload", + "item.edit.bitstreams.upload-button": "আপলোড করুন", + + + + // "item.edit.delete.cancel": "Cancel", + "item.edit.delete.cancel": "বাতিল করুন", + + // "item.edit.delete.confirm": "Delete", + "item.edit.delete.confirm": "মুছে ফেলা", + + // "item.edit.delete.description": "Are you sure this item should be completely deleted? Caution: At present, no tombstone would be left.", + "item.edit.delete.description": "আপনি কি নিশ্চিত যে এই আইটেমটি সম্পূর্ণরূপে মুছে ফেলা উচিত? সতর্কতা: বর্তমানে, কোন সমাধি পাথর অবশিষ্ট থাকবে না।", + + // "item.edit.delete.error": "An error occurred while deleting the item", + "item.edit.delete.error": "আইটেমটি মুছে ফেলার সময় একটি ত্রুটি ঘটেছে", + + // "item.edit.delete.header": "Delete item: {{ id }}", + "item.edit.delete.header": "আইটেম মুছুন: {{ id }}", + + // "item.edit.delete.success": "The item has been deleted", + "item.edit.delete.success": "আইটেম মুছে ফেলা হয়েছে", + + // "item.edit.head": "Edit Item", + "item.edit.head": "আইটেম সম্পাদনা করুন", + + // "item.edit.breadcrumbs": "Edit Item", + "item.edit.breadcrumbs": "আইটেম সম্পাদনা করুন", + + // "item.edit.tabs.disabled.tooltip": "You're not authorized to access this tab", + "item.edit.tabs.disabled.tooltip": "আপনি এই ট্যাবটি অ্যাক্সেস করার জন্য অনুমোদিত নন", + + + // "item.edit.tabs.mapper.head": "Collection Mapper", + "item.edit.tabs.mapper.head": "সংগ্রহ ম্যাপার", + + // "item.edit.tabs.item-mapper.title": "Item Edit - Collection Mapper", + "item.edit.tabs.item-mapper.title": "আইটেম সম্পাদনা - সংগ্রহ ম্যাপার", + + // "item.edit.item-mapper.buttons.add": "Map item to selected collections", + "item.edit.item-mapper.buttons.add": "নির্বাচিত সংগ্রহে মানচিত্র আইটেম", + + // "item.edit.item-mapper.buttons.remove": "Remove item's mapping for selected collections", + "item.edit.item-mapper.buttons.remove": "নির্বাচিত সংগ্রহের জন্য আইটেম এর সমন্নয় সরান", + + // "item.edit.item-mapper.cancel": "Cancel", + "item.edit.item-mapper.cancel": "বাতিল করুন", + + // "item.edit.item-mapper.description": "This is the item mapper tool that allows administrators to map this item to other collections. You can search for collections and map them, or browse the list of collections the item is currently mapped to.", + "item.edit.item-mapper.description": "এটি আইটেম ম্যাপার টুল যা প্রশাসকদের এই আইটেমটিকে অন্যান্য সংগ্রহগুলিতে মানচিত্র করতে দেয়। আপনি সংগ্রহগুলি এবং তাদের মানচিত্রের জন্য অনুসন্ধান করতে পারেন বা সংগ্রহের তালিকাটি বর্তমানে ম্যাপ করা হয়েছে।", + + // "item.edit.item-mapper.head": "Item Mapper - Map Item to Collections", + "item.edit.item-mapper.head": "আইটেম ম্যাপার - সংগ্রহের মানচিত্র আইটেম", + + // "item.edit.item-mapper.item": "Item: \"{{name}}\"", + "item.edit.item-mapper.item": "আইটেম: \"{{name}}\"", + + // "item.edit.item-mapper.no-search": "Please enter a query to search", + "item.edit.item-mapper.no-search": "অনুসন্ধান একটি প্রশ্নের লিখুন দয়া করে", + + // "item.edit.item-mapper.notifications.add.error.content": "Errors occurred for mapping of item to {{amount}} collections.", + "item.edit.item-mapper.notifications.add.error.content": "{{amount}} গুলি সংগ্রহের আইটেমটি সমন্নয়য়ের জন্য ত্রুটি ঘটেছে।", + + // "item.edit.item-mapper.notifications.add.error.head": "Mapping errors", + "item.edit.item-mapper.notifications.add.error.head": "সমন্নয় ত্রুটি", + + // "item.edit.item-mapper.notifications.add.success.content": "Successfully mapped item to {{amount}} collections.", + "item.edit.item-mapper.notifications.add.success.content": "সফলভাবে {{amount}} সংগ্রহের আইটেমটি সমন্নয় করা হয়েছে।", + + // "item.edit.item-mapper.notifications.add.success.head": "Mapping completed", + "item.edit.item-mapper.notifications.add.success.head": "সমন্নয় সম্পন্ন", + + // "item.edit.item-mapper.notifications.remove.error.content": "Errors occurred for the removal of the mapping to {{amount}} collections.", + "item.edit.item-mapper.notifications.remove.error.content": "{{amount}} গুলি সংগ্রহের আইটেমটি সমন্নয়য়ের জন্য ত্রুটি ঘটেছে।", + + // "item.edit.item-mapper.notifications.remove.error.head": "Removal of mapping errors", + "item.edit.item-mapper.notifications.remove.error.head": "সমন্নয় ত্রুটি অপসারণ", + + // "item.edit.item-mapper.notifications.remove.success.content": "Successfully removed mapping of item to {{amount}} collections.", + "item.edit.item-mapper.notifications.remove.success.content": "সফলভাবে {{amount}} সংগ্রহের আইটেম সমন্নয় সরানো হয়েছে।", + + // "item.edit.item-mapper.notifications.remove.success.head": "Removal of mapping completed", + "item.edit.item-mapper.notifications.remove.success.head": "সমন্নয় অপসারণ সম্পন্ন হয়েছে", + + // "item.edit.item-mapper.search-form.placeholder": "Search collections...", + "item.edit.item-mapper.search-form.placeholder": "সংগ্রহ অনুসন্ধান করুন ...", + + // "item.edit.item-mapper.tabs.browse": "Browse mapped collections", + "item.edit.item-mapper.tabs.browse": "সমন্বিত সংগ্রহ ব্রাউজ করুন", + + // "item.edit.item-mapper.tabs.map": "Map new collections", + "item.edit.item-mapper.tabs.map": "মানচিত্র নতুন সংগ্রহ", + + + + // "item.edit.metadata.add-button": "Add", + "item.edit.metadata.add-button": "যোগ করুন", + + // "item.edit.metadata.discard-button": "Discard", + "item.edit.metadata.discard-button": "বাতিল করা", + + // "item.edit.metadata.edit.buttons.edit": "Edit", + "item.edit.metadata.edit.buttons.edit": "সম্পাদনা করুন", + + // "item.edit.metadata.edit.buttons.remove": "Remove", + "item.edit.metadata.edit.buttons.remove": "অপসারণ", + + // "item.edit.metadata.edit.buttons.undo": "Undo changes", + "item.edit.metadata.edit.buttons.undo": "পূর্বাবস্থায় ফিরিয়ে আনুন", + + // "item.edit.metadata.edit.buttons.unedit": "Stop editing", + "item.edit.metadata.edit.buttons.unedit": "সম্পাদনা বন্ধ করুন", + + // "item.edit.metadata.empty": "The item currently doesn't contain any metadata. Click Add to start adding a metadata value.", + "item.edit.metadata.empty": "আইটেমটি বর্তমানে কোন মেটাডেটা নেই। একটি মেটাডেটা মান যোগ করতে শুরু করতে যোগ করুন ক্লিক করুন।", + + // "item.edit.metadata.headers.edit": "Edit", + "item.edit.metadata.headers.edit": "সম্পাদনা করুন", + + // "item.edit.metadata.headers.field": "Field", + "item.edit.metadata.headers.field": "মাঠ", + + // "item.edit.metadata.headers.language": "Lang", + "item.edit.metadata.headers.language": "ল্যাং।", + + // "item.edit.metadata.headers.value": "Value", + "item.edit.metadata.headers.value": "মূল্য", + + // "item.edit.metadata.metadatafield.invalid": "Please choose a valid metadata field", + "item.edit.metadata.metadatafield.invalid": "একটি বৈধ মেটাডেটা ক্ষেত্র নির্বাচন করুন", + + // "item.edit.metadata.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + "item.edit.metadata.notifications.discarded.content": "আপনার পরিবর্তন বাতিল করা হয়েছে। আপনার পরিবর্তনগুলি পুনঃস্থাপন করতে 'পূর্বাবস্থায় ফিরুন' বাটনে ক্লিক করুন", + + // "item.edit.metadata.notifications.discarded.title": "Changed discarded", + "item.edit.metadata.notifications.discarded.title": "পরিবর্তিত পরিবর্তন", + + // "item.edit.metadata.notifications.error.title": "An error occurred", + "item.edit.metadata.notifications.error.title": "একটি ত্রুটি ঘটেছে", + + // "item.edit.metadata.notifications.invalid.content": "Your changes were not saved. Please make sure all fields are valid before you save.", + "item.edit.metadata.notifications.invalid.content": "আপনার পরিবর্তন সংরক্ষিত ছিল না। আপনি সংরক্ষণ করার আগে সমস্ত ক্ষেত্র বৈধ নিশ্চিত করুন দয়া করে।", + + // "item.edit.metadata.notifications.invalid.title": "Metadata invalid", + "item.edit.metadata.notifications.invalid.title": "মেটাডেটা অবৈধ", + + // "item.edit.metadata.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", + "item.edit.metadata.notifications.outdated.content": "আপনি বর্তমানে কাজ করছেন এমন আইটেমটি অন্য ব্যবহারকারী দ্বারা পরিবর্তিত হয়েছে। আপনার বর্তমান পরিবর্তন দ্বন্দ্ব প্রতিরোধ করতে বাতিল করা হয়", + + // "item.edit.metadata.notifications.outdated.title": "Changed outdated", + "item.edit.metadata.notifications.outdated.title": "পরিবর্তিত হয়েছে", + + // "item.edit.metadata.notifications.saved.content": "Your changes to this item's metadata were saved.", + "item.edit.metadata.notifications.saved.content": "এই আইটেমটি এর মেটাডেটা আপনার পরিবর্তন সংরক্ষিত ছিল।", + + // "item.edit.metadata.notifications.saved.title": "Metadata saved", + "item.edit.metadata.notifications.saved.title": "মেটাডেটা সংরক্ষিত", + + // "item.edit.metadata.reinstate-button": "Undo", + "item.edit.metadata.reinstate-button": "পূর্বাবস্থায় ফেরানো", + + // "item.edit.metadata.save-button": "Save", + "item.edit.metadata.save-button": "সংরক্ষণ", + + + + // "item.edit.modify.overview.field": "Field", + "item.edit.modify.overview.field": "মাঠ", + + // "item.edit.modify.overview.language": "Language", + "item.edit.modify.overview.language": "ভাষা", + + // "item.edit.modify.overview.value": "Value", + "item.edit.modify.overview.value": "মূল্য", + + + + // "item.edit.move.cancel": "Back", + "item.edit.move.cancel": "পেছনে", + + // "item.edit.move.save-button": "Save", + "item.edit.move.save-button": "সংরক্ষণ", + + // "item.edit.move.discard-button": "Discard", + "item.edit.move.discard-button": "বাতিল করা", + + // "item.edit.move.description": "Select the collection you wish to move this item to. To narrow down the list of displayed collections, you can enter a search query in the box.", + "item.edit.move.description": "আপনি এই আইটেমটি সরানো করতে চান সংগ্রহ করুন নির্বাচন করুন। প্রদর্শিত সংগ্রহগুলির তালিকাটি সংকীর্ণ করার জন্য আপনি বাক্সে একটি অনুসন্ধান অনুসন্ধান করতে পারেন।", + + // "item.edit.move.error": "An error occurred when attempting to move the item", + "item.edit.move.error": "আইটেমটি সরানোর চেষ্টা করার সময় একটি ত্রুটি ঘটেছে", + + // "item.edit.move.head": "Move item: {{id}}", + "item.edit.move.head": "আইটেম সরান: {{id}}", + + // "item.edit.move.inheritpolicies.checkbox": "Inherit policies", + "item.edit.move.inheritpolicies.checkbox": "নীতি উত্তরাধিকারী", + + // "item.edit.move.inheritpolicies.description": "Inherit the default policies of the destination collection", + "item.edit.move.inheritpolicies.description": "গন্তব্য সংগ্রহের ডিফল্ট নীতিগুলি উত্তরাধিকারী", + + // "item.edit.move.move": "Move", + "item.edit.move.move": "সরানো", + + // "item.edit.move.processing": "Moving...", + "item.edit.move.processing": "চলন্ত ...", + + // "item.edit.move.search.placeholder": "Enter a search query to look for collections", + "item.edit.move.search.placeholder": "সংগ্রহের জন্য সন্ধান করার জন্য একটি অনুসন্ধান অনুসন্ধান লিখুন", + + // "item.edit.move.success": "The item has been moved successfully", + "item.edit.move.success": "আইটেম সফলভাবে সরানো হয়েছে", + + // "item.edit.move.title": "Move item", + "item.edit.move.title": "আইটেমটি সরান", + + + + // "item.edit.private.cancel": "Cancel", + "item.edit.private.cancel": "বাতিল করুন", + + // "item.edit.private.confirm": "Make it Private", + "item.edit.private.confirm": "এটা ব্যক্তিগত করা", + + // "item.edit.private.description": "Are you sure this item should be made private in the archive?", + "item.edit.private.description": "আপনি এই আইটেমটি সংরক্ষণাগার মধ্যে ব্যক্তিগত করা উচিত কি নিশ্চিত?", + + // "item.edit.private.error": "An error occurred while making the item private", + "item.edit.private.error": "আইটেম ব্যক্তিগত করার সময় একটি ত্রুটি ঘটেছে", + + // "item.edit.private.header": "Make item private: {{ id }}", + "item.edit.private.header": "আইটেম ব্যক্তিগত করুন: {{ id }}", + + // "item.edit.private.success": "The item is now private", + "item.edit.private.success": "আইটেম এখন ব্যক্তিগত", + + + + // "item.edit.public.cancel": "Cancel", + "item.edit.public.cancel": "বাতিল করুন", + + // "item.edit.public.confirm": "Make it Public", + "item.edit.public.confirm": "এটা পাবলিক করা", + + // "item.edit.public.description": "Are you sure this item should be made public in the archive?", + "item.edit.public.description": "আপনি কি নিশ্চিত এই আইটেমটি সংরক্ষণাগার মধ্যে পাবলিক করা উচিত?", + + // "item.edit.public.error": "An error occurred while making the item public", + "item.edit.public.error": "আইটেমটি জনসাধারণের কাছে একটি ত্রুটি ঘটেছে", + + // "item.edit.public.header": "Make item public: {{ id }}", + "item.edit.public.header": "আইটেম সর্বজনীন করুন: {{ id }}", + + // "item.edit.public.success": "The item is now public", + "item.edit.public.success": "আইটেম এখন পাবলিক", + + + + // "item.edit.reinstate.cancel": "Cancel", + "item.edit.reinstate.cancel": "বাতিল করুন", + + // "item.edit.reinstate.confirm": "Reinstate", + "item.edit.reinstate.confirm": "পুনঃস্থাপন", + + // "item.edit.reinstate.description": "Are you sure this item should be reinstated to the archive?", + "item.edit.reinstate.description": "আপনি কি নিশ্চিত যে এই আইটেমটি সংরক্ষণাগারটি পুনঃস্থাপন করা উচিত?", + + // "item.edit.reinstate.error": "An error occurred while reinstating the item", + "item.edit.reinstate.error": "আইটেমটি পুনঃস্থাপন করার সময় একটি ত্রুটি ঘটেছে", + + // "item.edit.reinstate.header": "Reinstate item: {{ id }}", + "item.edit.reinstate.header": "আইটেম পুনঃস্থাপন: {{ id }}", + + // "item.edit.reinstate.success": "The item was reinstated successfully", + "item.edit.reinstate.success": "আইটেম সফলভাবে পুনর্বহাল করা হয়", + + + + // "item.edit.relationships.discard-button": "Discard", + "item.edit.relationships.discard-button": "বাতিল করা", + + // "item.edit.relationships.edit.buttons.add": "Add", + "item.edit.relationships.edit.buttons.add": "যোগ করুন", + + // "item.edit.relationships.edit.buttons.remove": "Remove", + "item.edit.relationships.edit.buttons.remove": "অপসারণ", + + // "item.edit.relationships.edit.buttons.undo": "Undo changes", + "item.edit.relationships.edit.buttons.undo": "পূর্বাবস্থায় ফিরিয়ে আনুন", + + // "item.edit.relationships.no-relationships": "No relationships", + "item.edit.relationships.no-relationships": "কোন সম্পর্ক নেই", + + // "item.edit.relationships.notifications.discarded.content": "Your changes were discarded. To reinstate your changes click the 'Undo' button", + "item.edit.relationships.notifications.discarded.content": "আপনার পরিবর্তন বাতিল করা হয়েছে। আপনার পরিবর্তনগুলি পুনঃস্থাপন করতে 'পূর্বাবস্থায় ফিরুন' বাটনে ক্লিক করুন", + + // "item.edit.relationships.notifications.discarded.title": "Changes discarded", + "item.edit.relationships.notifications.discarded.title": "পরিবর্তন বাতিল করা হয়েছে", + + // "item.edit.relationships.notifications.failed.title": "Error editing relationships", + "item.edit.relationships.notifications.failed.title": "সম্পর্ক সম্পাদনা ত্রুটি", + + // "item.edit.relationships.notifications.outdated.content": "The item you're currently working on has been changed by another user. Your current changes are discarded to prevent conflicts", + "item.edit.relationships.notifications.outdated.content": "আপনি বর্তমানে কাজ করছেন এমন আইটেমটি অন্য ব্যবহারকারী দ্বারা পরিবর্তিত হয়েছে। আপনার বর্তমান পরিবর্তন দ্বন্দ্ব প্রতিরোধ করতে বাতিল করা হয়", + + // "item.edit.relationships.notifications.outdated.title": "Changes outdated", + "item.edit.relationships.notifications.outdated.title": "পরিবর্তিত পরিবর্তন", + + // "item.edit.relationships.notifications.saved.content": "Your changes to this item's relationships were saved.", + "item.edit.relationships.notifications.saved.content": "এই আইটেমটির সম্পর্কগুলিতে আপনার পরিবর্তনগুলি সংরক্ষণ করা হয়েছে।", + + // "item.edit.relationships.notifications.saved.title": "Relationships saved", + "item.edit.relationships.notifications.saved.title": "সম্পর্ক সংরক্ষিত", + + // "item.edit.relationships.reinstate-button": "Undo", + "item.edit.relationships.reinstate-button": "পূর্বাবস্থায় ফেরানো", + + // "item.edit.relationships.save-button": "Save", + "item.edit.relationships.save-button": "সংরক্ষণ", + + // "item.edit.relationships.no-entity-type": "Add 'dspace.entity.type' metadata to enable relationships for this item", + "item.edit.relationships.no-entity-type": "এই আইটেমটির জন্য সম্পর্ক সক্ষম করতে 'dspace.entity.type' মেটাডেটা যোগ করুন", + + + // "item.edit.return": "Back", + "item.edit.return": "পেছনে", + + + // "item.edit.tabs.bitstreams.head": "Bitstreams", + "item.edit.tabs.bitstreams.head": "বিটস্ট্রিমস", + + // "item.edit.tabs.bitstreams.title": "Item Edit - Bitstreams", + "item.edit.tabs.bitstreams.title": "আইটেম সম্পাদনা - বিটস্ট্রিমস", + + // "item.edit.tabs.curate.head": "Curate", + "item.edit.tabs.curate.head": "কিউরেট.", + + // "item.edit.tabs.curate.title": "Item Edit - Curate", + "item.edit.tabs.curate.title": "আইটেম সম্পাদনা - কিউরেট", + + // "item.edit.tabs.metadata.head": "Metadata", + "item.edit.tabs.metadata.head": "মেটাডেটা", + + // "item.edit.tabs.metadata.title": "Item Edit - Metadata", + "item.edit.tabs.metadata.title": "আইটেম সম্পাদনা - মেটাডাটা", + + // "item.edit.tabs.relationships.head": "Relationships", + "item.edit.tabs.relationships.head": "সম্পর্ক", + + // "item.edit.tabs.relationships.title": "Item Edit - Relationships", + "item.edit.tabs.relationships.title": "আইটেম সম্পাদনা - সম্পর্ক", + + // "item.edit.tabs.status.buttons.authorizations.button": "Authorizations...", + "item.edit.tabs.status.buttons.authorizations.button": "অনুমোদন ...", + + // "item.edit.tabs.status.buttons.authorizations.label": "Edit item's authorization policies", + "item.edit.tabs.status.buttons.authorizations.label": "আইটেম এর অনুমোদন নীতি সম্পাদনা করুন", + + // "item.edit.tabs.status.buttons.delete.button": "Permanently delete", + "item.edit.tabs.status.buttons.delete.button": "স্থায়ীভাবে মুছে দিন", + + // "item.edit.tabs.status.buttons.delete.label": "Completely expunge item", + "item.edit.tabs.status.buttons.delete.label": "সম্পূর্ণরূপে আইটেম এক্সপোজ করুন", + + // "item.edit.tabs.status.buttons.mappedCollections.button": "Mapped collections", + "item.edit.tabs.status.buttons.mappedCollections.button": "ম্যাপ সংগ্রহ", + + // "item.edit.tabs.status.buttons.mappedCollections.label": "Manage mapped collections", + "item.edit.tabs.status.buttons.mappedCollections.label": "ম্যাপড সংগ্রহ পরিচালনা করুন", + + // "item.edit.tabs.status.buttons.move.button": "Move...", + "item.edit.tabs.status.buttons.move.button": "সরানো ...", + + // "item.edit.tabs.status.buttons.move.label": "Move item to another collection", + "item.edit.tabs.status.buttons.move.label": "অন্য সংগ্রহে আইটেমটি সরান", + + // "item.edit.tabs.status.buttons.private.button": "Make it private...", + "item.edit.tabs.status.buttons.private.button": "এটা ব্যক্তিগত করা ...", + + // "item.edit.tabs.status.buttons.private.label": "Make item private", + "item.edit.tabs.status.buttons.private.label": "আইটেম ব্যক্তিগত করা", + + // "item.edit.tabs.status.buttons.public.button": "Make it public...", + "item.edit.tabs.status.buttons.public.button": "এটা পাবলিক করা ...", + + // "item.edit.tabs.status.buttons.public.label": "Make item public", + "item.edit.tabs.status.buttons.public.label": "আইটেম পাবলিক করুন", + + // "item.edit.tabs.status.buttons.reinstate.button": "Reinstate...", + "item.edit.tabs.status.buttons.reinstate.button": "পুনঃস্থাপন ...", + + // "item.edit.tabs.status.buttons.reinstate.label": "Reinstate item into the repository", + "item.edit.tabs.status.buttons.reinstate.label": "রিপোজিটরি মধ্যে আইটেম পুনর্বহাল", + + // "item.edit.tabs.status.buttons.unauthorized": "You're not authorized to perform this action", + "item.edit.tabs.status.buttons.unauthorized": "আপনি এই অ্যাকশন সঞ্চালন করার জন্য অনুমোদিত না", + + // "item.edit.tabs.status.buttons.withdraw.button": "Withdraw...", + "item.edit.tabs.status.buttons.withdraw.button": "প্রত্যাহার ...", + + // "item.edit.tabs.status.buttons.withdraw.label": "Withdraw item from the repository", + "item.edit.tabs.status.buttons.withdraw.label": "সংগ্রহস্থল থেকে আইটেম প্রত্যাহার", + + // "item.edit.tabs.status.description": "Welcome to the item management page. From here you can withdraw, reinstate, move or delete the item. You may also update or add new metadata / bitstreams on the other tabs.", + "item.edit.tabs.status.description": "আইটেম ম্যানেজমেন্ট পেজে স্বাগতম। এখানে থেকে আপনি আইটেমটি সরানো বা আইটেমটি মুছে ফেলতে পারেন। আপনি অন্যান্য ট্যাবে নতুন মেটাডেটা / বিটস্ট্রিমগুলি আপডেট বা যোগ করতে পারেন।", + + // "item.edit.tabs.status.head": "Status", + "item.edit.tabs.status.head": "অবস্থা", + + // "item.edit.tabs.status.labels.handle": "Handle", + "item.edit.tabs.status.labels.handle": "হাতল", + + // "item.edit.tabs.status.labels.id": "Item Internal ID", + "item.edit.tabs.status.labels.id": "আইটেম অভ্যন্তরীণ আইডি", + + // "item.edit.tabs.status.labels.itemPage": "Item Page", + "item.edit.tabs.status.labels.itemPage": "আইটেম পৃষ্ঠা", + + // "item.edit.tabs.status.labels.lastModified": "Last Modified", + "item.edit.tabs.status.labels.lastModified": "সর্বশেষ পরিবর্তিত", + + // "item.edit.tabs.status.title": "Item Edit - Status", + "item.edit.tabs.status.title": "আইটেম সম্পাদনা - স্থিতি", + + // "item.edit.tabs.versionhistory.head": "Version History", + "item.edit.tabs.versionhistory.head": "সংস্করণ ইতিহাস", + + // "item.edit.tabs.versionhistory.title": "Item Edit - Version History", + "item.edit.tabs.versionhistory.title": "আইটেম সম্পাদনা - সংস্করণ ইতিহাস", + + // "item.edit.tabs.versionhistory.under-construction": "Editing or adding new versions is not yet possible in this user interface.", + "item.edit.tabs.versionhistory.under-construction": "সম্পাদনা বা নতুন সংস্করণ যোগ করা এই ব্যবহারকারী ইন্টারফেসে এখনো সম্ভব নয়।", + + // "item.edit.tabs.view.head": "View Item", + "item.edit.tabs.view.head": "দেখুন আইটেম", + + // "item.edit.tabs.view.title": "Item Edit - View", + "item.edit.tabs.view.title": "আইটেম সম্পাদনা - দেখুন", + + + + // "item.edit.withdraw.cancel": "Cancel", + "item.edit.withdraw.cancel": "বাতিল করুন", + + // "item.edit.withdraw.confirm": "Withdraw", + "item.edit.withdraw.confirm": "প্রত্যাহার করুন", + + // "item.edit.withdraw.description": "Are you sure this item should be withdrawn from the archive?", + "item.edit.withdraw.description": "আপনি কি নিশ্চিত যে এই আইটেমটি সংরক্ষণাগার থেকে প্রত্যাহার করা উচিত?", + + // "item.edit.withdraw.error": "An error occurred while withdrawing the item", + "item.edit.withdraw.error": "আইটেমটি প্রত্যাহারের সময় একটি ত্রুটি ঘটেছে", + + // "item.edit.withdraw.header": "Withdraw item: {{ id }}", + "item.edit.withdraw.header": "প্রত্যাহার আইটেম: {{ id }}", + + // "item.edit.withdraw.success": "The item was withdrawn successfully", + "item.edit.withdraw.success": "আইটেম সফলভাবে প্রত্যাহার করা হয়", + + + + // "item.listelement.badge": "Item", + "item.listelement.badge": "আইটেম", + + // "item.page.description": "Description", + "item.page.description": "বর্ণনা", + + // "item.page.journal-issn": "Journal ISSN", + "item.page.journal-issn": "জার্নাল ইশান", + + // "item.page.journal-title": "Journal Title", + "item.page.journal-title": "জার্নাল শিরোনাম", + + // "item.page.publisher": "Publisher", + "item.page.publisher": "প্রকাশক", + + // "item.page.titleprefix": "Item: ", + "item.page.titleprefix": "আইটেম: ", + + // "item.page.volume-title": "Volume Title", + "item.page.volume-title": "ভলিউম শিরোনাম", + + // "item.search.results.head": "Item Search Results", + "item.search.results.head": "আইটেম অনুসন্ধান ফলাফল", + + // "item.search.title": "Item Search", + "item.search.title": "আইটেম অনুসন্ধান", + + + + // "item.page.abstract": "Abstract", + "item.page.abstract": "বিমূর্ত", + + // "item.page.author": "Authors", + "item.page.author": "লেখক", + + // "item.page.citation": "Citation", + "item.page.citation": "উদ্ধৃতি", + + // "item.page.collections": "Collections", + "item.page.collections": "সংগ্রহগুলি", + + // "item.page.collections.loading": "Loading...", + "item.page.collections.loading": "লোড হচ্ছে ...", + + // "item.page.collections.load-more": "Load more", + "item.page.collections.load-more": "আর ঢুকাও", + + // "item.page.date": "Date", + "item.page.date": "তারিখ.", + + // "item.page.edit": "Edit this item", + "item.page.edit": "এই আইটেমটি সম্পাদনা করুন", + + // "item.page.files": "Files", + "item.page.files": "নথি পত্র", + + // "item.page.filesection.description": "Description:", + "item.page.filesection.description": "বর্ণনা:", + + // "item.page.filesection.download": "Download", + "item.page.filesection.download": "ডাউনলোড করুন", + + // "item.page.filesection.format": "Format:", + "item.page.filesection.format": "বিন্যাস:", + + // "item.page.filesection.name": "Name:", + "item.page.filesection.name": "নাম:", + + // "item.page.filesection.size": "Size:", + "item.page.filesection.size": "আকার:", + + // "item.page.journal.search.title": "Articles in this journal", + "item.page.journal.search.title": "এই জার্নাল নিবন্ধ", + + // "item.page.link.full": "Full item page", + "item.page.link.full": "সম্পূর্ণ আইটেম পৃষ্ঠা", + + // "item.page.link.simple": "Simple item page", + "item.page.link.simple": "সহজ আইটেম পৃষ্ঠা", + + // "item.page.person.search.title": "Articles by this author", + "item.page.person.search.title": "এই লেখক দ্বারা প্রবন্ধ", + + // "item.page.related-items.view-more": "Show {{ amount }} more", + "item.page.related-items.view-more": "আরো দেখান {{amount}} আরো", + + // "item.page.related-items.view-less": "Hide last {{ amount }}", + "item.page.related-items.view-less": "শেষ {{amount}} লুকান", + + // "item.page.relationships.isAuthorOfPublication": "Publications", + "item.page.relationships.isAuthorOfPublication": "প্রকাশনা", + + // "item.page.relationships.isJournalOfPublication": "Publications", + "item.page.relationships.isJournalOfPublication": "প্রকাশনা", + + // "item.page.relationships.isOrgUnitOfPerson": "Authors", + "item.page.relationships.isOrgUnitOfPerson": "লেখক", + + // "item.page.relationships.isOrgUnitOfProject": "Research Projects", + "item.page.relationships.isOrgUnitOfProject": "গবেষণা প্রকল্প", + + // "item.page.subject": "Keywords", + "item.page.subject": "কীওয়ার্ড", + + // "item.page.uri": "URI", + "item.page.uri": "ঘৃণা", + + // "item.page.bitstreams.view-more": "Show more", + "item.page.bitstreams.view-more": "আরো দেখুন", + + // "item.page.bitstreams.collapse": "Collapse", + "item.page.bitstreams.collapse": "ধৈর্য", + + // "item.page.filesection.original.bundle" : "Original bundle", + "item.page.filesection.original.bundle" : "আসল বান্ডিল", + + // "item.page.filesection.license.bundle" : "License bundle", + "item.page.filesection.license.bundle" : "লাইসেন্স বান্ডিল", + + // "item.page.return": "Back", + "item.page.return": "পেছনে", + + // "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": "একটি নতুন সংস্করণ তৈরি করা যাচ্ছে না কারণ ভার্সন হিস্ট্রিতে একটি জমা ইনপ্রগ্রেসস অবস্থাই রয়েছে", + + // "item.preview.dc.identifier.uri": "Identifier:", + "item.preview.dc.identifier.uri": "শনাক্তকারী:", + + // "item.preview.dc.contributor.author": "Authors:", + "item.preview.dc.contributor.author": "লেখক:", + + // "item.preview.dc.date.issued": "Published date:", + "item.preview.dc.date.issued": "প্রকাশের তারিখ:", + + // "item.preview.dc.description.abstract": "Abstract:", + "item.preview.dc.description.abstract": "সংক্ষিপ্তসার:", + + // "item.preview.dc.identifier.other": "Other identifier:", + "item.preview.dc.identifier.other": "অন্য শনাক্তকারী:", + + // "item.preview.dc.language.iso": "Language:", + "item.preview.dc.language.iso": "ভাষা:", + + // "item.preview.dc.subject": "Subjects:", + "item.preview.dc.subject": "বিষয়:", + + // "item.preview.dc.title": "Title:", + "item.preview.dc.title": "শিরোনাম:", + + // "item.preview.person.familyName": "Surname:", + "item.preview.person.familyName": "পদবি:", + + // "item.preview.person.givenName": "Name:", + "item.preview.person.givenName": "নাম:", + + // "item.preview.person.identifier.orcid": "ORCID:", + "item.preview.person.identifier.orcid": "ওআরসিআইডি:", + + // "item.preview.project.funder.name": "Funder:", + "item.preview.project.funder.name": "ফান্ডার:", + + // "item.preview.project.funder.identifier": "Funder Identifier:", + "item.preview.project.funder.identifier": "ফান্ডার শনাক্তকারী:", + + // "item.preview.oaire.awardNumber": "Funding ID:", + "item.preview.oaire.awardNumber": "ফান্ডিং আইডি:", + + // "item.preview.dc.title.alternative": "Acronym:", + "item.preview.dc.title.alternative": "সংক্ষিপ্ত রূপ:", + + // "item.preview.dc.coverage.spatial": "Jurisdiction:", + "item.preview.dc.coverage.spatial": "এখতিয়ার:", + + // "item.preview.oaire.fundingStream": "Funding Stream:", + "item.preview.oaire.fundingStream": "ফান্ডিং স্ট্রীম:", + + + + // "item.select.confirm": "Confirm selected", + "item.select.confirm": "নির্বাচিত নিশ্চিত করুন", + + // "item.select.empty": "No items to show", + "item.select.empty": "কোন আইটেম দেখাতে", + + // "item.select.table.author": "Author", + "item.select.table.author": "লেখক", + + // "item.select.table.collection": "Collection", + "item.select.table.collection": "সংগ্রহ", + + // "item.select.table.title": "Title", + "item.select.table.title": "শিরোনাম", + + + // "item.version.history.empty": "There are no other versions for this item yet.", + "item.version.history.empty": "এখনো এই আইটেমটি জন্য অন্য কোন সংস্করণ নেই।", + + // "item.version.history.head": "Version History", + "item.version.history.head": "সংস্করণ ইতিহাস", + + // "item.version.history.return": "Back", + "item.version.history.return": "পেছনে", + + // "item.version.history.selected": "Selected version", + "item.version.history.selected": "নির্বাচিত সংস্করণ", + + // "item.version.history.selected.alert": "You are currently viewing version {{version}} of the item.", + "item.version.history.selected.alert": "আপনি বর্তমানে {{version}} এর সংস্করণটি দেখছেন।", + + // "item.version.history.table.version": "Version", + "item.version.history.table.version": "সংস্করণ.", + + // "item.version.history.table.item": "Item", + "item.version.history.table.item": "আইটেম", + + // "item.version.history.table.editor": "Editor", + "item.version.history.table.editor": "সম্পাদক", + + // "item.version.history.table.date": "Date", + "item.version.history.table.date": "তারিখ.", + + // "item.version.history.table.summary": "Summary", + "item.version.history.table.summary": "সারসংক্ষেপ", + + // "item.version.history.table.workspaceItem": "Workspace item", + "item.version.history.table.workspaceItem": "ওয়ার্কস্পেস আইটেম", + + // "item.version.history.table.workflowItem": "Workflow item", + "item.version.history.table.workflowItem": "ওয়ার্কফ্লো আইটেম", + + // "item.version.history.table.actions": "Action", + "item.version.history.table.actions": "অ্যাকশন", + + // "item.version.history.table.action.editWorkspaceItem": "Edit workspace item", + "item.version.history.table.action.editWorkspaceItem": "ওয়ার্কস্পেস আইটেম সম্পাদনা করুন", + + // "item.version.history.table.action.editSummary": "Edit summary", + "item.version.history.table.action.editSummary": "Sumary সম্পাদনা করুন", + + // "item.version.history.table.action.saveSummary": "Save summary edits", + "item.version.history.table.action.saveSummary": "সারাংশ সম্পাদনা সংরক্ষণ করুন", + + // "item.version.history.table.action.discardSummary": "Discard summary edits", + "item.version.history.table.action.discardSummary": "সংক্ষিপ্ত তালিকা বাতিল করুন", + + // "item.version.history.table.action.newVersion": "Create new version from this one", + "item.version.history.table.action.newVersion": "এই এক থেকে নতুন সংস্করণ তৈরি করুন", + + // "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": "একটি নতুন সংস্করণ তৈরি করা যাচ্ছে না কারণ ভার্সন হিস্ট্রিতে একটি জমা ইনপ্রগ্রেসস অবস্থাই রয়েছে", + + + // "item.version.notice": "This is not the latest version of this item. The latest version can be found here.", + "item.version.notice": "এটি এই আইটেমটির সর্বশেষ সংস্করণ নয়। সর্বশেষ সংস্করণটি পাওয়া যাবে ।", + + + // "item.version.create.modal.header": "New version", + "item.version.create.modal.header": "নতুন সংস্করণ", + + // "item.version.create.modal.text": "Create a new version for this item", + "item.version.create.modal.text": "এই আইটেমটি জন্য একটি নতুন সংস্করণ তৈরি করুন", + + // "item.version.create.modal.text.startingFrom": "starting from version {{version}}", + "item.version.create.modal.text.startingFrom": "সংস্করণ থেকে শুরু হচ্ছে {{version}}", + + // "item.version.create.modal.button.confirm": "Create", + "item.version.create.modal.button.confirm": "সৃষ্টি", + + // "item.version.create.modal.button.confirm.tooltip": "Create new version", + "item.version.create.modal.button.confirm.tooltip": "নতুন সংস্করণ তৈরি করুন", + + // "item.version.create.modal.button.cancel": "Cancel", + "item.version.create.modal.button.cancel": "বাতিল করুন", + + // "item.version.create.modal.button.cancel.tooltip": "Do not create new version", + "item.version.create.modal.button.cancel.tooltip": "নতুন সংস্করণ তৈরি করবেন না", + + // "item.version.create.modal.form.summary.label": "Summary", + "item.version.create.modal.form.summary.label": "সারসংক্ষেপ", + + // "item.version.create.modal.form.summary.placeholder": "Insert the summary for the new version", + "item.version.create.modal.form.summary.placeholder": "নতুন সংস্করণের জন্য সারাংশ সন্নিবেশ করান", + + // "item.version.create.notification.success" : "New version has been created with version number {{version}}", + "item.version.create.notification.success" : "সংস্করণ নম্বর {{version}} দিয়ে নতুন সংস্করণ তৈরি করা হয়েছে", + + // "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" : "একটি নতুন সংস্করণ তৈরি করা যাবে না কারণ ভার্সন হিস্ট্রিতে একটি জমা ইনপ্রগ্রেসস অবস্থাই রয়েছে", + + + // "item.version.delete.modal.header": "Delete version", + "item.version.delete.modal.header": "সংস্করণ মুছে ফেলুন", + + // "item.version.delete.modal.text": "Do you want to delete version {{version}}?", + "item.version.delete.modal.text": "আপনি সংস্করণ মুছে ফেলতে চান {{version}}?", + + // "item.version.delete.modal.button.confirm": "Delete", + "item.version.delete.modal.button.confirm": "মুছে ফেলা", + + // "item.version.delete.modal.button.confirm.tooltip": "Delete this version", + "item.version.delete.modal.button.confirm.tooltip": "এই সংস্করণ মুছে দিন", + + // "item.version.delete.modal.button.cancel": "Cancel", + "item.version.delete.modal.button.cancel": "বাতিল করুন", + + // "item.version.delete.modal.button.cancel.tooltip": "Do not delete this version", + "item.version.delete.modal.button.cancel.tooltip": "এই সংস্করণ মুছে ফেলবেন না", + + // "item.version.delete.notification.success" : "Version number {{version}} has been deleted", + "item.version.delete.notification.success" : "সংস্করণ নম্বর {{version}} মুছে ফেলা হয়েছে", + + // "item.version.delete.notification.failure" : "Version number {{version}} has not been deleted", + "item.version.delete.notification.failure" : "সংস্করণ নম্বর {{version}} মুছে ফেলা হয়নি", + + + // "item.version.edit.notification.success" : "The summary of version number {{version}} has been changed", + "item.version.edit.notification.success" : "সংস্করণ নম্বর {{version}}-এর সারাংশ পরিবর্তন করা হয়েছে", + + // "item.version.edit.notification.failure" : "The summary of version number {{version}} has not been changed", + "item.version.edit.notification.failure" : "সংস্করণ নম্বর {{version}}-এর সারাংশ পরিবর্তন করা হয়নি", + + + + // "journal.listelement.badge": "Journal", + "journal.listelement.badge": "জার্নাল", + + // "journal.page.description": "Description", + "journal.page.description": "বর্ণনা", + + // "journal.page.edit": "Edit this item", + "journal.page.edit": "এই আইটেমটি সম্পাদনা করুন", + + // "journal.page.editor": "Editor-in-Chief", + "journal.page.editor": "প্রধান সম্পাদক", + + // "journal.page.issn": "ISSN", + "journal.page.issn": "ISSN", + + // "journal.page.publisher": "Publisher", + "journal.page.publisher": "প্রকাশক", + + // "journal.page.titleprefix": "Journal: ", + "journal.page.titleprefix": "জার্নাল: ", + + // "journal.search.results.head": "Journal Search Results", + "journal.search.results.head": "জার্নাল অনুসন্ধান ফলাফল", + + // "journal.search.title": "Journal Search", + "journal.search.title": "জার্নাল অনুসন্ধান", + + + + // "journalissue.listelement.badge": "Journal Issue", + "journalissue.listelement.badge": "জার্নাল ইস্যু", + + // "journalissue.page.description": "Description", + "journalissue.page.description": "বর্ণনা", + + // "journalissue.page.edit": "Edit this item", + "journalissue.page.edit": "এই আইটেমটি সম্পাদনা করুন", + + // "journalissue.page.issuedate": "Issue Date", + "journalissue.page.issuedate": "প্রদানের তারিখ", + + // "journalissue.page.journal-issn": "Journal ISSN", + "journalissue.page.journal-issn": "জার্নাল ইশান", + + // "journalissue.page.journal-title": "Journal Title", + "journalissue.page.journal-title": "জার্নাল শিরোনাম", + + // "journalissue.page.keyword": "Keywords", + "journalissue.page.keyword": "কীওয়ার্ড", + + // "journalissue.page.number": "Number", + "journalissue.page.number": "সংখ্যা", + + // "journalissue.page.titleprefix": "Journal Issue: ", + "journalissue.page.titleprefix": "জার্নাল ইস্যু: ", + + + + // "journalvolume.listelement.badge": "Journal Volume", + "journalvolume.listelement.badge": "জার্নাল ভলিউম", + + // "journalvolume.page.description": "Description", + "journalvolume.page.description": "বর্ণনা", + + // "journalvolume.page.edit": "Edit this item", + "journalvolume.page.edit": "এই আইটেমটি সম্পাদনা করুন", + + // "journalvolume.page.issuedate": "Issue Date", + "journalvolume.page.issuedate": "প্রদানের তারিখ", + + // "journalvolume.page.titleprefix": "Journal Volume: ", + "journalvolume.page.titleprefix": "জার্নাল ভলিউম: ", + + // "journalvolume.page.volume": "Volume", + "journalvolume.page.volume": "ভলিউম", + + + // "iiifsearchable.listelement.badge": "Document Media", + "iiifsearchable.listelement.badge": "ডকুমেন্ট মিডিয়া", + + // "iiifsearchable.page.titleprefix": "Document: ", + "iiifsearchable.page.titleprefix": "দলিল: ", + + // "iiifsearchable.page.doi": "Permanent Link: ", + "iiifsearchable.page.doi": "স্থায়ী লিঙ্ক: ", + + // "iiifsearchable.page.issue": "Issue: ", + "iiifsearchable.page.issue": "সমস্যা: ", + + // "iiifsearchable.page.description": "Description: ", + "iiifsearchable.page.description": "বর্ণনা: ", + + // "iiifviewer.fullscreen.notice": "Use full screen for better viewing.", + "iiifviewer.fullscreen.notice": "ভাল দেখার জন্য পূর্ণ পর্দা ব্যবহার করুন।", + + // "iiif.listelement.badge": "Image Media", + "iiif.listelement.badge": "ছবি মিডিয়া", + + // "iiif.page.titleprefix": "Image: ", + "iiif.page.titleprefix": "ছবি: ", + + // "iiif.page.doi": "Permanent Link: ", + "iiif.page.doi": "স্থায়ী লিঙ্ক: ", + + // "iiif.page.issue": "Issue: ", + "iiif.page.issue": "সমস্যা: ", + + // "iiif.page.description": "Description: ", + "iiif.page.description": "বর্ণনা: ", + + + // "loading.bitstream": "Loading bitstream...", + "loading.bitstream": "বিটস্ট্রিম লোড হচ্ছে ...", + + // "loading.bitstreams": "Loading bitstreams...", + "loading.bitstreams": "বিটস্ট্রিম লোড হচ্ছে ...", + + // "loading.browse-by": "Loading items...", + "loading.browse-by": "লোড হচ্ছে আইটেম ...", + + // "loading.browse-by-page": "Loading page...", + "loading.browse-by-page": "লোড হচ্ছে পাতা ...", + + // "loading.collection": "Loading collection...", + "loading.collection": "লোড হচ্ছে সংগ্রহ ...", + + // "loading.collections": "Loading collections...", + "loading.collections": "লোড হচ্ছে সংগ্রহ ...", + + // "loading.content-source": "Loading content source...", + "loading.content-source": "কন্টেন্ট উৎস লোড হচ্ছে ...", + + // "loading.community": "Loading community...", + "loading.community": "কমিউনিটি লোড হচ্ছে ...", + + // "loading.default": "Loading...", + "loading.default": "লোড হচ্ছে ...", + + // "loading.item": "Loading item...", + "loading.item": "লোড হচ্ছে আইটেম ...", + + // "loading.items": "Loading items...", + "loading.items": "লোড হচ্ছে আইটেম ...", + + // "loading.mydspace-results": "Loading items...", + "loading.mydspace-results": "লোড হচ্ছে আইটেম ...", + + // "loading.objects": "Loading...", + "loading.objects": "লোড হচ্ছে ...", + + // "loading.recent-submissions": "Loading recent submissions...", + "loading.recent-submissions": "সাম্প্রতিক জমাগুলো লোড হচ্ছে ...", + + // "loading.search-results": "Loading search results...", + "loading.search-results": "অনুসন্ধানের ফলাফল লোড হচ্ছে ...", + + // "loading.sub-collections": "Loading sub-collections...", + "loading.sub-collections": "উপ-সংগ্রহগুলো লোড হচ্ছে ...", + + // "loading.sub-communities": "Loading sub-communities...", + "loading.sub-communities": "উপ-সম্প্রদায়গুলো লোড হচ্ছে ...", + + // "loading.top-level-communities": "Loading top-level communities...", + "loading.top-level-communities": "শীর্ষ-স্তরের সম্প্রদায়গুলো লোড হচ্ছে ...", + + + + // "login.form.email": "Email address", + "login.form.email": "ইমেইল ঠিকানা", + + // "login.form.forgot-password": "Have you forgotten your password?", + "login.form.forgot-password": "আপনি আপনার পাসওয়ার্ড ভুলে গেছেন?", + + // "login.form.header": "Please log in to DSpace", + "login.form.header": "ডিস্পেস লগ ইন করুন", + + // "login.form.new-user": "New user? Click here to register.", + "login.form.new-user": "নতুন ব্যবহারকারী? নিবন্ধন করতে এখানে ক্লিক করুন।", + + // "login.form.or-divider": "or", + "login.form.or-divider": "অথবা", + + // "login.form.oidc": "Log in with OIDC", + "login.form.oidc": "OIDC সঙ্গে লগ ইন করুন", + + // "login.form.password": "Password", + "login.form.password": "পাসওয়ার্ড", + + // "login.form.shibboleth": "Log in with Shibboleth", + "login.form.shibboleth": "Shibboleth এর সঙ্গে লগ ইন করুন", + + // "login.form.submit": "Log in", + "login.form.submit": "প্রবেশ করুন", + + // "login.title": "Login", + "login.title": "প্রবেশ করুন", + + // "login.breadcrumbs": "Login", + "login.breadcrumbs": "প্রবেশ করুন", + + + + // "logout.form.header": "Log out from DSpace", + "logout.form.header": "ডিস্পেস থেকে লগ আউট করুন", + + // "logout.form.submit": "Log out", + "logout.form.submit": "প্রস্থান", + + // "logout.title": "Logout", + "logout.title": "প্রস্থান", + + + + // "menu.header.admin": "Management", + "menu.header.admin": "ব্যবস্থাপনা", + + // "menu.header.image.logo": "Repository logo", + "menu.header.image.logo": "রিপোজিটরি লোগো", + + // "menu.header.admin.description": "Management menu", + "menu.header.admin.description": "ম্যানেজমেন্ট মেনু", + + + + // "menu.section.access_control": "Access Control", + "menu.section.access_control": "প্রবেশাধিকার নিয়ন্ত্রণ", + + // "menu.section.access_control_authorizations": "Authorizations", + "menu.section.access_control_authorizations": "অনুমোদনকরণ", + + // "menu.section.access_control_groups": "Groups", + "menu.section.access_control_groups": "গ্রুপ", + + // "menu.section.access_control_people": "People", + "menu.section.access_control_people": "ব্যাক্তি", + + + + // "menu.section.admin_search": "Admin Search", + "menu.section.admin_search": "অ্যাডমিন অনুসন্ধান", + + + + // "menu.section.browse_community": "This Community", + "menu.section.browse_community": "এই সম্প্রদায়", + + // "menu.section.browse_community_by_author": "By Author", + "menu.section.browse_community_by_author": "লেখক দ্বারা", + + // "menu.section.browse_community_by_issue_date": "By Issue Date", + "menu.section.browse_community_by_issue_date": "ইস্যু তারিখ দ্বারা", + + // "menu.section.browse_community_by_title": "By Title", + "menu.section.browse_community_by_title": "শিরোনাম দ্বারা", + + // "menu.section.browse_global": "All of DSpace", + "menu.section.browse_global": "ডিস্পেস এর সবকিছু", + + // "menu.section.browse_global_by_author": "By Author", + "menu.section.browse_global_by_author": "লেখক দ্বারা", + + // "menu.section.browse_global_by_dateissued": "By Issue Date", + "menu.section.browse_global_by_dateissued": "ইস্যু তারিখ দ্বারা", + + // "menu.section.browse_global_by_subject": "By Subject", + "menu.section.browse_global_by_subject": "বিষয় দ্বারা", + + // "menu.section.browse_global_by_title": "By Title", + "menu.section.browse_global_by_title": "শিরোনাম দ্বারা", + + // "menu.section.browse_global_communities_and_collections": "Communities & Collections", + "menu.section.browse_global_communities_and_collections": "সম্প্রদায় ও সংগ্রহ", + + + + // "menu.section.control_panel": "Control Panel", + "menu.section.control_panel": "কন্ট্রোল প্যানেল", + + // "menu.section.curation_task": "Curation Task", + "menu.section.curation_task": "নিরাময় টাস্ক", + + + + // "menu.section.edit": "Edit", + "menu.section.edit": "সম্পাদনা করুন", + + // "menu.section.edit_collection": "Collection", + "menu.section.edit_collection": "সংগ্রহ", + + // "menu.section.edit_community": "Community", + "menu.section.edit_community": "সম্প্রদায়", + + // "menu.section.edit_item": "Item", + "menu.section.edit_item": "আইটেম", + + + + // "menu.section.export": "Export", + "menu.section.export": "এক্সপোর্ট", + + // "menu.section.export_collection": "Collection", + "menu.section.export_collection": "সংগ্রহ", + + // "menu.section.export_community": "Community", + "menu.section.export_community": "সম্প্রদায়", + + // "menu.section.export_item": "Item", + "menu.section.export_item": "আইটেম", + + // "menu.section.export_metadata": "Metadata", + "menu.section.export_metadata": "মেটাডেটা", + + + + // "menu.section.icon.access_control": "Access Control menu section", + "menu.section.icon.access_control": "অ্যাক্সেস কন্ট্রোল মেনু বিভাগ", + + // "menu.section.icon.admin_search": "Admin search menu section", + "menu.section.icon.admin_search": "অ্যাডমিন অনুসন্ধান মেনু বিভাগ", + + // "menu.section.icon.control_panel": "Control Panel menu section", + "menu.section.icon.control_panel": "কন্ট্রোল প্যানেল মেনু বিভাগ", + + // "menu.section.icon.curation_tasks": "Curation Task menu section", + "menu.section.icon.curation_tasks": "নিরাময় টাস্ক মেনু বিভাগ", + + // "menu.section.icon.edit": "Edit menu section", + "menu.section.icon.edit": "মেনু বিভাগ সম্পাদনা করুন", + + // "menu.section.icon.export": "Export menu section", + "menu.section.icon.export": "রপ্তানি মেনু অধ্যায়", + + // "menu.section.icon.find": "Find menu section", + "menu.section.icon.find": "মেনু বিভাগ খুঁজুন", + + // "menu.section.icon.import": "Import menu section", + "menu.section.icon.import": "আমদানি মেনু বিভাগ", + + // "menu.section.icon.new": "New menu section", + "menu.section.icon.new": "নতুন মেনু বিভাগ", + + // "menu.section.icon.pin": "Pin sidebar", + "menu.section.icon.pin": "পিন সাইডবার", + + // "menu.section.icon.processes": "Processes menu section", + "menu.section.icon.processes": "প্রসেস মেনু বিভাগ", + + // "menu.section.icon.registries": "Registries menu section", + "menu.section.icon.registries": "নিবন্ধন মেনু বিভাগ", + + // "menu.section.icon.statistics_task": "Statistics Task menu section", + "menu.section.icon.statistics_task": "পরিসংখ্যান টাস্ক মেনু বিভাগ", + + // "menu.section.icon.workflow": "Administer workflow menu section", + "menu.section.icon.workflow": "প্রশাসনিক কর্মধারা মেনু সেকশন", + + // "menu.section.icon.unpin": "Unpin sidebar", + "menu.section.icon.unpin": "আনপিন সাইডবার", + + + + // "menu.section.import": "Import", + "menu.section.import": "আমদানি", + + // "menu.section.import_batch": "Batch Import (ZIP)", + "menu.section.import_batch": "ব্যাচ আমদানি (ZIP)", + + // "menu.section.import_metadata": "Metadata", + "menu.section.import_metadata": "মেটাডেটা", + + + + // "menu.section.new": "New", + "menu.section.new": "নতুন", + + // "menu.section.new_collection": "Collection", + "menu.section.new_collection": "সংগ্রহ", + + // "menu.section.new_community": "Community", + "menu.section.new_community": "সম্প্রদায়", + + // "menu.section.new_item": "Item", + "menu.section.new_item": "আইটেম", + + // "menu.section.new_item_version": "Item Version", + "menu.section.new_item_version": "আইটেম সংস্করণ", + + // "menu.section.new_process": "Process", + "menu.section.new_process": "প্রক্রিয়া", + + + + // "menu.section.pin": "Pin sidebar", + "menu.section.pin": "পিন সাইডবার", + + // "menu.section.unpin": "Unpin sidebar", + "menu.section.unpin": "আনপিন সাইডবার", + + + + // "menu.section.processes": "Processes", + "menu.section.processes": "প্রসেস.", + + + + // "menu.section.registries": "Registries", + "menu.section.registries": "নিবন্ধন", + + // "menu.section.registries_format": "Format", + "menu.section.registries_format": "বিন্যাস", + + // "menu.section.registries_metadata": "Metadata", + "menu.section.registries_metadata": "মেটাডেটা", + + + + // "menu.section.statistics": "Statistics", + "menu.section.statistics": "পরিসংখ্যান", + + // "menu.section.statistics_task": "Statistics Task", + "menu.section.statistics_task": "পরিসংখ্যান টাস্ক", + + + + // "menu.section.toggle.access_control": "Toggle Access Control section", + "menu.section.toggle.access_control": "অ্যাক্সেস কন্ট্রোল বিভাগ টগল করুন", + + // "menu.section.toggle.control_panel": "Toggle Control Panel section", + "menu.section.toggle.control_panel": "টগল কন্ট্রোল প্যানেল অধ্যায়", + + // "menu.section.toggle.curation_task": "Toggle Curation Task section", + "menu.section.toggle.curation_task": "কুপন টাস্ক বিভাগ টগল করুন", + + // "menu.section.toggle.edit": "Toggle Edit section", + "menu.section.toggle.edit": "সম্পাদনা বিভাগ টগল করুন", + + // "menu.section.toggle.export": "Toggle Export section", + "menu.section.toggle.export": "টগল এক্সপোর্ট বিভাগ", + + // "menu.section.toggle.find": "Toggle Find section", + "menu.section.toggle.find": "টগল করুন বিভাগে", + + // "menu.section.toggle.import": "Toggle Import section", + "menu.section.toggle.import": "আমদানি বিভাগ টগল করুন", + + // "menu.section.toggle.new": "Toggle New section", + "menu.section.toggle.new": "নতুন অধ্যায় টগল করুন", + + // "menu.section.toggle.registries": "Toggle Registries section", + "menu.section.toggle.registries": "নিবন্ধন বিভাগ টগল করুন", + + // "menu.section.toggle.statistics_task": "Toggle Statistics Task section", + "menu.section.toggle.statistics_task": "পরিসংখ্যান টাস্ক বিভাগ টগল করুন", + + + // "menu.section.workflow": "Administer Workflow", + "menu.section.workflow": "প্রশাসনিক কর্মধারা", + + + // "mydspace.breadcrumbs": "MyDSpace", + "mydspace.breadcrumbs": "আমার ডিস্পেস", + + // "mydspace.description": "", + "mydspace.description": "অপসারণ করা আবশ্যক", + + // "mydspace.general.text-here": "here", + "mydspace.general.text-here": "এখানে", + + // "mydspace.messages.controller-help": "Select this option to send a message to item's submitter.", + "mydspace.messages.controller-help": "আইটেমের জমাদানকারীর কাছে একটি বার্তা পাঠাতে এই বিকল্পগুলোর মদ্ধে একটি নির্বাচন করুন।", + + // "mydspace.messages.description-placeholder": "Insert your message here...", + "mydspace.messages.description-placeholder": "এখানে আপনার বার্তা দিন...", + + // "mydspace.messages.hide-msg": "Hide message", + "mydspace.messages.hide-msg": "বার্তা লুকান", + + // "mydspace.messages.mark-as-read": "Mark as read", + "mydspace.messages.mark-as-read": "পঠিত হিসেবে চিহ্নিত করুন", + + // "mydspace.messages.mark-as-unread": "Mark as unread", + "mydspace.messages.mark-as-unread": "অপঠিত হিসাবে চিহ্নিত", + + // "mydspace.messages.no-content": "No content.", + "mydspace.messages.no-content": "কোন উপাদান নেই.", + + // "mydspace.messages.no-messages": "No messages yet.", + "mydspace.messages.no-messages": "এখনো কোন বার্তা নেই।", + + // "mydspace.messages.send-btn": "Send", + "mydspace.messages.send-btn": "পাঠান", + + // "mydspace.messages.show-msg": "Show message", + "mydspace.messages.show-msg": "বার্তা দেখান", + + // "mydspace.messages.subject-placeholder": "Subject...", + "mydspace.messages.subject-placeholder": "বিষয়...", + + // "mydspace.messages.submitter-help": "Select this option to send a message to controller.", + "mydspace.messages.submitter-help": "কন্ট্রোলারের কাছে একটি বার্তা পাঠাতে এই বিকল্পটি নির্বাচন করুন।", + + // "mydspace.messages.title": "Messages", + "mydspace.messages.title": "বার্তা", + + // "mydspace.messages.to": "To", + "mydspace.messages.to": "প্রতি", + + // "mydspace.new-submission": "New submission", + "mydspace.new-submission": "নতুন জমা", + + // "mydspace.new-submission-external": "Import metadata from external source", + "mydspace.new-submission-external": "বহিরাগত উৎস থেকে মেটাডাটা আমদানি করুন", + + // "mydspace.new-submission-external-short": "Import metadata", + "mydspace.new-submission-external-short": "মেটাডেটা আমদানি করুন", + + // "mydspace.results.head": "Your submissions", + "mydspace.results.head": "আপনার জমাগুলো", + + // "mydspace.results.no-abstract": "No Abstract", + "mydspace.results.no-abstract": "কোন বিমূর্ত", + + // "mydspace.results.no-authors": "No Authors", + "mydspace.results.no-authors": "কোন লেখক", + + // "mydspace.results.no-collections": "No Collections", + "mydspace.results.no-collections": "কোন সংগ্রহ", + + // "mydspace.results.no-date": "No Date", + "mydspace.results.no-date": "তারিখ নেই", + + // "mydspace.results.no-files": "No Files", + "mydspace.results.no-files": "কোন ফাইল নেই", + + // "mydspace.results.no-results": "There were no items to show", + "mydspace.results.no-results": "দেখানোর জন্য কোন আইটেম ছিল না", + + // "mydspace.results.no-title": "No title", + "mydspace.results.no-title": "কোনো শিরোনাম নেই", + + // "mydspace.results.no-uri": "No Uri", + "mydspace.results.no-uri": "কোন ইউ আর আই (uri) নেই", + + // "mydspace.search-form.placeholder": "Search in mydspace...", + "mydspace.search-form.placeholder": "আমার ডিস্পেস এর মধ্যে অনুসন্ধান করুন ...", + + // "mydspace.show.workflow": "Workflow tasks", + "mydspace.show.workflow": "ওয়ার্কফ্লো কাজগুলো", + + // "mydspace.show.workspace": "Your Submissions", + "mydspace.show.workspace": "আপনার জমাগুলো", + + // "mydspace.status.archived": "Archived", + "mydspace.status.archived": "সংরক্ষণাগারভুক্ত", + + // "mydspace.status.validation": "Validation", + "mydspace.status.validation": "বৈধতা", + + // "mydspace.status.waiting-for-controller": "Waiting for controller", + "mydspace.status.waiting-for-controller": "নিয়ামক জন্য অপেক্ষা করছে", + + // "mydspace.status.workflow": "Workflow", + "mydspace.status.workflow": "ওয়ার্কফ্লো", + + // "mydspace.status.workspace": "Workspace", + "mydspace.status.workspace": "কর্মক্ষেত্র", + + // "mydspace.title": "MyDSpace", + "mydspace.title": "আমার ডিস্পেস", + + // "mydspace.upload.upload-failed": "Error creating new workspace. Please verify the content uploaded before retry.", + "mydspace.upload.upload-failed": "নতুন ওয়ার্কস্পেস তৈরি করার সময় ত্রুটি। পুনরায় চেষ্টা করার আগে আপলোড করা সামগ্রী যাচাই করুন।", + + // "mydspace.upload.upload-failed-manyentries": "Unprocessable file. Detected too many entries but allowed only one for file.", + "mydspace.upload.upload-failed-manyentries": "অরক্ষিত ফাইল। অনেক এন্ট্রি সনাক্ত কিন্তু শুধুমাত্র ফাইলের জন্য শুধুমাত্র একটি অনুমোদিত।", + + // "mydspace.upload.upload-failed-moreonefile": "Unprocessable request. Only one file is allowed.", + "mydspace.upload.upload-failed-moreonefile": "অরক্ষিত অনুরোধ। শুধুমাত্র একটি ফাইল অনুমতি দেওয়া আছে।", + + // "mydspace.upload.upload-multiple-successful": "{{qty}} new workspace items created.", + "mydspace.upload.upload-multiple-successful": "{{qty}} টি নতুন ওয়ার্কস্পেস আইটেম তৈরি করা হয়েছে।", + + // "mydspace.upload.upload-successful": "New workspace item created. Click {{here}} for edit it.", + "mydspace.upload.upload-successful": "নতুন ওয়ার্কস্পেস আইটেম তৈরি হয়েছে। এটি সম্পাদনা করার জন্য এখানে {{here}} ক্লিক করুন।", + + // "mydspace.view-btn": "View", + "mydspace.view-btn": "দেখুন", + + + + // "nav.browse.header": "All of DSpace", + "nav.browse.header": "ডিস্পেসের সবকিছু", + + // "nav.community-browse.header": "By Community", + "nav.community-browse.header": "সম্প্রদায় দ্বারা", + + // "nav.language": "Language switch", + "nav.language": "ভাষা পরিবর্তন", + + // "nav.login": "Log In", + "nav.login": "প্রবেশ করুন", + + // "nav.logout": "User profile menu and Log Out", + "nav.logout": "ব্যবহারকারী প্রোফাইল মেনু এবং লগ আউট", + + // "nav.main.description": "Main navigation bar", + "nav.main.description": "প্রধান ন্যাভিগেশন বার", + + // "nav.mydspace": "MyDSpace", + "nav.mydspace": "আমার ডিস্পেস", + + // "nav.profile": "Profile", + "nav.profile": "প্রোফাইল", + + // "nav.search": "Search", + "nav.search": "অনুসন্ধান করুন", + + // "nav.statistics.header": "Statistics", + "nav.statistics.header": "পরিসংখ্যান", + + // "nav.stop-impersonating": "Stop impersonating EPerson", + "nav.stop-impersonating": "ই-পারসন ছদ্মবেশী থামান", + + // "nav.toggle" : "Toggle navigation", + "nav.toggle" : "নেভিগেশন টগল করুন", + + // "nav.user.description" : "User profile bar", + "nav.user.description" : "ব্যবহারকারীর প্রোফাইল বার", + + // "none.listelement.badge": "Item", + "none.listelement.badge": "আইটেম", + + + // "orgunit.listelement.badge": "Organizational Unit", + "orgunit.listelement.badge": "প্রাতিষ্ঠানিক একক অংশ", + + // "orgunit.page.city": "City", + "orgunit.page.city": "শহর", + + // "orgunit.page.country": "Country", + "orgunit.page.country": "দেশ", + + // "orgunit.page.dateestablished": "Date established", + "orgunit.page.dateestablished": "স্থাপিত তারিখ", + + // "orgunit.page.description": "Description", + "orgunit.page.description": "বর্ণনা", + + // "orgunit.page.edit": "Edit this item", + "orgunit.page.edit": "এই আইটেমটি সম্পাদনা করুন", + + // "orgunit.page.id": "ID", + "orgunit.page.id": "আইডি", + + // "orgunit.page.titleprefix": "Organizational Unit: ", + "orgunit.page.titleprefix": "প্রাতিষ্ঠানিক একক অংশ: ", + + + + // "pagination.options.description": "Pagination options", + "pagination.options.description": "পেজিনেশনের বিকল্পগুলো", + + // "pagination.results-per-page": "Results Per Page", + "pagination.results-per-page": "প্রতি পৃষ্ঠায় ফলাফল", + + // "pagination.showing.detail": "{{ range }} of {{ total }}", + "pagination.showing.detail": "{{range}} এর {{total}}", + + // "pagination.showing.label": "Now showing ", + "pagination.showing.label": "এখন দেখানো হচ্ছে ", + + // "pagination.sort-direction": "Sort Options", + "pagination.sort-direction": "সাজানোর বিকল্পগুলো", + + + + // "person.listelement.badge": "Person", + "person.listelement.badge": "ব্যক্তি", + + // "person.listelement.no-title": "No name found", + "person.listelement.no-title": "কোন নাম পাওয়া যায় নি", + + // "person.page.birthdate": "Birth Date", + "person.page.birthdate": "জন্ম তারিখ", + + // "person.page.edit": "Edit this item", + "person.page.edit": "এই আইটেমটি সম্পাদনা করুন", + + // "person.page.email": "Email Address", + "person.page.email": "ইমেইল ঠিকানা", + + // "person.page.firstname": "First Name", + "person.page.firstname": "নামের প্রথম অংশ", + + // "person.page.jobtitle": "Job Title", + "person.page.jobtitle": "কাজের শিরোনাম", + + // "person.page.lastname": "Last Name", + "person.page.lastname": "নামের শেষাংশ", + + // "person.page.link.full": "Show all metadata", + "person.page.link.full": "সব মেটাডেটা দেখান", + + // "person.page.orcid": "ORCID", + "person.page.orcid": "Orcid.", + + // "person.page.staffid": "Staff ID", + "person.page.staffid": "স্টাফ আইডি", + + // "person.page.titleprefix": "Person: ", + "person.page.titleprefix": "ব্যক্তি: ", + + // "person.search.results.head": "Person Search Results", + "person.search.results.head": "ব্যক্তি অনুসন্ধান ফলাফল", + + // "person.search.title": "Person Search", + "person.search.title": "ব্যক্তি অনুসন্ধান", + + + + // "process.new.select-parameters": "Parameters", + "process.new.select-parameters": "পরামিতি", + + // "process.new.cancel": "Cancel", + "process.new.cancel": "বাতিল করুন", + + // "process.new.submit": "Save", + "process.new.submit": "সংরক্ষণ", + + // "process.new.select-script": "Script", + "process.new.select-script": "লিপি", + + // "process.new.select-script.placeholder": "Choose a script...", + "process.new.select-script.placeholder": "একটি স্ক্রিপ্ট নির্বাচন করুন ...", + + // "process.new.select-script.required": "Script is required", + "process.new.select-script.required": "স্ক্রিপ্ট প্রয়োজন", + + // "process.new.parameter.file.upload-button": "Select file...", + "process.new.parameter.file.upload-button": "ফাইল নির্বাচন...", + + // "process.new.parameter.file.required": "Please select a file", + "process.new.parameter.file.required": "দয়াকরে একটি ফাইল নির্বাচন করুন", + + // "process.new.parameter.string.required": "Parameter value is required", + "process.new.parameter.string.required": "পরামিতির মান প্রয়োজন", + + // "process.new.parameter.type.value": "value", + "process.new.parameter.type.value": "মূল্য", + + // "process.new.parameter.type.file": "file", + "process.new.parameter.type.file": "ফাইল", + + // "process.new.parameter.required.missing": "The following parameters are required but still missing:", + "process.new.parameter.required.missing": "নিম্নলিখিত পরামিতি প্রয়োজন কিন্তু এখনও অনুপস্থিত:", + + // "process.new.notification.success.title": "Success", + "process.new.notification.success.title": "সাফল্য", + + // "process.new.notification.success.content": "The process was successfully created", + "process.new.notification.success.content": "প্রক্রিয়া সফলভাবে তৈরি করা হয়েছে", + + // "process.new.notification.error.title": "Error", + "process.new.notification.error.title": "ত্রুটি", + + // "process.new.notification.error.content": "An error occurred while creating this process", + "process.new.notification.error.content": "এই প্রক্রিয়াটি তৈরি করার সময় একটি ত্রুটি ঘটেছে", + + // "process.new.header": "Create a new process", + "process.new.header": "একটি নতুন প্রক্রিয়া তৈরি করুন", + + // "process.new.title": "Create a new process", + "process.new.title": "একটি নতুন প্রক্রিয়া তৈরি করুন", + + // "process.new.breadcrumbs": "Create a new process", + "process.new.breadcrumbs": "একটি নতুন প্রক্রিয়া তৈরি করুন", + + + + // "process.detail.arguments" : "Arguments", + "process.detail.arguments" : "যুক্তি", + + // "process.detail.arguments.empty" : "This process doesn't contain any arguments", + "process.detail.arguments.empty" : "এই প্রক্রিয়া কোনো যুক্তি ধারণ করে না", + + // "process.detail.back" : "Back", + "process.detail.back" : "ফিরে যান", + + // "process.detail.output" : "Process Output", + "process.detail.output" : "প্রসেস আউটপুট", + + // "process.detail.logs.button": "Retrieve process output", + "process.detail.logs.button": "প্রক্রিয়া আউটপুট পুনরুদ্ধার", + + // "process.detail.logs.loading": "Retrieving", + "process.detail.logs.loading": "উদ্ধার", + + // "process.detail.logs.none": "This process has no output", + "process.detail.logs.none": "এই প্রক্রিয়া কোন আউটপুট আছে", + + // "process.detail.output-files" : "Output Files", + "process.detail.output-files" : "আউটপুট ফাইল", + + // "process.detail.output-files.empty" : "This process doesn't contain any output files", + "process.detail.output-files.empty" : "এই প্রক্রিয়ায় কোনো আউটপুট ফাইল নেই", + + // "process.detail.script" : "Script", + "process.detail.script" : "লিপি", + + // "process.detail.title" : "Process: {{ id }} - {{ name }}", + "process.detail.title" : "প্রক্রিয়া: {{ id }} - {{ name }}", + + // "process.detail.start-time" : "Start time", + "process.detail.start-time" : "শুরুর সময়", + + // "process.detail.end-time" : "Finish time", + "process.detail.end-time" : "শেষ সময়", + + // "process.detail.status" : "Status", + "process.detail.status" : "স্ট্যাটাস", + + // "process.detail.create" : "Create similar process", + "process.detail.create" : "অনুরূপ প্রক্রিয়া তৈরি করুন", + + + + // "process.overview.table.finish" : "Finish time (UTC)", + "process.overview.table.finish" : "শেষ সময় (UTC)", + + // "process.overview.table.id" : "Process ID", + "process.overview.table.id" : "প্রসেস আইডি", + + // "process.overview.table.name" : "Name", + "process.overview.table.name" : "নাম", + + // "process.overview.table.start" : "Start time (UTC)", + "process.overview.table.start" : "শুরুর সময় (UTC)", + + // "process.overview.table.status" : "Status", + "process.overview.table.status" : "স্ট্যাটাস", + + // "process.overview.table.user" : "User", + "process.overview.table.user" : "বাবহারকারি", + + // "process.overview.title": "Processes Overview", + "process.overview.title": "প্রসেসের সংক্ষিপ্ত বিবরণ", + + // "process.overview.breadcrumbs": "Processes Overview", + "process.overview.breadcrumbs": "প্রসেসের সংক্ষিপ্ত বিবরণ", + + // "process.overview.new": "New", + "process.overview.new": "নতুন", + + + // "profile.breadcrumbs": "Update Profile", + "profile.breadcrumbs": "আপডেট প্রফাইল", + + // "profile.card.identify": "Identify", + "profile.card.identify": "চিহ্নিত করুন", + + // "profile.card.security": "Security", + "profile.card.security": "নিরাপত্তা", + + // "profile.form.submit": "Save", + "profile.form.submit": "সংরক্ষণ", + + // "profile.groups.head": "Authorization groups you belong to", + "profile.groups.head": "অনুমোদিত গ্রুপগুলোতে আপনি অন্তর্গত", + + // "profile.head": "Update Profile", + "profile.head": "আপডেট প্রফাইল", + + // "profile.metadata.form.error.firstname.required": "First Name is required", + "profile.metadata.form.error.firstname.required": "প্রথম নাম প্রয়োজন", + + // "profile.metadata.form.error.lastname.required": "Last Name is required", + "profile.metadata.form.error.lastname.required": "শেষ নাম প্রয়োজন", + + // "profile.metadata.form.label.email": "Email Address", + "profile.metadata.form.label.email": "ইমেইল ঠিকানা", + + // "profile.metadata.form.label.firstname": "First Name", + "profile.metadata.form.label.firstname": "নামের প্রথম অংশ", + + // "profile.metadata.form.label.language": "Language", + "profile.metadata.form.label.language": "ভাষা", + + // "profile.metadata.form.label.lastname": "Last Name", + "profile.metadata.form.label.lastname": "নামের শেষাংশ", + + // "profile.metadata.form.label.phone": "Contact Telephone", + "profile.metadata.form.label.phone": "যোগাযোগ টেলিফোন", + + // "profile.metadata.form.notifications.success.content": "Your changes to the profile were saved.", + "profile.metadata.form.notifications.success.content": "প্রোফাইল আপনার পরিবর্তন সংরক্ষিত ছিল।", + + // "profile.metadata.form.notifications.success.title": "Profile saved", + "profile.metadata.form.notifications.success.title": "প্রোফাইল সংরক্ষিত হয়েছে", + + // "profile.notifications.warning.no-changes.content": "No changes were made to the Profile.", + "profile.notifications.warning.no-changes.content": "প্রোফাইলে কোন পরিবর্তন করা হয়নি।", + + // "profile.notifications.warning.no-changes.title": "No changes", + "profile.notifications.warning.no-changes.title": "পরিবর্তন নেই", + + // "profile.security.form.error.matching-passwords": "The passwords do not match.", + "profile.security.form.error.matching-passwords": "পাসওয়ার্ড মেলে না", + + // "profile.security.form.error.password-length": "The password should be at least 6 characters long.", + "profile.security.form.error.password-length": "পাসওয়ার্ড অন্তত ৬ অক্ষর দীর্ঘ হওয়া উচিত।", + + // "profile.security.form.info": "Optionally, you can enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", + "profile.security.form.info": "বিকল্পভাবে, আপনি নীচের বাক্সে একটি নতুন পাসওয়ার্ড লিখতে পারেন এবং এটি আবার দ্বিতীয় বাক্সে টাইপ করে এটি নিশ্চিত করতে পারেন। এটি অন্তত ছয় অক্ষর দীর্ঘ হতে হবে।", + + // "profile.security.form.label.password": "Password", + "profile.security.form.label.password": "পাসওয়ার্ড", + + // "profile.security.form.label.passwordrepeat": "Retype to confirm", + "profile.security.form.label.passwordrepeat": "নিশ্চিত করতে পুনরাই লিখুন", + + // "profile.security.form.notifications.success.content": "Your changes to the password were saved.", + "profile.security.form.notifications.success.content": "আপনার পাসওয়ার্ড পরিবর্তন সংরক্ষিত হয়েছে।", + + // "profile.security.form.notifications.success.title": "Password saved", + "profile.security.form.notifications.success.title": "পাসওয়ার্ড সংরক্ষিত", + + // "profile.security.form.notifications.error.title": "Error changing passwords", + "profile.security.form.notifications.error.title": "পাসওয়ার্ড পরিবর্তন করার সময় ত্রুটি হয়েছে", + + // "profile.security.form.notifications.error.not-long-enough": "The password has to be at least 6 characters long.", + "profile.security.form.notifications.error.not-long-enough": "পাসওয়ার্ড অন্তত ৬ অক্ষর দীর্ঘ হতে হবে।", + + // "profile.security.form.notifications.error.not-same": "The provided passwords are not the same.", + "profile.security.form.notifications.error.not-same": "প্রদত্ত পাসওয়ার্ড একই নয়।", + + // "profile.title": "Update Profile", + "profile.title": "আপডেট প্রফাইল", + + + + // "project.listelement.badge": "Research Project", + "project.listelement.badge": "গবেষণা প্রকল্প", + + // "project.page.contributor": "Contributors", + "project.page.contributor": "অবদানকারী", + + // "project.page.description": "Description", + "project.page.description": "বর্ণনা", + + // "project.page.edit": "Edit this item", + "project.page.edit": "এই আইটেমটি সম্পাদনা করুন", + + // "project.page.expectedcompletion": "Expected Completion", + "project.page.expectedcompletion": "প্রত্যাশিত সমাপ্তি", + + // "project.page.funder": "Funders", + "project.page.funder": "যারা আর্থিক সাহায্য করে", + + // "project.page.id": "ID", + "project.page.id": "আইডি", + + // "project.page.keyword": "Keywords", + "project.page.keyword": "কীওয়ার্ড", + + // "project.page.status": "Status", + "project.page.status": "অবস্থা", + + // "project.page.titleprefix": "Research Project: ", + "project.page.titleprefix": "গবেষণা প্রকল্প: ", + + // "project.search.results.head": "Project Search Results", + "project.search.results.head": "প্রকল্প অনুসন্ধান ফলাফল", + + + + // "publication.listelement.badge": "Publication", + "publication.listelement.badge": "প্রকাশনার", + + // "publication.page.description": "Description", + "publication.page.description": "বর্ণনা", + + // "publication.page.edit": "Edit this item", + "publication.page.edit": "এই আইটেমটি সম্পাদনা করুন", + + // "publication.page.journal-issn": "Journal ISSN", + "publication.page.journal-issn": "জার্নাল ISSN", + + // "publication.page.journal-title": "Journal Title", + "publication.page.journal-title": "জার্নাল শিরোনাম", + + // "publication.page.publisher": "Publisher", + "publication.page.publisher": "প্রকাশক", + + // "publication.page.titleprefix": "Publication: ", + "publication.page.titleprefix": "প্রকাশনা: ", + + // "publication.page.volume-title": "Volume Title", + "publication.page.volume-title": "ভলিউম শিরোনাম", + + // "publication.search.results.head": "Publication Search Results", + "publication.search.results.head": "প্রকাশনার অনুসন্ধান ফলাফল", + + // "publication.search.title": "Publication Search", + "publication.search.title": "প্রকাশনার অনুসন্ধান", + + + // "media-viewer.next": "Next", + "media-viewer.next": "পরবর্তী", + + // "media-viewer.previous": "Previous", + "media-viewer.previous": "পূর্ববর্তী", + + // "media-viewer.playlist": "Playlist", + "media-viewer.playlist": "প্লেলিস্ট", + + + // "register-email.title": "New user registration", + "register-email.title": "নতুন ব্যবহারকারীর জন্য নিবন্ধন", + + // "register-page.create-profile.header": "Create Profile", + "register-page.create-profile.header": "প্রোফাইল তৈরি করুন", + + // "register-page.create-profile.identification.header": "Identify", + "register-page.create-profile.identification.header": "চিহ্নিত করুন", + + // "register-page.create-profile.identification.email": "Email Address", + "register-page.create-profile.identification.email": "ইমেইল ঠিকানা", + + // "register-page.create-profile.identification.first-name": "First Name *", + "register-page.create-profile.identification.first-name": "নামের প্রথম অংশ *", + + // "register-page.create-profile.identification.first-name.error": "Please fill in a First Name", + "register-page.create-profile.identification.first-name.error": "একটি প্রথম নাম পূরণ করুন", + + // "register-page.create-profile.identification.last-name": "Last Name *", + "register-page.create-profile.identification.last-name": "নামের শেষাংশ *", + + // "register-page.create-profile.identification.last-name.error": "Please fill in a Last Name", + "register-page.create-profile.identification.last-name.error": "একটি শেষ নাম পূরণ করুন", + + // "register-page.create-profile.identification.contact": "Contact Telephone", + "register-page.create-profile.identification.contact": "যোগাযোগ টেলিফোন", + + // "register-page.create-profile.identification.language": "Language", + "register-page.create-profile.identification.language": "ভাষা", + + // "register-page.create-profile.security.header": "Security", + "register-page.create-profile.security.header": "নিরাপত্তা", + + // "register-page.create-profile.security.info": "Please enter a password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", + "register-page.create-profile.security.info": "নীচের বাক্সে একটি পাসওয়ার্ড লিখুন এবং দ্বিতীয় বাক্সে আবার টাইপ করে এটি নিশ্চিত করুন। এটি অন্তত ছয় অক্ষর দীর্ঘ হতে হবে।", + + // "register-page.create-profile.security.label.password": "Password *", + "register-page.create-profile.security.label.password": "পাসওয়ার্ড *", + + // "register-page.create-profile.security.label.passwordrepeat": "Retype to confirm *", + "register-page.create-profile.security.label.passwordrepeat": "নিশ্চিত করতে পুনরাই লিখুন *", + + // "register-page.create-profile.security.error.empty-password": "Please enter a password in the box below.", + "register-page.create-profile.security.error.empty-password": "নীচের বাক্সে একটি পাসওয়ার্ড লিখুন দয়া করে।", + + // "register-page.create-profile.security.error.matching-passwords": "The passwords do not match.", + "register-page.create-profile.security.error.matching-passwords": "পাসওয়ার্ড মেলে না.", + + // "register-page.create-profile.security.error.password-length": "The password should be at least 6 characters long.", + "register-page.create-profile.security.error.password-length": "পাসওয়ার্ড অন্তত ৬ অক্ষর দীর্ঘ হওয়া উচিত।", + + // "register-page.create-profile.submit": "Complete Registration", + "register-page.create-profile.submit": "সম্পূর্ণ নিবন্ধন", + + // "register-page.create-profile.submit.error.content": "Something went wrong while registering a new user.", + "register-page.create-profile.submit.error.content": "একটি নতুন ব্যবহারকারী নিবন্ধন করার সময় কিছু ভুল হয়েছে।", + + // "register-page.create-profile.submit.error.head": "Registration failed", + "register-page.create-profile.submit.error.head": "রেজিস্ট্রেশন ব্যর্থ হয়েছে", + + // "register-page.create-profile.submit.success.content": "The registration was successful. You have been logged in as the created user.", + "register-page.create-profile.submit.success.content": "নিবন্ধন সফল হয়েছে। আপনি তৈরি ব্যবহারকারী হিসাবে লগ ইন করেছেন।", + + // "register-page.create-profile.submit.success.head": "Registration completed", + "register-page.create-profile.submit.success.head": "নিবন্ধন সম্পন্ন", + + + // "register-page.registration.header": "New user registration", + "register-page.registration.header": "নতুন ব্যবহারকারীর জন্য নিবন্ধন", + + // "register-page.registration.info": "Register an account to subscribe to collections for email updates, and submit new items to DSpace.", + "register-page.registration.info": "ইমেল আপডেটের জন্য সংগ্রহে সদস্যতা নিতে একটি অ্যাকাউন্ট নিবন্ধন করুন এবং ডিস্পেস এ নতুন আইটেম জমা দিন।", + + // "register-page.registration.email": "Email Address *", + "register-page.registration.email": "ইমেইল ঠিকানা *", + + // "register-page.registration.email.error.required": "Please fill in an email address", + "register-page.registration.email.error.required": "একটি ইমেইল ঠিকানা পূরণ করুন", + + // "register-page.registration.email.error.pattern": "Please fill in a valid email address", + "register-page.registration.email.error.pattern": "একটি বৈধ ইমেইল ঠিকানা পূরণ করুন", + + // "register-page.registration.email.hint": "This address will be verified and used as your login name.", + "register-page.registration.email.hint": "এই ঠিকানাটি যাচাই করা হবে এবং আপনার লগইন নাম হিসাবে ব্যবহার করা হবে।", + + // "register-page.registration.submit": "Register", + "register-page.registration.submit": "নিবন্ধন", + + // "register-page.registration.success.head": "Verification email sent", + "register-page.registration.success.head": "যাচাই ইমেইল পাঠানো হয়েছে", + + // "register-page.registration.success.content": "An email has been sent to {{ email }} containing a special URL and further instructions.", + "register-page.registration.success.content": "একটি বিশেষ ইউআরএল এবং আরও নির্দেশাবলী ধারণকারী {{email}} এ একটি ইমেল পাঠানো হয়েছে।", + + // "register-page.registration.error.head": "Error when trying to register email", + "register-page.registration.error.head": "ইমেল নিবন্ধনের চেষ্টা করার সময় ত্রুটি", + + // "register-page.registration.error.content": "An error occured when registering the following email address: {{ email }}", + "register-page.registration.error.content": "নিম্নলিখিত ইমেল ঠিকানা নিবন্ধন করার সময় একটি ত্রুটি ঘটেছে: {{ email }}", + + + + // "relationships.add.error.relationship-type.content": "No suitable match could be found for relationship type {{ type }} between the two items", + "relationships.add.error.relationship-type.content": "দুটি আইটেমের মধ্যে সম্পর্কের প্রকার {{ type }} এর জন্য কোনো উপযুক্ত মিল খুঁজে পাওয়া যায়নি", + + // "relationships.add.error.server.content": "The server returned an error", + "relationships.add.error.server.content": "সার্ভারে একটি ত্রুটি হয়েছে", + + // "relationships.add.error.title": "Unable to add relationship", + "relationships.add.error.title": "সম্পর্ক যোগ করতে অক্ষম", + + // "relationships.isAuthorOf": "Authors", + "relationships.isAuthorOf": "লেখক", + + // "relationships.isAuthorOf.Person": "Authors (persons)", + "relationships.isAuthorOf.Person": "লেখক (ব্যক্তি)", + + // "relationships.isAuthorOf.OrgUnit": "Authors (organizational units)", + "relationships.isAuthorOf.OrgUnit": "লেখক (সাংগঠনিক ইউনিট)", + + // "relationships.isIssueOf": "Journal Issues", + "relationships.isIssueOf": "জার্নাল সমস্যা", + + // "relationships.isJournalIssueOf": "Journal Issue", + "relationships.isJournalIssueOf": "জার্নাল ইস্যু", + + // "relationships.isJournalOf": "Journals", + "relationships.isJournalOf": "জার্নালগুলো", + + // "relationships.isOrgUnitOf": "Organizational Units", + "relationships.isOrgUnitOf": "সাংগঠনিক ইউনিট", + + // "relationships.isPersonOf": "Authors", + "relationships.isPersonOf": "লেখক", + + // "relationships.isProjectOf": "Research Projects", + "relationships.isProjectOf": "গবেষণা প্রকল্পগুলো", + + // "relationships.isPublicationOf": "Publications", + "relationships.isPublicationOf": "প্রকাশনা", + + // "relationships.isPublicationOfJournalIssue": "Articles", + "relationships.isPublicationOfJournalIssue": "নিবন্ধসমূহ", + + // "relationships.isSingleJournalOf": "Journal", + "relationships.isSingleJournalOf": "জার্নাল", + + // "relationships.isSingleVolumeOf": "Journal Volume", + "relationships.isSingleVolumeOf": "জার্নাল ভলিউম", + + // "relationships.isVolumeOf": "Journal Volumes", + "relationships.isVolumeOf": "জার্নাল ভলিউম", + + // "relationships.isContributorOf": "Contributors", + "relationships.isContributorOf": "অবদানকারী", + + // "relationships.isContributorOf.OrgUnit": "Contributor (Organizational Unit)", + "relationships.isContributorOf.OrgUnit": "অবদানকারী (সাংগঠনিক ইউনিট)", + + // "relationships.isContributorOf.Person": "Contributor", + "relationships.isContributorOf.Person": "অবদানকারী", + + // "relationships.isFundingAgencyOf.OrgUnit": "Funder", + "relationships.isFundingAgencyOf.OrgUnit": "তহবিল.", + + + // "repository.image.logo": "Repository logo", + "repository.image.logo": "রিপোজিটরি লোগো", + + // "repository.title.prefix": "DSpace Angular :: ", + "repository.title.prefix": "ডিস্পেস অ্যাংগুলার :: ", + + // "repository.title.prefixDSpace": "DSpace Angular ::", + "repository.title.prefixDSpace": "ডিস্পেস অ্যাংগুলার ::", + + + // "resource-policies.add.button": "Add", + "resource-policies.add.button": "যোগ করুন", + + // "resource-policies.add.for.": "Add a new policy", + "resource-policies.add.for.": "একটি নতুন নীতি যোগ করুন", + + // "resource-policies.add.for.bitstream": "Add a new Bitstream policy", + "resource-policies.add.for.bitstream": "একটি নতুন বিটস্ট্রিম নীতি যোগ করুন", + + // "resource-policies.add.for.bundle": "Add a new Bundle policy", + "resource-policies.add.for.bundle": "একটি নতুন বান্ডিল নীতি যোগ করুন", + + // "resource-policies.add.for.item": "Add a new Item policy", + "resource-policies.add.for.item": "একটি নতুন আইটেম নীতি যোগ করুন", + + // "resource-policies.add.for.community": "Add a new Community policy", + "resource-policies.add.for.community": "একটি নতুন সম্প্রদায় নীতি যোগ করুন", + + // "resource-policies.add.for.collection": "Add a new Collection policy", + "resource-policies.add.for.collection": "একটি নতুন সংগ্রহ নীতি যোগ করুন", + + // "resource-policies.create.page.heading": "Create new resource policy for ", + "resource-policies.create.page.heading": "জন্য নতুন রিসোর্স নীতি তৈরি করুন", + + // "resource-policies.create.page.failure.content": "An error occurred while creating the resource policy.", + "resource-policies.create.page.failure.content": "সম্পদ নীতি তৈরি করার সময় একটি ত্রুটি ঘটেছে।", + + // "resource-policies.create.page.success.content": "Operation successful", + "resource-policies.create.page.success.content": "কাজটি সফল হয়েছে", + + // "resource-policies.create.page.title": "Create new resource policy", + "resource-policies.create.page.title": "নতুন সম্পদ নীতি তৈরি করুন", + + // "resource-policies.delete.btn": "Delete selected", + "resource-policies.delete.btn": "নির্বাচিতটি মুছুন", + + // "resource-policies.delete.btn.title": "Delete selected resource policies", + "resource-policies.delete.btn.title": "নির্বাচিত রিসোর্স নীতি মুছে দিন", + + // "resource-policies.delete.failure.content": "An error occurred while deleting selected resource policies.", + "resource-policies.delete.failure.content": "নির্বাচিত সম্পদ নীতি মুছে ফেলার সময় একটি ত্রুটি ঘটেছে।", + + // "resource-policies.delete.success.content": "Operation successful", + "resource-policies.delete.success.content": "কাজটি সফল হয়েছে", + + // "resource-policies.edit.page.heading": "Edit resource policy ", + "resource-policies.edit.page.heading": "রিসোর্স নীতি সম্পাদনা করুন", + + // "resource-policies.edit.page.failure.content": "An error occurred while editing the resource policy.", + "resource-policies.edit.page.failure.content": "সম্পদ নীতি সম্পাদনা করার সময় একটি ত্রুটি ঘটেছে।", + + // "resource-policies.edit.page.success.content": "Operation successful", + "resource-policies.edit.page.success.content": "কাজটি সফল হয়েছে", + + // "resource-policies.edit.page.title": "Edit resource policy", + "resource-policies.edit.page.title": "রিসোর্স নীতি সম্পাদনা করুন", + + // "resource-policies.form.action-type.label": "Select the action type", + "resource-policies.form.action-type.label": "অ্যাকশন টাইপ নির্বাচন করুন", + + // "resource-policies.form.action-type.required": "You must select the resource policy action.", + "resource-policies.form.action-type.required": "আপনাকে অবশই একটি সম্পদ নীতি নির্বাচন করতে হবে।", + + // "resource-policies.form.eperson-group-list.label": "The eperson or group that will be granted the permission", + "resource-policies.form.eperson-group-list.label": "ই-পারসন বা গ্রুপ যে অনুমতি প্রদান করবে", + + // "resource-policies.form.eperson-group-list.select.btn": "Select", + "resource-policies.form.eperson-group-list.select.btn": "নির্বাচন করুন", + + // "resource-policies.form.eperson-group-list.tab.eperson": "Search for a ePerson", + "resource-policies.form.eperson-group-list.tab.eperson": "একটি ই-পারসনের জন্য অনুসন্ধান করুন", + + // "resource-policies.form.eperson-group-list.tab.group": "Search for a group", + "resource-policies.form.eperson-group-list.tab.group": "একটি গ্রুপ জন্য অনুসন্ধান করুন", + + // "resource-policies.form.eperson-group-list.table.headers.action": "Action", + "resource-policies.form.eperson-group-list.table.headers.action": "অ্যাকশন", + + // "resource-policies.form.eperson-group-list.table.headers.id": "ID", + "resource-policies.form.eperson-group-list.table.headers.id": "আইডি", + + // "resource-policies.form.eperson-group-list.table.headers.name": "Name", + "resource-policies.form.eperson-group-list.table.headers.name": "নাম", + + // "resource-policies.form.date.end.label": "End Date", + "resource-policies.form.date.end.label": "শেষ তারিখ", + + // "resource-policies.form.date.start.label": "Start Date", + "resource-policies.form.date.start.label": "শুরুর তারিখ", + + // "resource-policies.form.description.label": "Description", + "resource-policies.form.description.label": "বর্ণনা", + + // "resource-policies.form.name.label": "Name", + "resource-policies.form.name.label": "নাম", + + // "resource-policies.form.policy-type.label": "Select the policy type", + "resource-policies.form.policy-type.label": "নীতির টাইপ নির্বাচন করুন", + + // "resource-policies.form.policy-type.required": "You must select the resource policy type.", + "resource-policies.form.policy-type.required": "আপনার অবশই রিসোর্স নীতি নির্বাচন করতে হবে।", + + // "resource-policies.table.headers.action": "Action", + "resource-policies.table.headers.action": "অ্যাকশন", + + // "resource-policies.table.headers.date.end": "End Date", + "resource-policies.table.headers.date.end": "শেষ তারিখ", + + // "resource-policies.table.headers.date.start": "Start Date", + "resource-policies.table.headers.date.start": "শুরুর তারিখ", + + // "resource-policies.table.headers.edit": "Edit", + "resource-policies.table.headers.edit": "সম্পাদনা করুন", + + // "resource-policies.table.headers.edit.group": "Edit group", + "resource-policies.table.headers.edit.group": "গ্রুপ সম্পাদনা করুন", + + // "resource-policies.table.headers.edit.policy": "Edit policy", + "resource-policies.table.headers.edit.policy": "নীতি সম্পাদনা করুন", + + // "resource-policies.table.headers.eperson": "EPerson", + "resource-policies.table.headers.eperson": "ই-পারসন", + + // "resource-policies.table.headers.group": "Group", + "resource-policies.table.headers.group": "গ্রুপ", + + // "resource-policies.table.headers.id": "ID", + "resource-policies.table.headers.id": "আইডি", + + // "resource-policies.table.headers.name": "Name", + "resource-policies.table.headers.name": "নাম", + + // "resource-policies.table.headers.policyType": "type", + "resource-policies.table.headers.policyType": "টাইপ.", + + // "resource-policies.table.headers.title.for.bitstream": "Policies for Bitstream", + "resource-policies.table.headers.title.for.bitstream": "বিটস্ট্রিমের জন্য নীতি", + + // "resource-policies.table.headers.title.for.bundle": "Policies for Bundle", + "resource-policies.table.headers.title.for.bundle": "বান্ডিলের জন্য নীতি", + + // "resource-policies.table.headers.title.for.item": "Policies for Item", + "resource-policies.table.headers.title.for.item": "আইটেমের জন্য নীতি", + + // "resource-policies.table.headers.title.for.community": "Policies for Community", + "resource-policies.table.headers.title.for.community": "সম্প্রদায়ের জন্য নীতি", + + // "resource-policies.table.headers.title.for.collection": "Policies for Collection", + "resource-policies.table.headers.title.for.collection": "সংগ্রহের জন্য নীতি", + + + + // "search.description": "", + "search.description": "", + + // "search.switch-configuration.title": "Show", + "search.switch-configuration.title": "দেখাও", + + // "search.title": "Search", + "search.title": "অনুসন্ধান করুন", + + // "search.breadcrumbs": "Search", + "search.breadcrumbs": "অনুসন্ধান করুন", + + // "search.search-form.placeholder": "Search the repository ...", + "search.search-form.placeholder": "সংগ্রহস্থল অনুসন্ধান করুন ...", + + + // "search.filters.applied.f.author": "Author", + "search.filters.applied.f.author": "লেখক", + + // "search.filters.applied.f.dateIssued.max": "End date", + "search.filters.applied.f.dateIssued.max": "শেষ তারিখ", + + // "search.filters.applied.f.dateIssued.min": "Start date", + "search.filters.applied.f.dateIssued.min": "শুরুর তারিখ", + + // "search.filters.applied.f.dateSubmitted": "Date submitted", + "search.filters.applied.f.dateSubmitted": "জন্ম জমা", + + // "search.filters.applied.f.discoverable": "Private", + "search.filters.applied.f.discoverable": "ব্যক্তিগত", + + // "search.filters.applied.f.entityType": "Item Type", + "search.filters.applied.f.entityType": "বস্তুর ধরন", + + // "search.filters.applied.f.has_content_in_original_bundle": "Has files", + "search.filters.applied.f.has_content_in_original_bundle": "ফাইল আছে", + + // "search.filters.applied.f.itemtype": "Type", + "search.filters.applied.f.itemtype": "ধরন", + + // "search.filters.applied.f.namedresourcetype": "Status", + "search.filters.applied.f.namedresourcetype": "অবস্থা", + + // "search.filters.applied.f.subject": "Subject", + "search.filters.applied.f.subject": "বিষয়", + + // "search.filters.applied.f.submitter": "Submitter", + "search.filters.applied.f.submitter": "জমাকারী", + + // "search.filters.applied.f.jobTitle": "Job Title", + "search.filters.applied.f.jobTitle": "কাজের শিরোনাম", + + // "search.filters.applied.f.birthDate.max": "End birth date", + "search.filters.applied.f.birthDate.max": "শেষ জন্ম তারিখ", + + // "search.filters.applied.f.birthDate.min": "Start birth date", + "search.filters.applied.f.birthDate.min": "জন্ম তারিখ শুরু করুন", + + // "search.filters.applied.f.withdrawn": "Withdrawn", + "search.filters.applied.f.withdrawn": "প্রত্যাহার", + + + + // "search.filters.filter.author.head": "Author", + "search.filters.filter.author.head": "লেখক", + + // "search.filters.filter.author.placeholder": "Author name", + "search.filters.filter.author.placeholder": "লেখকের নাম", + + // "search.filters.filter.author.label": "Search author name", + "search.filters.filter.author.label": "অনুসন্ধান লেখক নাম", + + // "search.filters.filter.birthDate.head": "Birth Date", + "search.filters.filter.birthDate.head": "জন্ম তারিখ", + + // "search.filters.filter.birthDate.placeholder": "Birth Date", + "search.filters.filter.birthDate.placeholder": "জন্ম তারিখ", + + // "search.filters.filter.birthDate.label": "Search birth date", + "search.filters.filter.birthDate.label": "জন্ম তারিখ অনুসন্ধান করুন", + + // "search.filters.filter.collapse": "Collapse filter", + "search.filters.filter.collapse": "ফিল্টার সঙ্কুচিত করুন", + + // "search.filters.filter.creativeDatePublished.head": "Date Published", + "search.filters.filter.creativeDatePublished.head": "তারিখ প্রকাশিত", + + // "search.filters.filter.creativeDatePublished.placeholder": "Date Published", + "search.filters.filter.creativeDatePublished.placeholder": "তারিখ প্রকাশিত", + + // "search.filters.filter.creativeDatePublished.label": "Search date published", + "search.filters.filter.creativeDatePublished.label": "অনুসন্ধান তারিখ প্রকাশিত", + + // "search.filters.filter.creativeWorkEditor.head": "Editor", + "search.filters.filter.creativeWorkEditor.head": "সম্পাদক", + + // "search.filters.filter.creativeWorkEditor.placeholder": "Editor", + "search.filters.filter.creativeWorkEditor.placeholder": "সম্পাদক", + + // "search.filters.filter.creativeWorkEditor.label": "Search editor", + "search.filters.filter.creativeWorkEditor.label": "অনুসন্ধান সম্পাদক", + + // "search.filters.filter.creativeWorkKeywords.head": "Subject", + "search.filters.filter.creativeWorkKeywords.head": "বিষয়", + + // "search.filters.filter.creativeWorkKeywords.placeholder": "Subject", + "search.filters.filter.creativeWorkKeywords.placeholder": "বিষয়", + + // "search.filters.filter.creativeWorkKeywords.label": "Search subject", + "search.filters.filter.creativeWorkKeywords.label": "অনুসন্ধান বিষয়", + + // "search.filters.filter.creativeWorkPublisher.head": "Publisher", + "search.filters.filter.creativeWorkPublisher.head": "প্রকাশক", + + // "search.filters.filter.creativeWorkPublisher.placeholder": "Publisher", + "search.filters.filter.creativeWorkPublisher.placeholder": "প্রকাশক", + + // "search.filters.filter.creativeWorkPublisher.label": "Search publisher", + "search.filters.filter.creativeWorkPublisher.label": "অনুসন্ধান প্রকাশক", + + // "search.filters.filter.dateIssued.head": "Date", + "search.filters.filter.dateIssued.head": "তারিখ", + + // "search.filters.filter.dateIssued.max.placeholder": "Maximum Date", + "search.filters.filter.dateIssued.max.placeholder": "সর্বোচ্চ তারিখ", + + // "search.filters.filter.dateIssued.max.label": "End", + "search.filters.filter.dateIssued.max.label": "শেষ", + + // "search.filters.filter.dateIssued.min.placeholder": "Minimum Date", + "search.filters.filter.dateIssued.min.placeholder": "নূন্যতম তারিখ", + + // "search.filters.filter.dateIssued.min.label": "Start", + "search.filters.filter.dateIssued.min.label": "শুরু করুন", + + // "search.filters.filter.dateSubmitted.head": "Date submitted", + "search.filters.filter.dateSubmitted.head": "জমাদানের তারিখ", + + // "search.filters.filter.dateSubmitted.placeholder": "Date submitted", + "search.filters.filter.dateSubmitted.placeholder": "জমাদানের তারিখ", + + // "search.filters.filter.dateSubmitted.label": "Search date submitted", + "search.filters.filter.dateSubmitted.label": "অনুসন্ধান তারিখ জমা হয়েছে", + + // "search.filters.filter.discoverable.head": "Private", + "search.filters.filter.discoverable.head": "ব্যক্তিগত", + + // "search.filters.filter.withdrawn.head": "Withdrawn", + "search.filters.filter.withdrawn.head": "প্রত্যাহার", + + // "search.filters.filter.entityType.head": "Item Type", + "search.filters.filter.entityType.head": "বস্তুর ধরন", + + // "search.filters.filter.entityType.placeholder": "Item Type", + "search.filters.filter.entityType.placeholder": "বস্তুর ধরন", + + // "search.filters.filter.entityType.label": "Search item type", + "search.filters.filter.entityType.label": "আইটেম টাইপ অনুসন্ধান করুন", + + // "search.filters.filter.expand": "Expand filter", + "search.filters.filter.expand": "ফিল্টার প্রসারিত করুন", + + // "search.filters.filter.has_content_in_original_bundle.head": "Has files", + "search.filters.filter.has_content_in_original_bundle.head": "ফাইল আছে", + + // "search.filters.filter.itemtype.head": "Type", + "search.filters.filter.itemtype.head": "ধরন", + + // "search.filters.filter.itemtype.placeholder": "Type", + "search.filters.filter.itemtype.placeholder": "ধরন", + + // "search.filters.filter.itemtype.label": "Search type", + "search.filters.filter.itemtype.label": "ধরন অনুসন্ধান করুন", + + // "search.filters.filter.jobTitle.head": "Job Title", + "search.filters.filter.jobTitle.head": "কাজের শিরোনাম", + + // "search.filters.filter.jobTitle.placeholder": "Job Title", + "search.filters.filter.jobTitle.placeholder": "কাজের শিরোনাম", + + // "search.filters.filter.jobTitle.label": "Search job title", + "search.filters.filter.jobTitle.label": "কাজের শিরোনাম অনুসন্ধান করুন", + + // "search.filters.filter.knowsLanguage.head": "Known language", + "search.filters.filter.knowsLanguage.head": "পরিচিত ভাষা", + + // "search.filters.filter.knowsLanguage.placeholder": "Known language", + "search.filters.filter.knowsLanguage.placeholder": "পরিচিত ভাষা", + + // "search.filters.filter.knowsLanguage.label": "Search known language", + "search.filters.filter.knowsLanguage.label": "পরিচিত ভাষা অনুসন্ধান করুন", + + // "search.filters.filter.namedresourcetype.head": "Status", + "search.filters.filter.namedresourcetype.head": "অবস্থা", + + // "search.filters.filter.namedresourcetype.placeholder": "Status", + "search.filters.filter.namedresourcetype.placeholder": "অবস্থা", + + // "search.filters.filter.namedresourcetype.label": "Search status", + "search.filters.filter.namedresourcetype.label": "অবস্থা অনুসন্ধান করুন", + + // "search.filters.filter.objectpeople.head": "People", + "search.filters.filter.objectpeople.head": "ব্যাক্তি", + + // "search.filters.filter.objectpeople.placeholder": "People", + "search.filters.filter.objectpeople.placeholder": "ব্যাক্তি", + + // "search.filters.filter.objectpeople.label": "Search people", + "search.filters.filter.objectpeople.label": "ব্যাক্তি অনুসন্ধান করুন", + + // "search.filters.filter.organizationAddressCountry.head": "Country", + "search.filters.filter.organizationAddressCountry.head": "দেশ", + + // "search.filters.filter.organizationAddressCountry.placeholder": "Country", + "search.filters.filter.organizationAddressCountry.placeholder": "দেশ", + + // "search.filters.filter.organizationAddressCountry.label": "Search country", + "search.filters.filter.organizationAddressCountry.label": "দেশ অনুসন্ধান করুন", + + // "search.filters.filter.organizationAddressLocality.head": "City", + "search.filters.filter.organizationAddressLocality.head": "শহর", + + // "search.filters.filter.organizationAddressLocality.placeholder": "City", + "search.filters.filter.organizationAddressLocality.placeholder": "শহর", + + // "search.filters.filter.organizationAddressLocality.label": "Search city", + "search.filters.filter.organizationAddressLocality.label": "অনুসন্ধান শহর", + + // "search.filters.filter.organizationFoundingDate.head": "Date Founded", + "search.filters.filter.organizationFoundingDate.head": "প্রতিষ্ঠার তারিখ", + + // "search.filters.filter.organizationFoundingDate.placeholder": "Date Founded", + "search.filters.filter.organizationFoundingDate.placeholder": "প্রতিষ্ঠার তারিখ", + + // "search.filters.filter.organizationFoundingDate.label": "Search date founded", + "search.filters.filter.organizationFoundingDate.label": "প্রতিষ্ঠার তারিখ অনুসন্ধান করুন", + + // "search.filters.filter.scope.head": "Scope", + "search.filters.filter.scope.head": "সুযোগ", + + // "search.filters.filter.scope.placeholder": "Scope filter", + "search.filters.filter.scope.placeholder": "স্কোপ ফিল্টার", + + // "search.filters.filter.scope.label": "Search scope filter", + "search.filters.filter.scope.label": "স্কোপ ফিল্টার অনুসন্ধান করুন", + + // "search.filters.filter.show-less": "Collapse", + "search.filters.filter.show-less": "সঙ্কুচিত করুন", + + // "search.filters.filter.show-more": "Show more", + "search.filters.filter.show-more": "আরো দেখুন", + + // "search.filters.filter.subject.head": "Subject", + "search.filters.filter.subject.head": "বিষয়", + + // "search.filters.filter.subject.placeholder": "Subject", + "search.filters.filter.subject.placeholder": "বিষয়", + + // "search.filters.filter.subject.label": "Search subject", + "search.filters.filter.subject.label": "বিষয় অনুসন্ধান করুন", + + // "search.filters.filter.submitter.head": "Submitter", + "search.filters.filter.submitter.head": "জমাকারী", + + // "search.filters.filter.submitter.placeholder": "Submitter", + "search.filters.filter.submitter.placeholder": "জমাকারী", + + // "search.filters.filter.submitter.label": "Search submitter", + "search.filters.filter.submitter.label": "জমাকারী অনুসন্ধান করুন", + + + + // "search.filters.entityType.JournalIssue": "Journal Issue", + "search.filters.entityType.JournalIssue": "জার্নাল ইস্যু", + + // "search.filters.entityType.JournalVolume": "Journal Volume", + "search.filters.entityType.JournalVolume": "জার্নাল ভলিউম", + + // "search.filters.entityType.OrgUnit": "Organizational Unit", + "search.filters.entityType.OrgUnit": "প্রাতিষ্ঠানিক একক অংশ", + + // "search.filters.has_content_in_original_bundle.true": "Yes", + "search.filters.has_content_in_original_bundle.true": "হ্যাঁ", + + // "search.filters.has_content_in_original_bundle.false": "No", + "search.filters.has_content_in_original_bundle.false": "না", + + // "search.filters.discoverable.true": "No", + "search.filters.discoverable.true": "না", + + // "search.filters.discoverable.false": "Yes", + "search.filters.discoverable.false": "হ্যাঁ", + + // "search.filters.withdrawn.true": "Yes", + "search.filters.withdrawn.true": "হ্যাঁ", + + // "search.filters.withdrawn.false": "No", + "search.filters.withdrawn.false": "না", + + + // "search.filters.head": "Filters", + "search.filters.head": "ফিল্টার", + + // "search.filters.reset": "Reset filters", + "search.filters.reset": "ফিল্টার রিসেট করুন", + + // "search.filters.search.submit": "Submit", + "search.filters.search.submit": "জমা দিন", + + + + // "search.form.search": "Search", + "search.form.search": "অনুসন্ধান করুন", + + // "search.form.search_dspace": "All repository", + "search.form.search_dspace": "সব সংগ্রহস্থল", + + // "search.form.scope.all": "All of DSpace", + "search.form.scope.all": "ডিস্পেসের সবকিছু", + + + + // "search.results.head": "Search Results", + "search.results.head": "অনুসন্ধানের ফলাফল", + + // "search.results.no-results": "Your search returned no results. Having trouble finding what you're looking for? Try putting", + "search.results.no-results": "আপনার অনুসন্ধানের কোন ফলাফল পাওয়া যাই নি। আপনি যেটা খুঁজছেন তা পেতে কি সমস্যা হচ্ছে? নির্বাণ চেষ্টা করুন", + + // "search.results.no-results-link": "quotes around it", + "search.results.no-results-link": "এর চারপাশে উদ্ধৃতি", + + // "search.results.empty": "Your search returned no results.", + "search.results.empty": "আপনার অনুসন্ধানের কোন ফলাফল পাওয়া যাই নি", + + + // "default.search.results.head": "Search Results", + "default.search.results.head": "অনুসন্ধানের ফলাফল", + + + // "search.sidebar.close": "Back to results", + "search.sidebar.close": "ফলাফলে ফিরে যান", + + // "search.sidebar.filters.title": "Filters", + "search.sidebar.filters.title": "ফিল্টারগুলো", + + // "search.sidebar.open": "Search Tools", + "search.sidebar.open": "খোঁজার যন্ত্র", + + // "search.sidebar.results": "results", + "search.sidebar.results": "ফলাফল", + + // "search.sidebar.settings.rpp": "Results per page", + "search.sidebar.settings.rpp": "প্রতি পৃষ্ঠায় ফলাফল", + + // "search.sidebar.settings.sort-by": "Sort By", + "search.sidebar.settings.sort-by": "ক্রমানুসার", + + // "search.sidebar.settings.title": "Settings", + "search.sidebar.settings.title": "সেটিংস", + + + + // "search.view-switch.show-detail": "Show detail", + "search.view-switch.show-detail": "বিস্তারিত দেখাও", + + // "search.view-switch.show-grid": "Show as grid", + "search.view-switch.show-grid": "গ্রিড হিসাবে দেখান", + + // "search.view-switch.show-list": "Show as list", + "search.view-switch.show-list": "তালিকা হিসাবে দেখান", + + + + // "sorting.ASC": "Ascending", + "sorting.ASC": "উর্দ্ধক্রমানুসারে", + + // "sorting.DESC": "Descending", + "sorting.DESC": "নিম্নক্রমানুসারে", + + // "sorting.dc.title.ASC": "Title Ascending", + "sorting.dc.title.ASC": "শিরোনাম উর্দ্ধক্রমানুসারে", + + // "sorting.dc.title.DESC": "Title Descending", + "sorting.dc.title.DESC": "শিরোনাম নিম্নক্রমানুসারে", + + // "sorting.score.ASC": "Least Relevant", + "sorting.score.ASC": "ন্যুনতম প্রাসঙ্গিক", + + // "sorting.score.DESC": "Most Relevant", + "sorting.score.DESC": "সবচেয়ে প্রাসঙ্গিক", + + // "sorting.dc.date.issued.ASC": "Date Issued Ascending", + "sorting.dc.date.issued.ASC": "ইস্যু করার তারিখ উর্দ্ধক্রমানুসারে", + + // "sorting.dc.date.issued.DESC": "Date Issued Descending", + "sorting.dc.date.issued.DESC": "ইস্যু করার তারিখ নিম্নক্রমানুসারে", + + // "sorting.dc.date.accessioned.ASC": "Accessioned Date Ascending", + "sorting.dc.date.accessioned.ASC": "যোগদানের তারিখ উর্দ্ধক্রমানুসারে", + + // "sorting.dc.date.accessioned.DESC": "Accessioned Date Descending", + "sorting.dc.date.accessioned.DESC": "যোগদানের তারিখ নিম্নক্রমানুসারে", + + // "sorting.lastModified.ASC": "Last modified Ascending", + "sorting.lastModified.ASC": "সর্বশেষ সংশোধিত উর্দ্ধক্রমানুসারে", + + // "sorting.lastModified.DESC": "Last modified Descending", + "sorting.lastModified.DESC": "সর্বশেষ সংশোধিত নিম্নক্রমানুসারে.", + + + // "statistics.title": "Statistics", + "statistics.title": "পরিসংখ্যান", + + // "statistics.header": "Statistics for {{ scope }}", + "statistics.header": "{{scope}} এর জন্য পরিসংখ্যান", + + // "statistics.breadcrumbs": "Statistics", + "statistics.breadcrumbs": "পরিসংখ্যান", + + // "statistics.page.no-data": "No data available", + "statistics.page.no-data": "কোন তথ্য নেই", + + // "statistics.table.no-data": "No data available", + "statistics.table.no-data": "কোন তথ্য নেই", + + // "statistics.table.title.TotalVisits": "Total visits", + "statistics.table.title.TotalVisits": "মোট পরিদর্শন", + + // "statistics.table.title.TotalVisitsPerMonth": "Total visits per month", + "statistics.table.title.TotalVisitsPerMonth": "প্রতি মাসে মোট পরিদর্শন", + + // "statistics.table.title.TotalDownloads": "File Visits", + "statistics.table.title.TotalDownloads": "ফাইল পরিদর্শন", + + // "statistics.table.title.TopCountries": "Top country views", + "statistics.table.title.TopCountries": "শীর্ষ দেশ পরিদর্শন", + + // "statistics.table.title.TopCities": "Top city views", + "statistics.table.title.TopCities": "শীর্ষ শহর পরিদর্শন", + + // "statistics.table.header.views": "Views", + "statistics.table.header.views": "পরিদর্শন", + + + + // "submission.edit.breadcrumbs": "Edit Submission", + "submission.edit.breadcrumbs": "সম্পাদনা সম্পাদনা করুন", + + // "submission.edit.title": "Edit Submission", + "submission.edit.title": "জমা সম্পাদনা করুন", + + // "submission.general.cancel": "Cancel", + "submission.general.cancel": "বাতিল করুন", + + // "submission.general.cannot_submit": "You have not the privilege to make a new submission.", + "submission.general.cannot_submit": "আপনার নতুন জমা দেওয়ার বিশেষাধিকার নেই।", + + // "submission.general.deposit": "Deposit", + "submission.general.deposit": "আমানত.", + + // "submission.general.discard.confirm.cancel": "Cancel", + "submission.general.discard.confirm.cancel": "বাতিল করুন", + + // "submission.general.discard.confirm.info": "This operation can't be undone. Are you sure?", + "submission.general.discard.confirm.info": "এই অপারেশন পূর্বাবস্থায় ফেরানো যাবে না। তুমি কি নিশ্চিত?", + + // "submission.general.discard.confirm.submit": "Yes, I'm sure", + "submission.general.discard.confirm.submit": "হ্যা, আমি নিশ্চিত", + + // "submission.general.discard.confirm.title": "Discard submission", + "submission.general.discard.confirm.title": "জমা বাতিল করুন", + + // "submission.general.discard.submit": "Discard", + "submission.general.discard.submit": "বাতিল করা", + + // "submission.general.info.saved": "Saved", + "submission.general.info.saved": "সংরক্ষিত", + + // "submission.general.info.pending-changes": "Unsaved changes", + "submission.general.info.pending-changes": "অসংরক্ষিত পরিবর্তন", + + // "submission.general.save": "Save", + "submission.general.save": "সংরক্ষণ করুন", + + // "submission.general.save-later": "Save for later", + "submission.general.save-later": "পরে জন্য সংরক্ষণ করুন", + + + // "submission.import-external.page.title": "Import metadata from an external source", + "submission.import-external.page.title": "একটি বহিরাগত উৎস থেকে মেটাডাটা আমদানি করুন", + + // "submission.import-external.title": "Import metadata from an external source", + "submission.import-external.title": "একটি বহিরাগত উৎস থেকে মেটাডাটা আমদানি করুন", + + // "submission.import-external.title.Journal": "Import a journal from an external source", + "submission.import-external.title.Journal": "একটি বহিরাগত উৎস থেকে একটি জার্নাল আমদানি করুন", + + // "submission.import-external.title.JournalIssue": "Import a journal issue from an external source", + "submission.import-external.title.JournalIssue": "একটি বহিরাগত উৎস থেকে একটি জার্নাল ইস্যু আমদানি করুন", + + // "submission.import-external.title.JournalVolume": "Import a journal volume from an external source", + "submission.import-external.title.JournalVolume": "একটি বহিরাগত উৎস থেকে একটি জার্নাল ভলিউম আমদানি করুন", + + // "submission.import-external.title.OrgUnit": "Import a publisher from an external source", + "submission.import-external.title.OrgUnit": "একটি বহিরাগত উৎস থেকে একটি প্রকাশক আমদানি করুন", + + // "submission.import-external.title.Person": "Import a person from an external source", + "submission.import-external.title.Person": "একটি বহিরাগত উৎস থেকে একটি ব্যক্তি আমদানি করুন", + + // "submission.import-external.title.Project": "Import a project from an external source", + "submission.import-external.title.Project": "একটি বহিরাগত উৎস থেকে একটি প্রকল্প আমদানি করুন", + + // "submission.import-external.title.Publication": "Import a publication from an external source", + "submission.import-external.title.Publication": "একটি বহিরাগত উৎস থেকে একটি প্রকাশনা আমদানি করুন", + + // "submission.import-external.title.none": "Import metadata from an external source", + "submission.import-external.title.none": "একটি বহিরাগত উৎস থেকে মেটাডাটা আমদানি করুন", + + // "submission.import-external.page.hint": "Enter a query above to find items from the web to import in to DSpace.", + "submission.import-external.page.hint": "ডিস্পেস এ আমদানি করার জন্য ওয়েব থেকে আইটেমগুলি খুঁজে পেতে উপরের একটি প্রশ্নের উপরে প্রবেশ করুন।", + + // "submission.import-external.back-to-my-dspace": "Back to MyDSpace", + "submission.import-external.back-to-my-dspace": "আমার ডিস্পেস এ ফিরে যান", + + // "submission.import-external.search.placeholder": "Search the external source", + "submission.import-external.search.placeholder": "বাহ্যিক উৎস অনুসন্ধান করুন", + + // "submission.import-external.search.button": "Search", + "submission.import-external.search.button": "অনুসন্ধান করুন", + + // "submission.import-external.search.button.hint": "Write some words to search", + "submission.import-external.search.button.hint": "অনুসন্ধান করার জন্য কিছু শব্দ লিখুন", + + // "submission.import-external.search.source.hint": "Pick an external source", + "submission.import-external.search.source.hint": "একটি বহিরাগত উৎস বাছাই করুন", + + // "submission.import-external.source.arxiv": "arXiv", + "submission.import-external.source.arxiv": "arXiv", + + // "submission.import-external.source.loading": "Loading ...", + "submission.import-external.source.loading": "লোড হচ্ছে ...", + + // "submission.import-external.source.sherpaJournal": "SHERPA Journals", + "submission.import-external.source.sherpaJournal": "SHERPA জার্নাল", + + // "submission.import-external.source.sherpaJournalIssn": "SHERPA Journals by ISSN", + "submission.import-external.source.sherpaJournalIssn": "SHERPA জার্নাল দ্বারা ISSN", + + // "submission.import-external.source.sherpaPublisher": "SHERPA Publishers", + "submission.import-external.source.sherpaPublisher": "SHERPA পাবলিশার্স", + + // "submission.import-external.source.openAIREFunding": "Funding OpenAIRE API", + "submission.import-external.source.openAIREFunding": "OpenAIRE এ পি আই (API) কে আর্থিক ভাবে সাহায্য", + + // "submission.import-external.source.orcid": "ORCID", + "submission.import-external.source.orcid": "Orcid.", + + // "submission.import-external.source.pubmed": "Pubmed", + "submission.import-external.source.pubmed": "PubMed.", + + // "submission.import-external.source.lcname": "Library of Congress Names", + "submission.import-external.source.lcname": "লাইব্রেরি অব কংগ্রেসের নামগুলো", + + // "submission.import-external.preview.title": "Item Preview", + "submission.import-external.preview.title": "আইটেম পূর্বরূপ", + + // "submission.import-external.preview.subtitle": "The metadata below was imported from an external source. It will be pre-filled when you start the submission.", + "submission.import-external.preview.subtitle": "নীচের মেটাডেটা একটি বহিরাগত উৎস থেকে আমদানি করা হয়েছিল। আপনি জমা শুরু যখন এটি প্রাক ভরাট করা হবে।", + + // "submission.import-external.preview.button.import": "Start submission", + "submission.import-external.preview.button.import": "জমাদেয়া শুরু করুন", + + // "submission.import-external.preview.error.import.title": "Submission error", + "submission.import-external.preview.error.import.title": "জমাদানে ত্রুটি হয়েছে", + + // "submission.import-external.preview.error.import.body": "An error occurs during the external source entry import process.", + "submission.import-external.preview.error.import.body": "বহিরাগত উৎস থেকে এন্ট্রি আমদানি প্রক্রিয়ার সময় একটি ত্রুটি ঘটেছে।", + + // "submission.sections.describe.relationship-lookup.close": "Close", + "submission.sections.describe.relationship-lookup.close": "বন্ধ করুন", + + // "submission.sections.describe.relationship-lookup.external-source.added": "Successfully added local entry to the selection", + "submission.sections.describe.relationship-lookup.external-source.added": "সফলভাবে নির্বাচন স্থানীয় এন্ট্রি যোগ করা হয়েছে", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.isAuthorOfPublication": "Import remote author", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.isAuthorOfPublication": "দূরবর্তী লেখক আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal": "Import remote journal", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal": "দূরবর্তী জার্নাল আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Issue": "Import remote journal issue", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Issue": "দূরবর্তী জার্নাল ইস্যু আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "Import remote journal volume", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "দূরবর্তী জার্নাল ভলিউম আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-button-title.isProjectOfPublication": "Project", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.isProjectOfPublication": "প্রকল্প", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isProjectOfPublication.added.new-entity": "New Entity Added!", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isProjectOfPublication.added.new-entity": "নতুন এন্ট্রি যোগ করা হয়েছে!", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isProjectOfPublication.title": "Project", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isProjectOfPublication.title": "প্রকল্প", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.openAIREFunding": "Funding OpenAIRE API", + "submission.sections.describe.relationship-lookup.external-source.import-modal.head.openAIREFunding": "OpenAIRE এ পি আই (API) কে আর্থিক ভাবে সাহায্য করা", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "Import Remote Author", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.title": "দূরবর্তী লেখক আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "Successfully added local author to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.local-entity": "নির্বাচনে স্থানীয় লেখককে সফলভাবে যোগ করা হয়েছে", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.new-entity": "Successfully imported and added external author to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isAuthorOfPublication.added.new-entity": "সফলভাবে আমদানি করা হয়েছে এবং নির্বাচনে বহিরাগত লেখক যোগ করা হয়েছে", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "Authority", + "submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "কর্তৃপক্ষ", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.authority.new": "Import as a new local authority entry", + "submission.sections.describe.relationship-lookup.external-source.import-modal.authority.new": "একটি নতুন স্থানীয় কর্তৃপক্ষ এন্ট্রি হিসাবে আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.cancel": "Cancel", + "submission.sections.describe.relationship-lookup.external-source.import-modal.cancel": "বাতিল করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.collection": "Select a collection to import new entries to", + "submission.sections.describe.relationship-lookup.external-source.import-modal.collection": "নতুন এন্ট্রি আমদানি করতে একটি সংগ্রহ নির্বাচন করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.entities": "Entities", + "submission.sections.describe.relationship-lookup.external-source.import-modal.entities": "Entities(সত্তা)", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.entities.new": "Import as a new local entity", + "submission.sections.describe.relationship-lookup.external-source.import-modal.entities.new": "একটি নতুন স্থানীয় সত্তা হিসাবে আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.lcname": "Importing from LC Name", + "submission.sections.describe.relationship-lookup.external-source.import-modal.head.lcname": "এলসি নাম থেকে আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.orcid": "Importing from ORCID", + "submission.sections.describe.relationship-lookup.external-source.import-modal.head.orcid": "ORCID থেকে আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaJournal": "Importing from Sherpa Journal", + "submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaJournal": "শেরপা জার্নাল থেকে আমদানি করা হচ্ছে", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaPublisher": "Importing from Sherpa Publisher", + "submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaPublisher": "শেরপা প্রকাশক থেকে আমদানি করা হচ্ছে", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.pubmed": "Importing from PubMed", + "submission.sections.describe.relationship-lookup.external-source.import-modal.head.pubmed": "PubMed থেকে আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.head.arxiv": "Importing from arXiv", + "submission.sections.describe.relationship-lookup.external-source.import-modal.head.arxiv": "arXiv থেকে আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.import": "Import", + "submission.sections.describe.relationship-lookup.external-source.import-modal.import": "আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.title": "Import Remote Journal", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.title": "দূরবর্তী জার্নাল আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.local-entity": "Successfully added local journal to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.local-entity": "সফলভাবে নির্বাচন স্থানীয় জার্নাল যোগ করা", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.new-entity": "Successfully imported and added external journal to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.new-entity": "সফলভাবে আমদানি করা হয়েছে এবং নির্বাচনে বহিরাগত জার্নাল যোগ করা হয়েছে", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.title": "Import Remote Journal Issue", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.title": "দূরবর্তী জার্নাল ইস্যু আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.local-entity": "Successfully added local journal issue to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.local-entity": "নির্বাচনে স্থানীয় জার্নাল সমস্যা সফলভাবে যোগ করা হয়েছে", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.new-entity": "Successfully imported and added external journal issue to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.new-entity": "সফলভাবে আমদানি করা হয়েছে এবং নির্বাচনে বহিরাগত জার্নাল যোগ করা হয়েছে", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.title": "Import Remote Journal Volume", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.title": "দূরবর্তী জার্নাল ভলিউম আমদানি করুন", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.local-entity": "Successfully added local journal volume to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.local-entity": "নির্বাচনে স্থানীয় জার্নাল সমস্যা সফলভাবে যোগ করা হয়েছে", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.new-entity": "Successfully imported and added external journal volume to the selection", + "submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.new-entity": "সফলভাবে আমদানি করা হয়েছে এবং নির্বাচনে বহিরাগত জার্নাল যোগ করা হয়েছে", + + // "submission.sections.describe.relationship-lookup.external-source.import-modal.select": "Select a local match:", + "submission.sections.describe.relationship-lookup.external-source.import-modal.select": "একটি স্থানীয় মিল নির্বাচন করুন:", + + // "submission.sections.describe.relationship-lookup.search-tab.deselect-all": "Deselect all", + "submission.sections.describe.relationship-lookup.search-tab.deselect-all": "সব গুলো অনির্বাচিত করুন", + + // "submission.sections.describe.relationship-lookup.search-tab.deselect-page": "Deselect page", + "submission.sections.describe.relationship-lookup.search-tab.deselect-page": "পাতা অনির্বাচিত করুন", + + // "submission.sections.describe.relationship-lookup.search-tab.loading": "Loading...", + "submission.sections.describe.relationship-lookup.search-tab.loading": "লোড হচ্ছে ...", + + // "submission.sections.describe.relationship-lookup.search-tab.placeholder": "Search query", + "submission.sections.describe.relationship-lookup.search-tab.placeholder": "অনুসন্ধান কুয়েরি", + + // "submission.sections.describe.relationship-lookup.search-tab.search": "Go", + "submission.sections.describe.relationship-lookup.search-tab.search": "যান", + + // "submission.sections.describe.relationship-lookup.search-tab.search-form.placeholder": "Search...", + "submission.sections.describe.relationship-lookup.search-tab.search-form.placeholder": "অনুসন্ধান ...", + + // "submission.sections.describe.relationship-lookup.search-tab.select-all": "Select all", + "submission.sections.describe.relationship-lookup.search-tab.select-all": "সব নির্বাচন করুন", + + // "submission.sections.describe.relationship-lookup.search-tab.select-page": "Select page", + "submission.sections.describe.relationship-lookup.search-tab.select-page": "পৃষ্ঠা নির্বাচন করুন", + + // "submission.sections.describe.relationship-lookup.selected": "Selected {{ size }} items", + "submission.sections.describe.relationship-lookup.selected": "নির্বাচিত {{size}} আইটেমগুলো", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "Local Authors ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isAuthorOfPublication": "স্থানীয় লেখক ({{count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalOfPublication": "Local Journals ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalOfPublication": "স্থানীয় জার্নাল ({{count}})", + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Project": "Local Projects ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Project": "স্থানীয় প্রকল্প ({{count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Publication": "Local Publications ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Publication": "স্থানীয় প্রকাশনা ({count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "Local Authors ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Person": "স্থানীয় লেখক ({{count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "Local Organizational Units ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.OrgUnit": "স্থানীয় সাংগঠনিক ইউনিট ({{count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataPackage": "Local Data Packages ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataPackage": "স্থানীয় তথ্য প্যাকেজ ({{count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataFile": "Local Data Files ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.DataFile": "স্থানীয় তথ্য ফাইল ({{count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.Journal": "Local Journals ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.Journal": "স্থানীয় জার্নাল ({{count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalIssueOfPublication": "Local Journal Issues ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalIssueOfPublication": "স্থানীয় জার্নাল সমস্যা ({count}})", + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalIssue": "Local Journal Issues ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalIssue": "স্থানীয় জার্নাল সমস্যা ({count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalVolumeOfPublication": "Local Journal Volumes ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isJournalVolumeOfPublication": "স্থানীয় জার্নাল ভলিউম ({{count}})", + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalVolume": "Local Journal Volumes ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.JournalVolume": "স্থানীয় জার্নাল ভলিউম ({{count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaJournal": "Sherpa Journals ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaJournal": "শেরপা জার্নাল ({{count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaPublisher": "Sherpa Publishers ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.sherpaPublisher": "শেরপা পাবলিশার্স ({{count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.orcid": "ORCID ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.orcid": "ORCID ({{count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.lcname": "LC Names ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.lcname": "এলসি নাম ({{count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.pubmed": "PubMed ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.pubmed": "PubMed ({{count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.arxiv": "arXiv ({{ count }})", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.arxiv": "arXiv ({{count}})", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfPublication": "Search for Funding Agencies", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfPublication": "তহবিল সংস্থাগুলোর জন্য অনুসন্ধান করুন", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingOfPublication": "Search for Funding", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingOfPublication": "তহবিলের জন্য অনুসন্ধান করুন", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isChildOrgUnitOf": "Search for Organizational Units", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isChildOrgUnitOf": "সাংগঠনিক ইউনিট জন্য অনুসন্ধান করুন", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.openAIREFunding": "Funding OpenAIRE API", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.openAIREFunding": "OpenAIRE এ পি আই (API) কে আর্থিক ভাবে সাহায্য করা", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isProjectOfPublication": "Projects", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isProjectOfPublication": "প্রকল্প", + + // "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfProject": "Funder of the Project", + "submission.sections.describe.relationship-lookup.search-tab.tab-title.isFundingAgencyOfProject": "প্রকল্পের ফান্ডার", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.openAIREFunding": "Funding OpenAIRE API", + "submission.sections.describe.relationship-lookup.selection-tab.title.openAIREFunding": "OpenAIRE এ পি আই (API) কে আর্থিক ভাবে সাহায্য করা", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isProjectOfPublication": "Project", + "submission.sections.describe.relationship-lookup.selection-tab.title.isProjectOfPublication": "প্রকল্প", + + // "submission.sections.describe.relationship-lookup.title.isProjectOfPublication": "Projects", + "submission.sections.describe.relationship-lookup.title.isProjectOfPublication": "প্রকল্প", + + // "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfProject": "Funder of the Project", + "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfProject": "প্রকল্পেের জন্য আর্থিক ভাবে সাহায্যকারী", + + + + + // "submission.sections.describe.relationship-lookup.selection-tab.search-form.placeholder": "Search...", + "submission.sections.describe.relationship-lookup.selection-tab.search-form.placeholder": "অনুসন্ধান ...", + + // "submission.sections.describe.relationship-lookup.selection-tab.tab-title": "Current Selection ({{ count }})", + "submission.sections.describe.relationship-lookup.selection-tab.tab-title": "বর্তমান নির্বাচন ({{count}})", + + // "submission.sections.describe.relationship-lookup.title.isJournalIssueOfPublication": "Journal Issues", + "submission.sections.describe.relationship-lookup.title.isJournalIssueOfPublication": "জার্নাল সমস্যা", + // "submission.sections.describe.relationship-lookup.title.JournalIssue": "Journal Issues", + "submission.sections.describe.relationship-lookup.title.JournalIssue": "জার্নাল সমস্যা", + + // "submission.sections.describe.relationship-lookup.title.isJournalVolumeOfPublication": "Journal Volumes", + "submission.sections.describe.relationship-lookup.title.isJournalVolumeOfPublication": "জার্নাল ভলিউম", + // "submission.sections.describe.relationship-lookup.title.JournalVolume": "Journal Volumes", + "submission.sections.describe.relationship-lookup.title.JournalVolume": "জার্নাল ভলিউম", + + // "submission.sections.describe.relationship-lookup.title.isJournalOfPublication": "Journals", + "submission.sections.describe.relationship-lookup.title.isJournalOfPublication": "জার্নাল", + + // "submission.sections.describe.relationship-lookup.title.isAuthorOfPublication": "Authors", + "submission.sections.describe.relationship-lookup.title.isAuthorOfPublication": "লেখক", + + // "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfPublication": "Funding Agency", + "submission.sections.describe.relationship-lookup.title.isFundingAgencyOfPublication": "তহবিল সংস্থা", + // "submission.sections.describe.relationship-lookup.title.Project": "Projects", + "submission.sections.describe.relationship-lookup.title.Project": "প্রকল্প", + + // "submission.sections.describe.relationship-lookup.title.Publication": "Publications", + "submission.sections.describe.relationship-lookup.title.Publication": "প্রকাশনা", + + // "submission.sections.describe.relationship-lookup.title.Person": "Authors", + "submission.sections.describe.relationship-lookup.title.Person": "লেখক", + + // "submission.sections.describe.relationship-lookup.title.OrgUnit": "Organizational Units", + "submission.sections.describe.relationship-lookup.title.OrgUnit": "সাংগঠনিক ইউনিট", + + // "submission.sections.describe.relationship-lookup.title.DataPackage": "Data Packages", + "submission.sections.describe.relationship-lookup.title.DataPackage": "তথ্য প্যাকেজ", + + // "submission.sections.describe.relationship-lookup.title.DataFile": "Data Files", + "submission.sections.describe.relationship-lookup.title.DataFile": "ডাটা ফাইল", + + // "submission.sections.describe.relationship-lookup.title.Funding Agency": "Funding Agency", + "submission.sections.describe.relationship-lookup.title.Funding Agency": "তহবিল সংস্থা", + + // "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "Funding", + "submission.sections.describe.relationship-lookup.title.isFundingOfPublication": "তহবিল", + + // "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "Parent Organizational Unit", + "submission.sections.describe.relationship-lookup.title.isChildOrgUnitOf": "অভিভাবক সাংগঠনিক ইউনিট", + + // "submission.sections.describe.relationship-lookup.search-tab.toggle-dropdown": "Toggle dropdown", + "submission.sections.describe.relationship-lookup.search-tab.toggle-dropdown": "ড্রপডাউন টগল করুন", + + // "submission.sections.describe.relationship-lookup.selection-tab.settings": "Settings", + "submission.sections.describe.relationship-lookup.selection-tab.settings": "সেটিংস", + + // "submission.sections.describe.relationship-lookup.selection-tab.no-selection": "Your selection is currently empty.", + "submission.sections.describe.relationship-lookup.selection-tab.no-selection": "আপনার নির্বাচন বর্তমানে খালি।", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isAuthorOfPublication": "Selected Authors", + "submission.sections.describe.relationship-lookup.selection-tab.title.isAuthorOfPublication": "নির্বাচিত লেখক", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalOfPublication": "Selected Journals", + "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalOfPublication": "নির্বাচিত জার্নাল", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalVolumeOfPublication": "Selected Journal Volume", + "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalVolumeOfPublication": "নির্বাচিত জার্নাল ভলিউম", + // "submission.sections.describe.relationship-lookup.selection-tab.title.Project": "Selected Projects", + "submission.sections.describe.relationship-lookup.selection-tab.title.Project": "নির্বাচিত প্রকল্প", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.Publication": "Selected Publications", + "submission.sections.describe.relationship-lookup.selection-tab.title.Publication": "নির্বাচিত প্রকাশনা", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.Person": "Selected Authors", + "submission.sections.describe.relationship-lookup.selection-tab.title.Person": "নির্বাচিত লেখক", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.OrgUnit": "Selected Organizational Units", + "submission.sections.describe.relationship-lookup.selection-tab.title.OrgUnit": "নির্বাচিত সাংগঠনিক ইউনিট", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.DataPackage": "Selected Data Packages", + "submission.sections.describe.relationship-lookup.selection-tab.title.DataPackage": "নির্বাচিত তথ্য প্যাকেজ", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.DataFile": "Selected Data Files", + "submission.sections.describe.relationship-lookup.selection-tab.title.DataFile": "নির্বাচিত তথ্য ফাইল", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.Journal": "Selected Journals", + "submission.sections.describe.relationship-lookup.selection-tab.title.Journal": "নির্বাচিত জার্নাল", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalIssueOfPublication": "Selected Issue", + "submission.sections.describe.relationship-lookup.selection-tab.title.isJournalIssueOfPublication": "নির্বাচিত সমস্যা", + // "submission.sections.describe.relationship-lookup.selection-tab.title.JournalVolume": "Selected Journal Volume", + "submission.sections.describe.relationship-lookup.selection-tab.title.JournalVolume": "নির্বাচিত জার্নাল ভলিউম", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingAgencyOfPublication": "Selected Funding Agency", + "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingAgencyOfPublication": "নির্বাচিত তহবিল সংস্থা", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingOfPublication": "Selected Funding", + "submission.sections.describe.relationship-lookup.selection-tab.title.isFundingOfPublication": "নির্বাচিত তহবিল", + // "submission.sections.describe.relationship-lookup.selection-tab.title.JournalIssue": "Selected Issue", + "submission.sections.describe.relationship-lookup.selection-tab.title.JournalIssue": "নির্বাচিত সমস্যা", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.isChildOrgUnitOf": "Selected Organizational Unit", + "submission.sections.describe.relationship-lookup.selection-tab.title.isChildOrgUnitOf": "নির্বাচিত সাংগঠনিক ইউনিট", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaJournal": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaJournal": "অনুসন্ধানের ফলাফল", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaPublisher": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.sherpaPublisher": "অনুসন্ধানের ফলাফল", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.orcid": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.orcid": "অনুসন্ধানের ফলাফল", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.orcidv2": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.orcidv2": "অনুসন্ধানের ফলাফল", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.lcname": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.lcname": "অনুসন্ধানের ফলাফল", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.pubmed": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.pubmed": "অনুসন্ধানের ফলাফল", + + // "submission.sections.describe.relationship-lookup.selection-tab.title.arxiv": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.arxiv": "অনুসন্ধানের ফলাফল", + + // "submission.sections.describe.relationship-lookup.name-variant.notification.content": "Would you like to save \"{{ value }}\" as a name variant for this person so you and others can reuse it for future submissions? If you don\'t you can still use it for this submission.", + "submission.sections.describe.relationship-lookup.name-variant.notification.content": "আপনি এই ব্যক্তির জন্য একটি নাম বৈকল্পিক \"{{ value }}\" হিসাবে সংরক্ষণ করতে চান তাই আপনি এবং অন্যদের ভবিষ্যতের জমা দেওয়ার জন্য এটি পুনঃব্যবহার করতে পারেন? আপনি যদি আপনি এই জমা দেওয়ার জন্য এখনও এটি ব্যবহার করতে পারেন না।", + + // "submission.sections.describe.relationship-lookup.name-variant.notification.confirm": "Save a new name variant", + "submission.sections.describe.relationship-lookup.name-variant.notification.confirm": "একটি নতুন নাম বৈকল্পিক সংরক্ষণ করুন", + + // "submission.sections.describe.relationship-lookup.name-variant.notification.decline": "Use only for this submission", + "submission.sections.describe.relationship-lookup.name-variant.notification.decline": "এই জমা জন্য শুধুমাত্র ব্যবহার করুন", + + // "submission.sections.ccLicense.type": "License Type", + "submission.sections.ccLicense.type": "লাইসেন্সের ধরন", + + // "submission.sections.ccLicense.select": "Select a license type…", + "submission.sections.ccLicense.select": "একটি লাইসেন্সের ধরন নির্বাচন করুন ...", + + // "submission.sections.ccLicense.change": "Change your license type…", + "submission.sections.ccLicense.change": "আপনার লাইসেন্সের ধরন পরিবর্তন করুন ...", + + // "submission.sections.ccLicense.none": "No licenses available", + "submission.sections.ccLicense.none": "কোন লাইসেন্স পাওয়া যাই নি", + + // "submission.sections.ccLicense.option.select": "Select an option…", + "submission.sections.ccLicense.option.select": "যেকোনো একটি নির্বাচন করুন…", + + // "submission.sections.ccLicense.link": "You’ve selected the following license:", + "submission.sections.ccLicense.link": "আপনি নিম্নলিখিত লাইসেন্স নির্বাচন করেছেন:", + + // "submission.sections.ccLicense.confirmation": "I grant the license above", + "submission.sections.ccLicense.confirmation": "আমি উপরের লাইসেন্স অনুমোদন করেছি", + + // "submission.sections.general.add-more": "Add more", + "submission.sections.general.add-more": "আরো যোগ করো", + + // "submission.sections.general.collection": "Collection", + "submission.sections.general.collection": "সংগ্রহ", + + // "submission.sections.general.deposit_error_notice": "There was an issue when submitting the item, please try again later.", + "submission.sections.general.deposit_error_notice": "আইটেমটি জমা দেওয়ার সময় একটি সমস্যা ছিল, দয়া করে পরে আবার চেষ্টা করুন।", + + // "submission.sections.general.deposit_success_notice": "Submission deposited successfully.", + "submission.sections.general.deposit_success_notice": "নথি সফলভাবে জমা দেয়ে হয়েছে।", + + // "submission.sections.general.discard_error_notice": "There was an issue when discarding the item, please try again later.", + "submission.sections.general.discard_error_notice": "আইটেমটি বাতিল করার সময় একটি সমস্যা ছিল দয়া করে পরে আবার চেষ্টা করুন।", + + // "submission.sections.general.discard_success_notice": "Submission discarded successfully.", + "submission.sections.general.discard_success_notice": "নথি সফলভাবে বাতিল করা হয়েছে।", + + // "submission.sections.general.metadata-extracted": "New metadata have been extracted and added to the {{sectionId}} section.", + "submission.sections.general.metadata-extracted": "নতুন মেটাডাটা নিষ্কাশন করা হয়েছে এবং {{sectionId}} বিভাগে যোগ করা হয়েছে।", + + // "submission.sections.general.metadata-extracted-new-section": "New {{sectionId}} section has been added to submission.", + "submission.sections.general.metadata-extracted-new-section": "নতুন {{sectionId}} বিভাগটি জমা দেওয়ার জন্য যুক্ত করা হয়েছে।", + + // "submission.sections.general.no-collection": "No collection found", + "submission.sections.general.no-collection": "কোন সংগ্রহ পাওয়া যায় নি", + + // "submission.sections.general.no-sections": "No options available", + "submission.sections.general.no-sections": "কোন বিকল্প নেই", + + // "submission.sections.general.save_error_notice": "There was an issue when saving the item, please try again later.", + "submission.sections.general.save_error_notice": "আইটেমটি সংরক্ষণ করার সময় একটি সমস্যা ছিল, দয়া করে পরে আবার চেষ্টা করুন।", + + // "submission.sections.general.save_success_notice": "Submission saved successfully.", + "submission.sections.general.save_success_notice": "নথি সফলভাবে সংরক্ষিত।", + + // "submission.sections.general.search-collection": "Search for a collection", + "submission.sections.general.search-collection": "একটি সংগ্রহের জন্য অনুসন্ধান করুন", + + // "submission.sections.general.sections_not_valid": "There are incomplete sections.", + "submission.sections.general.sections_not_valid": "অসম্পূর্ণ বিভাগ আছে।", + + + + // "submission.sections.submit.progressbar.accessCondition": "Item access conditions", + "submission.sections.submit.progressbar.accessCondition": "আইটেম অ্যাক্সেসের শর্তাবলী", + + // "submission.sections.submit.progressbar.CClicense": "Creative commons license", + "submission.sections.submit.progressbar.CClicense": "ক্রিয়েটিভ কমন্স লাইসেন্স", + + // "submission.sections.submit.progressbar.describe.recycle": "Recycle", + "submission.sections.submit.progressbar.describe.recycle": "পুনরাই ব্যবহারযোগ্য করুন", + + // "submission.sections.submit.progressbar.describe.stepcustom": "Describe", + "submission.sections.submit.progressbar.describe.stepcustom": "বর্ণনা করুন", + + // "submission.sections.submit.progressbar.describe.stepone": "Describe", + "submission.sections.submit.progressbar.describe.stepone": "বর্ণনা করুন", + + // "submission.sections.submit.progressbar.describe.steptwo": "Describe", + "submission.sections.submit.progressbar.describe.steptwo": "বর্ণনা করুন", + + // "submission.sections.submit.progressbar.detect-duplicate": "Potential duplicates", + "submission.sections.submit.progressbar.detect-duplicate": "সম্ভাব্য ডুপ্লিকেট", + + // "submission.sections.submit.progressbar.license": "Deposit license", + "submission.sections.submit.progressbar.license": "আমানত লাইসেন্স", + + // "submission.sections.submit.progressbar.upload": "Upload files", + "submission.sections.submit.progressbar.upload": "ফাইল আপলোড", + + + + // "submission.sections.status.errors.title": "Errors", + "submission.sections.status.errors.title": "ত্রুটি", + + // "submission.sections.status.valid.title": "Valid", + "submission.sections.status.valid.title": "বৈধ", + + // "submission.sections.status.warnings.title": "Warnings", + "submission.sections.status.warnings.title": "সতর্কতা", + + // "submission.sections.status.errors.aria": "has errors", + "submission.sections.status.errors.aria": "ত্রুটি আছে", + + // "submission.sections.status.valid.aria": "is valid", + "submission.sections.status.valid.aria": "বৈধ", + + // "submission.sections.status.warnings.aria": "has warnings", + "submission.sections.status.warnings.aria": "সতর্কতা আছে", + + // "submission.sections.toggle.open": "Open section", + "submission.sections.toggle.open": "বিভাগ খুলুন", + + // "submission.sections.toggle.close": "Close section", + "submission.sections.toggle.close": "বিভাগ বন্ধ করুন", + + // "submission.sections.toggle.aria.open": "Expand {{sectionHeader}} section", + "submission.sections.toggle.aria.open": "বিস্তৃত করুন {{sectionHeader}} বিভাগ", + + // "submission.sections.toggle.aria.close": "Collapse {{sectionHeader}} section", + "submission.sections.toggle.aria.close": "বন্ধ করুন {{ sectionHeader }} বিভাগ", + + // "submission.sections.upload.delete.confirm.cancel": "Cancel", + "submission.sections.upload.delete.confirm.cancel": "বাতিল করুন", + + // "submission.sections.upload.delete.confirm.info": "This operation can't be undone. Are you sure?", + "submission.sections.upload.delete.confirm.info": "এই অপারেশন পূর্বাবস্থায় ফেরানো যাবে না। তুমি কি নিশ্চিত?", + + // "submission.sections.upload.delete.confirm.submit": "Yes, I'm sure", + "submission.sections.upload.delete.confirm.submit": "হ্যা, আমি নিশ্চিত", + + // "submission.sections.upload.delete.confirm.title": "Delete bitstream", + "submission.sections.upload.delete.confirm.title": "বিটস্ট্রিম মুছুন", + + // "submission.sections.upload.delete.submit": "Delete", + "submission.sections.upload.delete.submit": "মুছে ফেলা", + + // "submission.sections.upload.download.title": "Download bitstream", + "submission.sections.upload.download.title": "বিটস্ট্রিম ডাউনলোড করুন", + + // "submission.sections.upload.drop-message": "Drop files to attach them to the item", + "submission.sections.upload.drop-message": "ফাইলগুলিকে আইটেমের সাথে সংযুক্ত করতে ড্রপ করুন৷", + + // "submission.sections.upload.edit.title": "Edit bitstream", + "submission.sections.upload.edit.title": "বিটস্ট্রিম সম্পাদনা করুন", + + // "submission.sections.upload.form.access-condition-label": "Access condition type", + "submission.sections.upload.form.access-condition-label": "অ্যাক্সেস শর্ত টাইপ", + + // "submission.sections.upload.form.access-condition-hint": "Select an access condition to apply on the bitstream once the item is deposited", + "submission.sections.upload.form.access-condition-hint": "আইটেমটি জমা দেওয়ার পরে বিটস্ট্রিমে আবেদন করার জন্য একটি অ্যাক্সেস শর্ত নির্বাচন করুন", + + // "submission.sections.upload.form.date-required": "Date is required.", + "submission.sections.upload.form.date-required": "তারিখ প্রয়োজন।", + + // "submission.sections.upload.form.date-required-from": "Grant access from date is required.", + "submission.sections.upload.form.date-required-from": "যে তারিখ থেকে প্রবেশাধিকার প্রয়োজন", + + // "submission.sections.upload.form.date-required-until": "Grant access until date is required.", + "submission.sections.upload.form.date-required-until": "যে তারিখ পর্যন্ত অ্যাক্সেস মঞ্জুর প্রয়োজন", + + // "submission.sections.upload.form.from-label": "Grant access from", + "submission.sections.upload.form.from-label": "যখন থেকে অ্যাক্সেস মঞ্জুর করবেন", + + // "submission.sections.upload.form.from-hint": "Select the date from which the related access condition is applied", + "submission.sections.upload.form.from-hint": "যে তারিখ থেকে সম্পর্কিত অ্যাক্সেস শর্ত প্রয়োগ করা হয়েছে তা নির্বাচন করুন", + + // "submission.sections.upload.form.from-placeholder": "From", + "submission.sections.upload.form.from-placeholder": "থেকে", + + // "submission.sections.upload.form.group-label": "Group", + "submission.sections.upload.form.group-label": "গ্রুপ", + + // "submission.sections.upload.form.group-required": "Group is required.", + "submission.sections.upload.form.group-required": "গ্রুপ প্রয়োজন।", + + // "submission.sections.upload.form.until-label": "Grant access until", + "submission.sections.upload.form.until-label": "অ্যাক্সেস অনুমোদন করুন যতক্ষণ পর্যন্ত না", + + // "submission.sections.upload.form.until-hint": "Select the date until which the related access condition is applied", + "submission.sections.upload.form.until-hint": "যে তারিখ থেকে সম্পর্কিত অ্যাক্সেস শর্ত প্রয়োগ করা হয়েছে তা নির্বাচন করুন", + + // "submission.sections.upload.form.until-placeholder": "Until", + "submission.sections.upload.form.until-placeholder": "যতক্ষণ পর্যন্ত", + + // "submission.sections.upload.header.policy.default.nolist": "Uploaded files in the {{collectionName}} collection will be accessible according to the following group(s):", + "submission.sections.upload.header.policy.default.nolist": "{{collectionName}} সংগ্রহে আপলোড করা ফাইলগুলি নিম্নলিখিত গ্রুপ(গুলি) অনুসারে অ্যাক্সেসযোগ্য হবে:", + + // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", + "submission.sections.upload.header.policy.default.withlist": "অনুগ্রহ করে মনে রাখবেন যে {{collectionName}} সংগ্রহে আপলোড করা ফাইলগুলি অ্যাক্সেসযোগ্য হবে, একক ফাইলের জন্য স্পষ্টভাবে যা নির্ধারণ করা হয়েছে তা ছাড়াও, নিম্নলিখিত গ্রুপ(গুলি) সহ:", + + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + "submission.sections.upload.info": "এখানে আপনি বর্তমানে আইটেমটিতে সমস্ত ফাইল পাবেন। আপনি ফাইল মেটাডেটা এবং অ্যাক্সেস শর্তাদি আপডেট করতে পারেন অথবা অতিরিক্ত ফাইল আপলোড করুন - পৃষ্ঠাটিতে সর্বত্র ড্র্যাগ করুন এবং ড্রপ করুন ", + + // "submission.sections.upload.no-entry": "No", + "submission.sections.upload.no-entry": "না", + + // "submission.sections.upload.no-file-uploaded": "No file uploaded yet.", + "submission.sections.upload.no-file-uploaded": "কোন ফাইল এখনো আপলোড হয়নি।", + + // "submission.sections.upload.save-metadata": "Save metadata", + "submission.sections.upload.save-metadata": "মেটাডেটা সংরক্ষণ করুন", + + // "submission.sections.upload.undo": "Cancel", + "submission.sections.upload.undo": "বাতিল করুন", + + // "submission.sections.upload.upload-failed": "Upload failed", + "submission.sections.upload.upload-failed": "আপলোড ব্যর্থ হয়েছে", + + // "submission.sections.upload.upload-successful": "Upload successful", + "submission.sections.upload.upload-successful": "সফল আপলোড করুন", + + // "submission.sections.accesses.form.discoverable-description": "When checked, this item will be discoverable in search/browse. When unchecked, the item will only be available via a direct link and will never appear in search/browse.", + "submission.sections.accesses.form.discoverable-description": "চেক যখন এই আইটেমটি অনুসন্ধান / ব্রাউজ আবিষ্কারযোগ্য হবে। আইটেমটি unchecked যখন শুধুমাত্র সরাসরি লিঙ্কের মাধ্যমে উপলব্ধ হবে এবং অনুসন্ধান / ব্রাউজ প্রদর্শিত হবে না।", + + // "submission.sections.accesses.form.discoverable-label": "Discoverable", + "submission.sections.accesses.form.discoverable-label": "আবিষ্কারযোগ্য", + + // "submission.sections.accesses.form.access-condition-label": "Access condition type", + "submission.sections.accesses.form.access-condition-label": "অ্যাক্সেস শর্তের ধরন", + + // "submission.sections.accesses.form.access-condition-hint": "Select an access condition to apply on the item once it is deposited", + "submission.sections.accesses.form.access-condition-hint": "আইটেমটি জমা হওয়ার পরে আবেদন করার জন্য একটি অ্যাক্সেস শর্ত নির্বাচন করুন", + + // "submission.sections.accesses.form.date-required": "Date is required.", + "submission.sections.accesses.form.date-required": "তারিখ প্রয়োজন।", + + // "submission.sections.accesses.form.date-required-from": "Grant access from date is required.", + "submission.sections.accesses.form.date-required-from": "যে তারিখ থেকে প্রবেশাধিকার প্রয়োজন", + + // "submission.sections.accesses.form.date-required-until": "Grant access until date is required.", + "submission.sections.accesses.form.date-required-until": "যে তারিখ পর্যন্ত অ্যাক্সেস অনুমোদন প্রয়োজন।", + + // "submission.sections.accesses.form.from-label": "Grant access from", + "submission.sections.accesses.form.from-label": "যখন থেকে অ্যাক্সেস মঞ্জুর করবেন", + + // "submission.sections.accesses.form.from-hint": "Select the date from which the related access condition is applied", + "submission.sections.accesses.form.from-hint": "যে তারিখ থেকে সম্পর্কিত অ্যাক্সেস শর্ত প্রয়োগ করা হয়েছে তা নির্বাচন করুন", + + // "submission.sections.accesses.form.from-placeholder": "From", + "submission.sections.accesses.form.from-placeholder": "থেকে", + + // "submission.sections.accesses.form.group-label": "Group", + "submission.sections.accesses.form.group-label": "গ্রুপ", + + // "submission.sections.accesses.form.group-required": "Group is required.", + "submission.sections.accesses.form.group-required": "গ্রুপ প্রয়োজন।", + + // "submission.sections.accesses.form.until-label": "Grant access until", + "submission.sections.accesses.form.until-label": "অ্যাক্সেস অনুমোদন করুন যতক্ষণ পর্যন্ত না", + + // "submission.sections.accesses.form.until-hint": "Select the date until which the related access condition is applied", + "submission.sections.accesses.form.until-hint": "সংশ্লিষ্ট অ্যাক্সেস শর্ত প্রযোজ্য হওয়া পর্যন্ত তারিখটি নির্বাচন করুন", + + // "submission.sections.accesses.form.until-placeholder": "Until", + "submission.sections.accesses.form.until-placeholder": "পর্যন্ত", + + + // "submission.submit.breadcrumbs": "New submission", + "submission.submit.breadcrumbs": "নতুন নথি/জমা", + + // "submission.submit.title": "New submission", + "submission.submit.title": "নতুন নথি/জমা", + + + + // "submission.workflow.generic.delete": "Delete", + "submission.workflow.generic.delete": "মুছে ফেলা", + + // "submission.workflow.generic.delete-help": "If you would to discard this item, select \"Delete\". You will then be asked to confirm it.", + "submission.workflow.generic.delete-help": "আপনি এই আইটেমটি বাতিল করতে চান \"মুছে ফেলুন\"। তারপর আপনি এটি নিশ্চিত করতে বলা হবে।", + + // "submission.workflow.generic.edit": "Edit", + "submission.workflow.generic.edit": "সম্পাদনা করুন", + + // "submission.workflow.generic.edit-help": "Select this option to change the item's metadata.", + "submission.workflow.generic.edit-help": "আইটেমটির মেটাডেটা পরিবর্তন করার জন্য এই বিকল্পটি নির্বাচন করুন।", + + // "submission.workflow.generic.view": "View", + "submission.workflow.generic.view": "দেখুন", + + // "submission.workflow.generic.view-help": "Select this option to view the item's metadata.", + "submission.workflow.generic.view-help": "আইটেমটির মেটাডাটা দেখতে এই বিকল্পটি নির্বাচন করুন।", + + + + // "submission.workflow.tasks.claimed.approve": "Approve", + "submission.workflow.tasks.claimed.approve": "অনুমোদন", + + // "submission.workflow.tasks.claimed.approve_help": "If you have reviewed the item and it is suitable for inclusion in the collection, select \"Approve\".", + "submission.workflow.tasks.claimed.approve_help": "আপনি যদি আইটেমটি পর্যালোচনা করেছেন এবং এটি সংগ্রহের অন্তর্ভুক্তির জন্য উপযুক্ত। \"অনুমোদন\" নির্বাচন করুন।", + + // "submission.workflow.tasks.claimed.edit": "Edit", + "submission.workflow.tasks.claimed.edit": "সম্পাদনা করুন", + + // "submission.workflow.tasks.claimed.edit_help": "Select this option to change the item's metadata.", + "submission.workflow.tasks.claimed.edit_help": "আইটেমটির মেটাডেটা পরিবর্তন করার জন্য এই বিকল্পটি নির্বাচন করুন।", + + // "submission.workflow.tasks.claimed.reject.reason.info": "Please enter your reason for rejecting the submission into the box below, indicating whether the submitter may fix a problem and resubmit.", + "submission.workflow.tasks.claimed.reject.reason.info": "অনুগ্রহ করে নীচের বাক্সে জমা দেওয়ার প্রত্যাখ্যান করার জন্য আপনার কারণটি প্রবেশ করান কিনা তা নির্দেশ করে যে জমাটি একটি সমস্যা সমাধান করতে পারে এবং পুনরায় জমা দিতে পারে কিনা তা নির্দেশ করে।", + + // "submission.workflow.tasks.claimed.reject.reason.placeholder": "Describe the reason of reject", + "submission.workflow.tasks.claimed.reject.reason.placeholder": "প্রত্যাখ্যানের কারণ বর্ণনা করুন", + + // "submission.workflow.tasks.claimed.reject.reason.submit": "Reject item", + "submission.workflow.tasks.claimed.reject.reason.submit": "আইটেম প্রত্যাখ্যান করুন", + + // "submission.workflow.tasks.claimed.reject.reason.title": "Reason", + "submission.workflow.tasks.claimed.reject.reason.title": "কারণ", + + // "submission.workflow.tasks.claimed.reject.submit": "Reject", + "submission.workflow.tasks.claimed.reject.submit": "প্রত্যাখ্যান", + + // "submission.workflow.tasks.claimed.reject_help": "If you have reviewed the item and found it is not suitable for inclusion in the collection, select \"Reject\". You will then be asked to enter a message indicating why the item is unsuitable, and whether the submitter should change something and resubmit.", + "submission.workflow.tasks.claimed.reject_help": "যদি আপনি আইটেমটি পর্যালোচনা করেছেন এবং এটি খুঁজে পেয়েছেন এটি না সংগ্রহের অন্তর্ভুক্তির জন্য উপযুক্ত \"প্রত্যাখ্যান\"। তারপর আপনাকে একটি বার্তা প্রবেশ করতে বলা হবে যে আইটেমটি অনুপযুক্ত কেন এবং জমা দেওয়ার কিছু পরিবর্তন এবং পুনরায় জমা দিতে হবে কিনা।", + + // "submission.workflow.tasks.claimed.return": "Return to pool", + "submission.workflow.tasks.claimed.return": "পুলে ফিরে যান", + + // "submission.workflow.tasks.claimed.return_help": "Return the task to the pool so that another user may perform the task.", + "submission.workflow.tasks.claimed.return_help": "পুলে টাস্কটি ফেরত দিন যাতে অন্য ব্যবহারকারীটি কাজটি সম্পাদন করতে পারে।", + + + + // "submission.workflow.tasks.generic.error": "Error occurred during operation...", + "submission.workflow.tasks.generic.error": "অপারেশন চলাকালীন ত্রুটি ঘটেছে ...", + + // "submission.workflow.tasks.generic.processing": "Processing...", + "submission.workflow.tasks.generic.processing": "প্রক্রিয়াকরণ ...", + + // "submission.workflow.tasks.generic.submitter": "Submitter", + "submission.workflow.tasks.generic.submitter": "জমাদানকারী", + + // "submission.workflow.tasks.generic.success": "Operation successful", + "submission.workflow.tasks.generic.success": "কাজটি সফল হয়েছে", + + + + // "submission.workflow.tasks.pool.claim": "Claim", + "submission.workflow.tasks.pool.claim": "দাবি", + + // "submission.workflow.tasks.pool.claim_help": "Assign this task to yourself.", + "submission.workflow.tasks.pool.claim_help": "নিজেকে এই টাস্ক বরাদ্দ করুন।", + + // "submission.workflow.tasks.pool.hide-detail": "Hide detail", + "submission.workflow.tasks.pool.hide-detail": "বিস্তারিত লুকান", + + // "submission.workflow.tasks.pool.show-detail": "Show detail", + "submission.workflow.tasks.pool.show-detail": "বিস্তারিত দেখাও", + + + + // "thumbnail.default.alt": "Thumbnail Image", + "thumbnail.default.alt": "থাম্বনেইল ইমেজ", + + // "thumbnail.default.placeholder": "No Thumbnail Available", + "thumbnail.default.placeholder": "কোন থাম্বনেইল পাওয়া যাই নি", + + // "thumbnail.project.alt": "Project Logo", + "thumbnail.project.alt": "প্রকল্পের লোগো", + + // "thumbnail.project.placeholder": "Project Placeholder Image", + "thumbnail.project.placeholder": "প্রকল্প স্থানধারক ছবি", + + // "thumbnail.orgunit.alt": "OrgUnit Logo", + "thumbnail.orgunit.alt": "অরগ ইউনিট লোগো", + + // "thumbnail.orgunit.placeholder": "OrgUnit Placeholder Image", + "thumbnail.orgunit.placeholder": "অরগ ইউনিট স্থানধারক ছবি", + + // "thumbnail.person.alt": "Profile Picture", + "thumbnail.person.alt": "প্রোফাইল ছবি", + + // "thumbnail.person.placeholder": "No Profile Picture Available", + "thumbnail.person.placeholder": "কোন প্রোফাইল ছবি পাওয়া যাই নি", + + + + // "title": "DSpace", + "title": "ডিস্পেস", + + + + // "vocabulary-treeview.header": "Hierarchical tree view", + "vocabulary-treeview.header": "শ্রেণীবিন্যাস ট্রি ভিউ", + + // "vocabulary-treeview.load-more": "Load more", + "vocabulary-treeview.load-more": "আর লোড করুন", + + // "vocabulary-treeview.search.form.reset": "Reset", + "vocabulary-treeview.search.form.reset": "রিসেট", + + // "vocabulary-treeview.search.form.search": "Search", + "vocabulary-treeview.search.form.search": "অনুসন্ধান করুন", + + // "vocabulary-treeview.search.no-result": "There were no items to show", + "vocabulary-treeview.search.no-result": "দেখানোর জন্য কোন আইটেম ছিল না", + + // "vocabulary-treeview.tree.description.nsi": "The Norwegian Science Index", + "vocabulary-treeview.tree.description.nsi": "নরওয়েজিয়ান বিজ্ঞান সূচক", + + // "vocabulary-treeview.tree.description.srsc": "Research Subject Categories", + "vocabulary-treeview.tree.description.srsc": "গবেষণা বিষয় বিভাগ", + + + + // "uploader.browse": "browse", + "uploader.browse": "ব্রাউজ করুন", + + // "uploader.drag-message": "Drag & Drop your files here", + "uploader.drag-message": "এখানে আপনার ফাইল ড্র্যাগ এবং ড্রপ করুন", + + // "uploader.delete.btn-title": "Delete", + "uploader.delete.btn-title": "মুছুন", + + // "uploader.or": ", or ", + "uploader.or": "অথবা", + + // "uploader.processing": "Processing", + "uploader.processing": "প্রক্রিয়াকরণ", + + // "uploader.queue-length": "Queue length", + "uploader.queue-length": "সারির দৈর্ঘ্য", + + // "virtual-metadata.delete-item.info": "Select the types for which you want to save the virtual metadata as real metadata", + "virtual-metadata.delete-item.info": "আপনি প্রকৃত মেটাডাটা হিসাবে ভার্চুয়াল মেটাডাটা সংরক্ষণ করতে চান এমন ধরনের নির্বাচন করুন", + + // "virtual-metadata.delete-item.modal-head": "The virtual metadata of this relation", + "virtual-metadata.delete-item.modal-head": "এই সম্পর্কের ভার্চুয়াল মেটাডাটা", + + // "virtual-metadata.delete-relationship.modal-head": "Select the items for which you want to save the virtual metadata as real metadata", + "virtual-metadata.delete-relationship.modal-head": "রিয়েল মেটাডেটা হিসাবে আপনি ভার্চুয়াল মেটাডেটা সংরক্ষণ করতে চান এমন আইটেমগুলি নির্বাচন করুন", + + + + // "workspace.search.results.head": "Your submissions", + "workspace.search.results.head": "আপনার জমা দেয়া নথি", + + // "workflowAdmin.search.results.head": "Administer Workflow", + "workflowAdmin.search.results.head": "প্রশাসনিক কর্মধারা", + + // "workflow.search.results.head": "Workflow tasks", + "workflow.search.results.head": "ওয়ার্কফ্লো কাজ", + + + + // "workflow-item.edit.breadcrumbs": "Edit workflowitem", + "workflow-item.edit.breadcrumbs": "ওয়ার্কফ্লিউটেম সম্পাদনা করুন", + + // "workflow-item.edit.title": "Edit workflowitem", + "workflow-item.edit.title": "ওয়ার্কফ্লিউটেম সম্পাদনা করুন", + + // "workflow-item.delete.notification.success.title": "Deleted", + "workflow-item.delete.notification.success.title": "মুছে ফেলা হয়েছে", + + // "workflow-item.delete.notification.success.content": "This workflow item was successfully deleted", + "workflow-item.delete.notification.success.content": "এই ওয়ার্কফ্লো আইটেম সফলভাবে মুছে ফেলা হয়েছে", + + // "workflow-item.delete.notification.error.title": "Something went wrong", + "workflow-item.delete.notification.error.title": "কিছু ভুল হয়েছে", + + // "workflow-item.delete.notification.error.content": "The workflow item could not be deleted", + "workflow-item.delete.notification.error.content": "ওয়ার্কফ্লো আইটেম মুছে ফেলা যাবে না", + + // "workflow-item.delete.title": "Delete workflow item", + "workflow-item.delete.title": "ওয়ার্কফ্লো আইটেম মুছে দিন", + + // "workflow-item.delete.header": "Delete workflow item", + "workflow-item.delete.header": "ওয়ার্কফ্লো আইটেম মুছে দিন", + + // "workflow-item.delete.button.cancel": "Cancel", + "workflow-item.delete.button.cancel": "বাতিল করুন", + + // "workflow-item.delete.button.confirm": "Delete", + "workflow-item.delete.button.confirm": "মুছে ফেলা", + + + // "workflow-item.send-back.notification.success.title": "Sent back to submitter", + "workflow-item.send-back.notification.success.title": "জমাদানকারির কাছে ফিরত পাঠান", + + // "workflow-item.send-back.notification.success.content": "This workflow item was successfully sent back to the submitter", + "workflow-item.send-back.notification.success.content": "এই ওয়ার্কফ্লো আইটেম সফলভাবে জমাকারী ফিরে পাঠানো হয়েছে", + + // "workflow-item.send-back.notification.error.title": "Something went wrong", + "workflow-item.send-back.notification.error.title": "কিছু ভুল হয়েছে", + + // "workflow-item.send-back.notification.error.content": "The workflow item could not be sent back to the submitter", + "workflow-item.send-back.notification.error.content": "ওয়ার্কফ্লো আইটেম জমাদানকারির কাছে ফেরত পাঠানো যাই নি", + + // "workflow-item.send-back.title": "Send workflow item back to submitter", + "workflow-item.send-back.title": "ওয়ার্কফ্লো আইটেম জমাদানকারির কাছে ফেরত পাঠান", + + // "workflow-item.send-back.header": "Send workflow item back to submitter", + "workflow-item.send-back.header": "ওয়ার্কফ্লো আইটেম জমাদানকারির কাছে ফেরত পাঠান", + + // "workflow-item.send-back.button.cancel": "Cancel", + "workflow-item.send-back.button.cancel": "বাতিল করুন", + + // "workflow-item.send-back.button.confirm": "Send back", + "workflow-item.send-back.button.confirm": "ফেরত পাঠাও", + + // "workflow-item.view.breadcrumbs": "Workflow View", + "workflow-item.view.breadcrumbs": "ওয়ার্কফ্লো ভিউ", + + + // "idle-modal.header": "Session will expire soon", + "idle-modal.header": "অধিবেশন শীঘ্রই মেয়াদ শেষ হবে", + + // "idle-modal.info": "For security reasons, user sessions expire after {{ timeToExpire }} minutes of inactivity. Your session will expire soon. Would you like to extend it or log out?", + "idle-modal.info": "নিরাপত্তার কারণে ব্যবহারকারী সেশন {{timeToExpire}}}} কয়েক মিনিটের পরে মেয়াদ শেষ হয়। আপনার অধিবেশন শীঘ্রই মেয়াদ শেষ হবে। আপনি এটি প্রসারিত বা লগ আউট করতে চান?", + + // "idle-modal.log-out": "Log out", + "idle-modal.log-out": "প্রস্থান", + + // "idle-modal.extend-session": "Extend session" + "idle-modal.extend-session": "সেশন প্রসারিত করুন" + + +} \ No newline at end of file diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index 1cbdca762e6..b6b75158d6c 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -178,7 +178,13 @@ export const environment: BuildConfig = { code: 'lv', label: 'Latviešu', active: true, - }], + } + // { + // code: 'bn', + // label: 'বাংলা', + // active: true, + // } + ], // Browse-By Pages browseBy: { From 716cea376da914d56f1f96a7aab3d7bc69a63f07 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Tue, 22 Mar 2022 13:29:23 +0100 Subject: [PATCH 0098/2129] fix circular dependency issues relating to request models --- .../epeople-registry.component.spec.ts | 2 +- .../eperson-form.component.spec.ts | 2 +- .../bitstream-formats.component.spec.ts | 2 +- .../bitstream-formats.component.ts | 2 +- .../metadata-registry.component.spec.ts | 2 +- .../metadata-schema.component.spec.ts | 2 +- .../browse-by-date-page.component.spec.ts | 2 +- .../browse-by-title-page.component.spec.ts | 2 +- .../community-list-datasource.ts | 2 +- .../community-list-service.spec.ts | 2 +- .../community-list-service.ts | 2 +- .../community-list.component.ts | 2 +- ...page-sub-collection-list.component.spec.ts | 2 +- ...-page-sub-community-list.component.spec.ts | 2 +- src/app/core/auth/auth-request.service.ts | 3 +- src/app/core/auth/authenticated.guard.ts | 2 +- .../auth/token-response-parsing.service.ts | 2 +- .../browse-definition-data.service.spec.ts | 2 +- .../browse/browse-definition-data.service.ts | 4 +- src/app/core/browse/browse.service.spec.ts | 2 +- .../core/cache/builders/link.service.spec.ts | 2 +- .../remote-data-build.service.spec.ts | 2 +- .../builders/remote-data-build.service.ts | 6 +-- .../core/cache/object-cache.service.spec.ts | 3 +- src/app/core/cache/object-cache.service.ts | 2 +- .../core/cache/server-sync-buffer.effects.ts | 2 +- src/app/core/config/config.service.spec.ts | 3 +- src/app/core/config/config.service.ts | 2 +- .../config/submission-forms-config.service.ts | 2 +- .../submission-uploads-config.service.ts | 2 +- src/app/core/core-state.model.ts | 30 ++++++++++++ src/app/core/core.module.ts | 3 +- src/app/core/core.reducers.ts | 38 +++++---------- src/app/core/core.selectors.ts | 2 +- .../base-response-parsing.service.spec.ts | 3 +- .../data/base-response-parsing.service.ts | 2 +- src/app/core/data/bitstream-data.service.ts | 5 +- .../bitstream-format-data.service.spec.ts | 4 +- .../data/bitstream-format-data.service.ts | 2 +- src/app/core/data/bundle-data.service.spec.ts | 2 +- src/app/core/data/bundle-data.service.ts | 5 +- src/app/core/data/collection-data.service.ts | 8 ++-- src/app/core/data/comcol-data.service.spec.ts | 4 +- src/app/core/data/comcol-data.service.ts | 2 +- src/app/core/data/community-data.service.ts | 4 +- .../core/data/configuration-data.service.ts | 2 +- ...content-source-response-parsing.service.ts | 2 +- src/app/core/data/data.service.spec.ts | 5 +- src/app/core/data/data.service.ts | 4 +- .../data/debug-response-parsing.service.ts | 2 +- .../data/dso-redirect-data.service.spec.ts | 2 +- .../core/data/dso-redirect-data.service.ts | 2 +- .../core/data/dso-response-parsing.service.ts | 2 +- .../core/data/dspace-object-data.service.ts | 4 +- .../dspace-rest-response-parsing.service.ts | 2 +- .../endpoint-map-response-parsing.service.ts | 2 +- src/app/core/data/entity-type.service.ts | 2 +- .../data/eperson-registration.service.spec.ts | 2 +- src/app/core/data/external-source.service.ts | 4 +- .../facet-config-response-parsing.service.ts | 2 +- .../facet-value-response-parsing.service.ts | 2 +- .../authorization-data.service.spec.ts | 2 +- .../authorization-data.service.ts | 4 +- .../feature-data.service.ts | 2 +- ...discovery-page-response-parsing.service.ts | 2 +- src/app/core/data/find-list-options.model.ts | 14 ++++++ .../core/data/href-only-data.service.spec.ts | 2 +- src/app/core/data/href-only-data.service.ts | 4 +- src/app/core/data/item-data.service.spec.ts | 7 +-- src/app/core/data/item-data.service.ts | 6 ++- .../data/item-template-data.service.spec.ts | 6 +-- .../core/data/item-template-data.service.ts | 2 +- .../data/metadata-field-data.service.spec.ts | 2 +- .../core/data/metadata-field-data.service.ts | 4 +- .../core/data/metadata-schema-data.service.ts | 2 +- .../data/mydspace-response-parsing.service.ts | 2 +- .../object-updates.service.spec.ts | 2 +- .../object-updates/object-updates.service.ts | 2 +- src/app/core/data/parsing.service.ts | 2 +- .../data/processes/process-data.service.ts | 2 +- .../data/processes/script-data.service.ts | 5 +- .../registration-response-parsing.service.ts | 2 +- .../core/data/relationship-type.service.ts | 2 +- .../core/data/relationship.service.spec.ts | 5 +- src/app/core/data/relationship.service.ts | 6 ++- src/app/core/data/request-entry.model.ts | 13 +++++ src/app/core/data/request-state.model.ts | 8 ++++ src/app/core/data/request.actions.ts | 2 +- src/app/core/data/request.effects.ts | 7 +-- src/app/core/data/request.models.ts | 48 ++++++------------- src/app/core/data/request.reducer.spec.ts | 3 +- src/app/core/data/request.reducer.ts | 24 +--------- src/app/core/data/request.service.spec.ts | 9 ++-- src/app/core/data/request.service.ts | 14 +++--- src/app/core/data/response-state.model.ts | 13 +++++ ...rest-request-with-response-parser.model.ts | 14 ++++++ src/app/core/data/rest-request.model.ts | 20 ++++++++ src/app/core/data/root-data.service.ts | 4 +- .../data/search-response-parsing.service.ts | 2 +- src/app/core/data/site-data.service.spec.ts | 4 +- src/app/core/data/site-data.service.ts | 2 +- ...atus-code-only-response-parsing.service.ts | 2 +- src/app/core/data/version-data.service.ts | 4 +- .../core/data/version-history-data.service.ts | 4 +- .../core/data/workflow-action-data.service.ts | 4 +- .../core/eperson/eperson-data.service.spec.ts | 5 +- src/app/core/eperson/eperson-data.service.ts | 3 +- .../core/eperson/group-data.service.spec.ts | 5 +- src/app/core/eperson/group-data.service.ts | 3 +- src/app/core/history/selectors.ts | 2 +- src/app/core/index/index.effects.ts | 2 +- src/app/core/index/index.selectors.ts | 2 +- .../builder/json-patch-operations-builder.ts | 2 +- .../json-patch-operations.service.spec.ts | 4 +- .../json-patch-operations.service.ts | 2 +- src/app/core/json-patch/selectors.ts | 2 +- src/app/core/metadata/metadata.service.ts | 2 +- .../pagination/pagination.service.spec.ts | 2 +- src/app/core/pagination/pagination.service.ts | 2 +- .../core/registry/registry.service.spec.ts | 2 +- src/app/core/registry/registry.service.ts | 2 +- .../resource-policy.service.spec.ts | 4 +- .../resource-policy.service.ts | 4 +- src/app/core/services/route.service.ts | 2 +- src/app/core/shared/operators.spec.ts | 2 +- src/app/core/shared/request.operators.ts | 5 +- .../search-configuration.service.spec.ts | 2 +- .../search/search-configuration.service.ts | 2 +- .../core/shared/search/search.service.spec.ts | 4 +- src/app/core/shared/search/search.service.ts | 5 +- .../statistics/usage-report-data.service.ts | 2 +- .../submission-cc-license-data.service.ts | 2 +- .../submission-cc-license-url-data.service.ts | 2 +- ...sion-json-patch-operations.service.spec.ts | 2 +- ...ubmission-json-patch-operations.service.ts | 2 +- .../submission-response-parsing.service.ts | 2 +- .../submission/submission-rest.service.ts | 2 +- .../models/vocabulary-find-options.model.ts | 2 +- .../vocabularies/vocabulary.service.spec.ts | 2 +- .../vocabularies/vocabulary.service.ts | 4 +- .../submission/workflowitem-data.service.ts | 2 +- .../submission/workspaceitem-data.service.ts | 2 +- .../tasks/claimed-task-data.service.spec.ts | 4 +- .../core/tasks/claimed-task-data.service.ts | 4 +- .../core/tasks/pool-task-data.service.spec.ts | 4 +- src/app/core/tasks/pool-task-data.service.ts | 4 +- .../tasks/task-response-parsing.service.ts | 2 +- src/app/core/tasks/tasks.service.spec.ts | 5 +- src/app/core/tasks/tasks.service.ts | 2 +- .../forgot-password-form.component.spec.ts | 2 +- .../forgot-password-form.component.ts | 2 +- ...top-level-community-list.component.spec.ts | 2 +- ...-and-drop-bitstream-list.component.spec.ts | 2 +- .../full-file-section.component.spec.ts | 2 +- .../related-items/related-items-component.ts | 2 +- .../collection-selector.component.spec.ts | 2 +- .../my-dspace-page.component.spec.ts | 2 +- .../process-overview.component.spec.ts | 2 +- .../overview/process-overview.component.ts | 2 +- .../create-profile.component.spec.ts | 2 +- .../create-profile.component.ts | 2 +- .../browse-by/browse-by.component.spec.ts | 2 +- .../collection-dropdown.component.spec.ts | 2 +- .../collection-dropdown.component.ts | 2 +- src/app/shared/log-in/log-in.component.ts | 2 +- .../password/log-in-password.component.ts | 2 +- .../shibboleth/log-in-shibboleth.component.ts | 2 +- .../mocks/remote-data-build.service.mock.ts | 2 +- src/app/shared/mocks/request.service.mock.ts | 2 +- .../item-detail-preview.component.spec.ts | 2 +- .../pagination/pagination.component.spec.ts | 2 +- src/app/shared/pagination/pagination.utils.ts | 2 +- .../eperson-group-list.component.spec.ts | 2 +- .../eperson-group-list.component.ts | 2 +- .../search-form/search-form.component.spec.ts | 2 +- .../search-facet-option.component.spec.ts | 2 +- ...earch-facet-range-option.component.spec.ts | 2 +- ...ch-facet-selected-option.component.spec.ts | 2 +- .../search-label.component.spec.ts | 2 +- .../date/starts-with-date.component.spec.ts | 2 +- .../text/starts-with-text.component.spec.ts | 2 +- .../shared/testing/pagination-service.stub.ts | 2 +- .../testing/submission-rest-service.stub.ts | 2 +- src/app/shared/testing/utils.test.ts | 2 +- .../shared/utils/follow-link-config.model.ts | 2 +- .../vocabulary-treeview.component.ts | 2 +- src/app/statistics/statistics.service.spec.ts | 8 ++-- src/app/statistics/statistics.service.ts | 2 +- ...mport-external-searchbar.component.spec.ts | 2 +- ...ion-import-external-searchbar.component.ts | 2 +- 190 files changed, 403 insertions(+), 322 deletions(-) create mode 100644 src/app/core/core-state.model.ts create mode 100644 src/app/core/data/find-list-options.model.ts create mode 100644 src/app/core/data/request-entry.model.ts create mode 100644 src/app/core/data/request-state.model.ts create mode 100644 src/app/core/data/response-state.model.ts create mode 100644 src/app/core/data/rest-request-with-response-parser.model.ts create mode 100644 src/app/core/data/rest-request.model.ts diff --git a/src/app/access-control/epeople-registry/epeople-registry.component.spec.ts b/src/app/access-control/epeople-registry/epeople-registry.component.spec.ts index bcf7e8f1d92..c0d70fd0b25 100644 --- a/src/app/access-control/epeople-registry/epeople-registry.component.spec.ts +++ b/src/app/access-control/epeople-registry/epeople-registry.component.spec.ts @@ -9,7 +9,6 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core'; import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model'; import { RemoteData } from '../../core/data/remote-data'; -import { FindListOptions } from '../../core/data/request.models'; import { EPersonDataService } from '../../core/eperson/eperson-data.service'; import { EPerson } from '../../core/eperson/models/eperson.model'; import { PageInfo } from '../../core/shared/page-info.model'; @@ -27,6 +26,7 @@ import { AuthorizationDataService } from '../../core/data/feature-authorization/ import { RequestService } from '../../core/data/request.service'; import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('EPeopleRegistryComponent', () => { let component: EPeopleRegistryComponent; diff --git a/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.spec.ts b/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.spec.ts index 832f4f6ce55..163f3d308a0 100644 --- a/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.spec.ts +++ b/src/app/access-control/epeople-registry/eperson-form/eperson-form.component.spec.ts @@ -8,7 +8,6 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { buildPaginatedList, PaginatedList } from '../../../core/data/paginated-list.model'; import { RemoteData } from '../../../core/data/remote-data'; -import { FindListOptions } from '../../../core/data/request.models'; import { EPersonDataService } from '../../../core/eperson/eperson-data.service'; import { EPerson } from '../../../core/eperson/models/eperson.model'; import { PageInfo } from '../../../core/shared/page-info.model'; @@ -28,6 +27,7 @@ import { createPaginatedList } from '../../../shared/testing/utils.test'; import { RequestService } from '../../../core/data/request.service'; import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; describe('EPersonFormComponent', () => { let component: EPersonFormComponent; diff --git a/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.spec.ts b/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.spec.ts index 8cfba1d37bd..7d3a726eec7 100644 --- a/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.spec.ts +++ b/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.spec.ts @@ -25,9 +25,9 @@ import { import { createPaginatedList } from '../../../shared/testing/utils.test'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; describe('BitstreamFormatsComponent', () => { let comp: BitstreamFormatsComponent; diff --git a/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.ts b/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.ts index cbbcbe07a4f..89d8ac29f3d 100644 --- a/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.ts +++ b/src/app/admin/admin-registries/bitstream-formats/bitstream-formats.component.ts @@ -5,7 +5,6 @@ import { PaginatedList } from '../../../core/data/paginated-list.model'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { BitstreamFormat } from '../../../core/shared/bitstream-format.model'; import { BitstreamFormatDataService } from '../../../core/data/bitstream-format-data.service'; -import { FindListOptions } from '../../../core/data/request.models'; import { map, switchMap, take } from 'rxjs/operators'; import { hasValue } from '../../../shared/empty.util'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; @@ -13,6 +12,7 @@ import { Router } from '@angular/router'; import { TranslateService } from '@ngx-translate/core'; import { NoContent } from '../../../core/shared/NoContent.model'; import { PaginationService } from '../../../core/pagination/pagination.service'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; /** * This component renders a list of bitstream formats diff --git a/src/app/admin/admin-registries/metadata-registry/metadata-registry.component.spec.ts b/src/app/admin/admin-registries/metadata-registry/metadata-registry.component.spec.ts index 0253725cb93..af92bbd1cef 100644 --- a/src/app/admin/admin-registries/metadata-registry/metadata-registry.component.spec.ts +++ b/src/app/admin/admin-registries/metadata-registry/metadata-registry.component.spec.ts @@ -21,8 +21,8 @@ import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.u import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; describe('MetadataRegistryComponent', () => { let comp: MetadataRegistryComponent; diff --git a/src/app/admin/admin-registries/metadata-schema/metadata-schema.component.spec.ts b/src/app/admin/admin-registries/metadata-schema/metadata-schema.component.spec.ts index 6eb3c5b1a44..8b2abe577c3 100644 --- a/src/app/admin/admin-registries/metadata-schema/metadata-schema.component.spec.ts +++ b/src/app/admin/admin-registries/metadata-schema/metadata-schema.component.spec.ts @@ -25,9 +25,9 @@ import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.u import { VarDirective } from '../../../shared/utils/var.directive'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; describe('MetadataSchemaComponent', () => { let comp: MetadataSchemaComponent; diff --git a/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.spec.ts b/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.spec.ts index 7b0ddcb18eb..15ec9d78db8 100644 --- a/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.spec.ts +++ b/src/app/browse-by/browse-by-date-page/browse-by-date-page.component.spec.ts @@ -20,9 +20,9 @@ import { VarDirective } from '../../shared/utils/var.directive'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../core/data/request.models'; import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('BrowseByDatePageComponent', () => { let comp: BrowseByDatePageComponent; diff --git a/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.spec.ts b/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.spec.ts index 584da1c45af..554b059ac5c 100644 --- a/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.spec.ts +++ b/src/app/browse-by/browse-by-title-page/browse-by-title-page.component.spec.ts @@ -20,9 +20,9 @@ import { VarDirective } from '../../shared/utils/var.directive'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../core/data/request.models'; import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('BrowseByTitlePageComponent', () => { let comp: BrowseByTitlePageComponent; diff --git a/src/app/community-list-page/community-list-datasource.ts b/src/app/community-list-page/community-list-datasource.ts index f234125373b..7f4d9be2b75 100644 --- a/src/app/community-list-page/community-list-datasource.ts +++ b/src/app/community-list-page/community-list-datasource.ts @@ -1,11 +1,11 @@ import { Subscription } from 'rxjs/internal/Subscription'; -import { FindListOptions } from '../core/data/request.models'; import { hasValue } from '../shared/empty.util'; import { CommunityListService} from './community-list-service'; import { CollectionViewer, DataSource } from '@angular/cdk/collections'; import { BehaviorSubject, Observable, } from 'rxjs'; import { finalize } from 'rxjs/operators'; import { FlatNode } from './flat-node.model'; +import { FindListOptions } from '../core/data/find-list-options.model'; /** * DataSource object needed by a CDK Tree to render its nodes. diff --git a/src/app/community-list-page/community-list-service.spec.ts b/src/app/community-list-page/community-list-service.spec.ts index f0e69128267..401ffe0b116 100644 --- a/src/app/community-list-page/community-list-service.spec.ts +++ b/src/app/community-list-page/community-list-service.spec.ts @@ -12,9 +12,9 @@ import { CollectionDataService } from '../core/data/collection-data.service'; import { CommunityDataService } from '../core/data/community-data.service'; import { Community } from '../core/shared/community.model'; import { Collection } from '../core/shared/collection.model'; -import { FindListOptions } from '../core/data/request.models'; import { PageInfo } from '../core/shared/page-info.model'; import { FlatNode } from './flat-node.model'; +import { FindListOptions } from '../core/data/find-list-options.model'; describe('CommunityListService', () => { let store: StoreMock; diff --git a/src/app/community-list-page/community-list-service.ts b/src/app/community-list-page/community-list-service.ts index b5b6ffa3f50..d09da8964b6 100644 --- a/src/app/community-list-page/community-list-service.ts +++ b/src/app/community-list-page/community-list-service.ts @@ -6,7 +6,6 @@ import { filter, map, switchMap } from 'rxjs/operators'; import { AppState } from '../app.reducer'; import { CommunityDataService } from '../core/data/community-data.service'; -import { FindListOptions } from '../core/data/request.models'; import { Community } from '../core/shared/community.model'; import { Collection } from '../core/shared/collection.model'; import { PageInfo } from '../core/shared/page-info.model'; @@ -22,6 +21,7 @@ import { getFirstCompletedRemoteData, getFirstSucceededRemoteData } from '../cor import { followLink } from '../shared/utils/follow-link-config.model'; import { FlatNode } from './flat-node.model'; import { ShowMoreFlatNode } from './show-more-flat-node.model'; +import { FindListOptions } from '../core/data/find-list-options.model'; // Helper method to combine an flatten an array of observables of flatNode arrays export const combineAndFlatten = (obsList: Observable[]): Observable => diff --git a/src/app/community-list-page/community-list/community-list.component.ts b/src/app/community-list-page/community-list/community-list.component.ts index d92c1c38602..556387da251 100644 --- a/src/app/community-list-page/community-list/community-list.component.ts +++ b/src/app/community-list-page/community-list/community-list.component.ts @@ -1,12 +1,12 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { take } from 'rxjs/operators'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../core/data/request.models'; import { CommunityListService} from '../community-list-service'; import { CommunityListDatasource } from '../community-list-datasource'; import { FlatTreeControl } from '@angular/cdk/tree'; import { isEmpty } from '../../shared/empty.util'; import { FlatNode } from '../flat-node.model'; +import { FindListOptions } from '../../core/data/find-list-options.model'; /** * A tree-structured list of nodes representing the communities, their subCommunities and collections. diff --git a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts index 93a6c6fbb1c..ec61fac6130 100644 --- a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts +++ b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts @@ -11,7 +11,6 @@ import { CommunityPageSubCollectionListComponent } from './community-page-sub-co import { Community } from '../../core/shared/community.model'; import { SharedModule } from '../../shared/shared.module'; import { CollectionDataService } from '../../core/data/collection-data.service'; -import { FindListOptions } from '../../core/data/request.models'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { buildPaginatedList } from '../../core/data/paginated-list.model'; import { PageInfo } from '../../core/shared/page-info.model'; @@ -25,6 +24,7 @@ import { PaginationService } from '../../core/pagination/pagination.service'; import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { ThemeService } from '../../shared/theme-support/theme.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('CommunityPageSubCollectionList Component', () => { let comp: CommunityPageSubCollectionListComponent; diff --git a/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts b/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts index e573259b63d..2bc829a3b05 100644 --- a/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts +++ b/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts @@ -13,7 +13,6 @@ import { buildPaginatedList } from '../../core/data/paginated-list.model'; import { PageInfo } from '../../core/shared/page-info.model'; import { SharedModule } from '../../shared/shared.module'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; -import { FindListOptions } from '../../core/data/request.models'; import { HostWindowService } from '../../shared/host-window.service'; import { HostWindowServiceStub } from '../../shared/testing/host-window-service.stub'; import { CommunityDataService } from '../../core/data/community-data.service'; @@ -25,6 +24,7 @@ import { PaginationService } from '../../core/pagination/pagination.service'; import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { ThemeService } from '../../shared/theme-support/theme.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('CommunityPageSubCommunityListComponent Component', () => { let comp: CommunityPageSubCommunityListComponent; diff --git a/src/app/core/auth/auth-request.service.ts b/src/app/core/auth/auth-request.service.ts index 00a94822d3b..da38d730a5f 100644 --- a/src/app/core/auth/auth-request.service.ts +++ b/src/app/core/auth/auth-request.service.ts @@ -3,7 +3,7 @@ import { distinctUntilChanged, filter, map, mergeMap, switchMap, tap } from 'rxj import { HALEndpointService } from '../shared/hal-endpoint.service'; import { RequestService } from '../data/request.service'; import { isNotEmpty } from '../../shared/empty.util'; -import { GetRequest, PostRequest, RestRequest, } from '../data/request.models'; +import { GetRequest, PostRequest, } from '../data/request.models'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { getFirstCompletedRemoteData } from '../shared/operators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; @@ -11,6 +11,7 @@ import { RemoteData } from '../data/remote-data'; import { AuthStatus } from './models/auth-status.model'; import { ShortLivedToken } from './models/short-lived-token.model'; import { URLCombiner } from '../url-combiner/url-combiner'; +import { RestRequest } from '../data/rest-request.model'; /** * Abstract service to send authentication requests diff --git a/src/app/core/auth/authenticated.guard.ts b/src/app/core/auth/authenticated.guard.ts index 0b9eeec5095..1ab1d2e0a51 100644 --- a/src/app/core/auth/authenticated.guard.ts +++ b/src/app/core/auth/authenticated.guard.ts @@ -11,9 +11,9 @@ import { Observable } from 'rxjs'; import { map, find, switchMap } from 'rxjs/operators'; import { select, Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { isAuthenticated, isAuthenticationLoading } from './selectors'; import { AuthService, LOGIN_ROUTE } from './auth.service'; +import { CoreState } from '../core-state.model'; /** * Prevent unauthorized activating and loading of routes diff --git a/src/app/core/auth/token-response-parsing.service.ts b/src/app/core/auth/token-response-parsing.service.ts index d39b3cc33db..1ba7a16b14e 100644 --- a/src/app/core/auth/token-response-parsing.service.ts +++ b/src/app/core/auth/token-response-parsing.service.ts @@ -1,9 +1,9 @@ import { ResponseParsingService } from '../data/parsing.service'; -import { RestRequest } from '../data/request.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { RestResponse, TokenResponse } from '../cache/response.models'; import { isNotEmpty } from '../../shared/empty.util'; import { Injectable } from '@angular/core'; +import { RestRequest } from '../data/rest-request.model'; @Injectable() /** diff --git a/src/app/core/browse/browse-definition-data.service.spec.ts b/src/app/core/browse/browse-definition-data.service.spec.ts index 1127748ca9c..92de3e1e293 100644 --- a/src/app/core/browse/browse-definition-data.service.spec.ts +++ b/src/app/core/browse/browse-definition-data.service.spec.ts @@ -1,7 +1,7 @@ import { BrowseDefinitionDataService } from './browse-definition-data.service'; -import { FindListOptions } from '../data/request.models'; import { followLink } from '../../shared/utils/follow-link-config.model'; import { EMPTY } from 'rxjs'; +import { FindListOptions } from '../data/find-list-options.model'; describe(`BrowseDefinitionDataService`, () => { let service: BrowseDefinitionDataService; diff --git a/src/app/core/browse/browse-definition-data.service.ts b/src/app/core/browse/browse-definition-data.service.ts index 31338417caf..1930947f761 100644 --- a/src/app/core/browse/browse-definition-data.service.ts +++ b/src/app/core/browse/browse-definition-data.service.ts @@ -6,7 +6,6 @@ import { BrowseDefinition } from '../shared/browse-definition.model'; import { RequestService } from '../data/request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -15,8 +14,9 @@ import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { Observable } from 'rxjs'; import { RemoteData } from '../data/remote-data'; -import { FindListOptions } from '../data/request.models'; import { PaginatedList } from '../data/paginated-list.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; /* tslint:disable:max-classes-per-file */ diff --git a/src/app/core/browse/browse.service.spec.ts b/src/app/core/browse/browse.service.spec.ts index a28add2e30a..634bdbff540 100644 --- a/src/app/core/browse/browse.service.spec.ts +++ b/src/app/core/browse/browse.service.spec.ts @@ -5,7 +5,6 @@ import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-bu import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; -import { RequestEntry } from '../data/request.reducer'; import { RequestService } from '../data/request.service'; import { BrowseDefinition } from '../shared/browse-definition.model'; import { BrowseEntrySearchOptions } from './browse-entry-search-options.model'; @@ -13,6 +12,7 @@ import { BrowseService } from './browse.service'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createPaginatedList, getFirstUsedArgumentOfSpyMethod } from '../../shared/testing/utils.test'; import { getMockHrefOnlyDataService } from '../../shared/mocks/href-only-data.service.mock'; +import { RequestEntry } from '../data/request-entry.model'; describe('BrowseService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/cache/builders/link.service.spec.ts b/src/app/core/cache/builders/link.service.spec.ts index f567c39314b..9ec3f9356bf 100644 --- a/src/app/core/cache/builders/link.service.spec.ts +++ b/src/app/core/cache/builders/link.service.spec.ts @@ -1,13 +1,13 @@ import { Injectable } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { followLink, FollowLinkConfig } from '../../../shared/utils/follow-link-config.model'; -import { FindListOptions } from '../../data/request.models'; import { HALLink } from '../../shared/hal-link.model'; import { HALResource } from '../../shared/hal-resource.model'; import { ResourceType } from '../../shared/resource-type'; import { LinkService } from './link.service'; import { DATA_SERVICE_FACTORY, LINK_DEFINITION_FACTORY, LINK_DEFINITION_MAP_FACTORY } from './build-decorators'; import { isEmpty } from 'rxjs/operators'; +import { FindListOptions } from '../../data/find-list-options.model'; const TEST_MODEL = new ResourceType('testmodel'); let result: any; diff --git a/src/app/core/cache/builders/remote-data-build.service.spec.ts b/src/app/core/cache/builders/remote-data-build.service.spec.ts index adda4617183..1d22da494f6 100644 --- a/src/app/core/cache/builders/remote-data-build.service.spec.ts +++ b/src/app/core/cache/builders/remote-data-build.service.spec.ts @@ -13,11 +13,11 @@ import { RequestService } from '../../data/request.service'; import { UnCacheableObject } from '../../shared/uncacheable-object.model'; import { RemoteData } from '../../data/remote-data'; import { Observable, of as observableOf } from 'rxjs'; -import { RequestEntry} from '../../data/request.reducer'; import { followLink, FollowLinkConfig } from '../../../shared/utils/follow-link-config.model'; import { take } from 'rxjs/operators'; import { HALLink } from '../../shared/hal-link.model'; import { RequestEntryState } from '../../data/request-entry-state.model'; +import { RequestEntry } from '../../data/request-entry.model'; describe('RemoteDataBuildService', () => { let service: RemoteDataBuildService; 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 1ae2ef961e3..016f6b16f6a 100644 --- a/src/app/core/cache/builders/remote-data-build.service.ts +++ b/src/app/core/cache/builders/remote-data-build.service.ts @@ -11,10 +11,6 @@ import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.u 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 -} from '../../data/request.reducer'; import { RequestService } from '../../data/request.service'; import { ObjectCacheService } from '../object-cache.service'; import { LinkService } from './link.service'; @@ -27,6 +23,8 @@ import { getUrlWithoutEmbedParams } from '../../index/index.selectors'; import { getResourceTypeValueFor } from '../object-cache.reducer'; import { hasSucceeded, RequestEntryState } from '../../data/request-entry-state.model'; import { getRequestFromRequestHref, getRequestFromRequestUUID } from '../../shared/request.operators'; +import { RequestEntry } from '../../data/request-entry.model'; +import { ResponseState } from '../../data/response-state.model'; @Injectable() export class RemoteDataBuildService { diff --git a/src/app/core/cache/object-cache.service.spec.ts b/src/app/core/cache/object-cache.service.spec.ts index e9cc7694a7a..bde6831967d 100644 --- a/src/app/core/cache/object-cache.service.spec.ts +++ b/src/app/core/cache/object-cache.service.spec.ts @@ -7,7 +7,7 @@ import { Operation } from 'fast-json-patch'; import { empty, of as observableOf } from 'rxjs'; import { first } from 'rxjs/operators'; -import { coreReducers, CoreState } from '../core.reducers'; +import { coreReducers} from '../core.reducers'; import { RestRequestMethod } from '../data/rest-request-method'; import { Item } from '../shared/item.model'; import { @@ -24,6 +24,7 @@ import { HALLink } from '../shared/hal-link.model'; import { storeModuleConfig } from '../../app.reducer'; import { TestColdObservable } from 'jasmine-marbles/src/test-observables'; import { IndexName } from '../index/index-name.model'; +import { CoreState } from '../core-state.model'; describe('ObjectCacheService', () => { let service: ObjectCacheService; diff --git a/src/app/core/cache/object-cache.service.ts b/src/app/core/cache/object-cache.service.ts index 8b9660a668b..6d48242178c 100644 --- a/src/app/core/cache/object-cache.service.ts +++ b/src/app/core/cache/object-cache.service.ts @@ -5,7 +5,7 @@ import { combineLatest as observableCombineLatest, Observable, of as observableO import { distinctUntilChanged, filter, map, mergeMap, switchMap, take } from 'rxjs/operators'; import { hasValue, isNotEmpty, isEmpty } from '../../shared/empty.util'; -import { CoreState } from '../core.reducers'; +import { CoreState } from '../core-state.model'; import { coreSelector } from '../core.selectors'; import { RestRequestMethod } from '../data/rest-request-method'; import { diff --git a/src/app/core/cache/server-sync-buffer.effects.ts b/src/app/core/cache/server-sync-buffer.effects.ts index d8ed88e12c1..10eedac3024 100644 --- a/src/app/core/cache/server-sync-buffer.effects.ts +++ b/src/app/core/cache/server-sync-buffer.effects.ts @@ -8,7 +8,6 @@ import { EmptySSBAction, ServerSyncBufferActionTypes } from './server-sync-buffer.actions'; -import { CoreState } from '../core.reducers'; import { Action, createSelector, MemoizedSelector, select, Store } from '@ngrx/store'; import { ServerSyncBufferEntry, ServerSyncBufferState } from './server-sync-buffer.reducer'; import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; @@ -22,6 +21,7 @@ import { environment } from '../../../environments/environment'; import { ObjectCacheEntry } from './object-cache.reducer'; import { Operation } from 'fast-json-patch'; import { NoOpAction } from '../../shared/ngrx/no-op.action'; +import { CoreState } from '../core-state.model'; @Injectable() export class ServerSyncBufferEffects { diff --git a/src/app/core/config/config.service.spec.ts b/src/app/core/config/config.service.spec.ts index 1eca35d2234..be354ddc6f9 100644 --- a/src/app/core/config/config.service.spec.ts +++ b/src/app/core/config/config.service.spec.ts @@ -3,11 +3,12 @@ import { TestScheduler } from 'rxjs/testing'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { ConfigService } from './config.service'; import { RequestService } from '../data/request.service'; -import { FindListOptions, GetRequest } from '../data/request.models'; +import { GetRequest } from '../data/request.models'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-build.service.mock'; +import { FindListOptions } from '../data/find-list-options.model'; const LINK_NAME = 'test'; const BROWSE = 'search/findByCollection'; diff --git a/src/app/core/config/config.service.ts b/src/app/core/config/config.service.ts index ddf909b5b0f..e52f9482f43 100644 --- a/src/app/core/config/config.service.ts +++ b/src/app/core/config/config.service.ts @@ -6,7 +6,6 @@ import { ConfigObject } from './models/config.model'; import { RemoteData } from '../data/remote-data'; import { DataService } from '../data/data.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; @@ -14,6 +13,7 @@ import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { getFirstCompletedRemoteData } from '../shared/operators'; import { map } from 'rxjs/operators'; +import { CoreState } from '../core-state.model'; class DataServiceImpl extends DataService { constructor( diff --git a/src/app/core/config/submission-forms-config.service.ts b/src/app/core/config/submission-forms-config.service.ts index a5c3f980605..1db5c2fa019 100644 --- a/src/app/core/config/submission-forms-config.service.ts +++ b/src/app/core/config/submission-forms-config.service.ts @@ -5,7 +5,6 @@ import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; @@ -17,6 +16,7 @@ import { SubmissionFormsModel } from './models/config-submission-forms.model'; import { RemoteData } from '../data/remote-data'; import { Observable } from 'rxjs'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { CoreState } from '../core-state.model'; @Injectable() @dataService(SUBMISSION_FORMS_TYPE) diff --git a/src/app/core/config/submission-uploads-config.service.ts b/src/app/core/config/submission-uploads-config.service.ts index a9e35a3183e..8ad17749bd3 100644 --- a/src/app/core/config/submission-uploads-config.service.ts +++ b/src/app/core/config/submission-uploads-config.service.ts @@ -7,7 +7,6 @@ import { dataService } from '../cache/builders/build-decorators'; import { SUBMISSION_UPLOADS_TYPE } from './models/config-type'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service'; @@ -16,6 +15,7 @@ import { SubmissionUploadsModel } from './models/config-submission-uploads.model import { RemoteData } from '../data/remote-data'; import { Observable } from 'rxjs'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { CoreState } from '../core-state.model'; /** * Provides methods to retrieve, from REST server, bitstream access conditions configurations applicable during the submission process. diff --git a/src/app/core/core-state.model.ts b/src/app/core/core-state.model.ts new file mode 100644 index 00000000000..b8211fdb555 --- /dev/null +++ b/src/app/core/core-state.model.ts @@ -0,0 +1,30 @@ +import { + BitstreamFormatRegistryState +} from '../admin/admin-registries/bitstream-formats/bitstream-format.reducers'; +import { ObjectCacheState } from './cache/object-cache.reducer'; +import { ServerSyncBufferState } from './cache/server-sync-buffer.reducer'; +import { ObjectUpdatesState } from './data/object-updates/object-updates.reducer'; +import { HistoryState } from './history/history.reducer'; +import { MetaIndexState } from './index/index.reducer'; +import { AuthState } from './auth/auth.reducer'; +import { JsonPatchOperationsState } from './json-patch/json-patch-operations.reducer'; +import { MetaTagState } from './metadata/meta-tag.reducer'; +import { RouteState } from './services/route.reducer'; +import { RequestState } from './data/request-state.model'; + +/** + * The core sub-state in the NgRx store + */ +export interface CoreState { + 'bitstreamFormats': BitstreamFormatRegistryState; + 'cache/object': ObjectCacheState; + 'cache/syncbuffer': ServerSyncBufferState; + 'cache/object-updates': ObjectUpdatesState; + 'data/request': RequestState; + 'history': HistoryState; + 'index': MetaIndexState; + 'auth': AuthState; + 'json/patch': JsonPatchOperationsState; + 'metaTag': MetaTagState; + 'route': RouteState; +} diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index 026c87be9d1..4ffc22355ca 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -42,7 +42,7 @@ import { SubmissionSectionModel } from './config/models/config-submission-sectio import { SubmissionUploadsModel } from './config/models/config-submission-uploads.model'; import { SubmissionFormsConfigService } from './config/submission-forms-config.service'; import { coreEffects } from './core.effects'; -import { coreReducers, CoreState } from './core.reducers'; +import { coreReducers} from './core.reducers'; import { BitstreamFormatDataService } from './data/bitstream-format-data.service'; import { CollectionDataService } from './data/collection-data.service'; import { CommunityDataService } from './data/community-data.service'; @@ -163,6 +163,7 @@ import { RootDataService } from './data/root-data.service'; import { Root } from './data/root.model'; import { SearchConfig } from './shared/search/search-filters/search-config.model'; import { SequenceService } from './shared/sequence.service'; +import { CoreState } from './core-state.model'; /** * When not in production, endpoint responses can be mocked for testing purposes diff --git a/src/app/core/core.reducers.ts b/src/app/core/core.reducers.ts index 8b3ec32b462..c0165c53848 100644 --- a/src/app/core/core.reducers.ts +++ b/src/app/core/core.reducers.ts @@ -1,33 +1,19 @@ import { ActionReducerMap, } from '@ngrx/store'; -import { objectCacheReducer, ObjectCacheState } from './cache/object-cache.reducer'; -import { indexReducer, MetaIndexState } from './index/index.reducer'; -import { requestReducer, RequestState } from './data/request.reducer'; -import { authReducer, AuthState } from './auth/auth.reducer'; -import { jsonPatchOperationsReducer, JsonPatchOperationsState } from './json-patch/json-patch-operations.reducer'; -import { serverSyncBufferReducer, ServerSyncBufferState } from './cache/server-sync-buffer.reducer'; -import { objectUpdatesReducer, ObjectUpdatesState } from './data/object-updates/object-updates.reducer'; -import { routeReducer, RouteState } from './services/route.reducer'; +import { objectCacheReducer } from './cache/object-cache.reducer'; +import { indexReducer } from './index/index.reducer'; +import { requestReducer } from './data/request.reducer'; +import { authReducer } from './auth/auth.reducer'; +import { jsonPatchOperationsReducer } from './json-patch/json-patch-operations.reducer'; +import { serverSyncBufferReducer } from './cache/server-sync-buffer.reducer'; +import { objectUpdatesReducer } from './data/object-updates/object-updates.reducer'; +import { routeReducer } from './services/route.reducer'; import { - bitstreamFormatReducer, - BitstreamFormatRegistryState + bitstreamFormatReducer } from '../admin/admin-registries/bitstream-formats/bitstream-format.reducers'; -import { historyReducer, HistoryState } from './history/history.reducer'; -import { metaTagReducer, MetaTagState } from './metadata/meta-tag.reducer'; - -export interface CoreState { - 'bitstreamFormats': BitstreamFormatRegistryState; - 'cache/object': ObjectCacheState; - 'cache/syncbuffer': ServerSyncBufferState; - 'cache/object-updates': ObjectUpdatesState; - 'data/request': RequestState; - 'history': HistoryState; - 'index': MetaIndexState; - 'auth': AuthState; - 'json/patch': JsonPatchOperationsState; - 'metaTag': MetaTagState; - 'route': RouteState; -} +import { historyReducer } from './history/history.reducer'; +import { metaTagReducer } from './metadata/meta-tag.reducer'; +import { CoreState } from './core-state.model'; export const coreReducers: ActionReducerMap = { 'bitstreamFormats': bitstreamFormatReducer, diff --git a/src/app/core/core.selectors.ts b/src/app/core/core.selectors.ts index 60365be7c26..77c7974de2c 100644 --- a/src/app/core/core.selectors.ts +++ b/src/app/core/core.selectors.ts @@ -1,5 +1,5 @@ import { createFeatureSelector } from '@ngrx/store'; -import { CoreState } from './core.reducers'; +import { CoreState } from './core-state.model'; /** * Base selector to select the core state from the store diff --git a/src/app/core/data/base-response-parsing.service.spec.ts b/src/app/core/data/base-response-parsing.service.spec.ts index c8a96838549..1ad584eab8d 100644 --- a/src/app/core/data/base-response-parsing.service.spec.ts +++ b/src/app/core/data/base-response-parsing.service.spec.ts @@ -1,8 +1,9 @@ import { BaseResponseParsingService } from './base-response-parsing.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { GetRequest, RestRequest } from './request.models'; +import { GetRequest} from './request.models'; import { DSpaceObject } from '../shared/dspace-object.model'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { RestRequest } from './rest-request.model'; /* tslint:disable:max-classes-per-file */ class TestService extends BaseResponseParsingService { diff --git a/src/app/core/data/base-response-parsing.service.ts b/src/app/core/data/base-response-parsing.service.ts index 61945c3161e..c8f416b894b 100644 --- a/src/app/core/data/base-response-parsing.service.ts +++ b/src/app/core/data/base-response-parsing.service.ts @@ -6,9 +6,9 @@ import { ObjectCacheService } from '../cache/object-cache.service'; import { GenericConstructor } from '../shared/generic-constructor'; import { PaginatedList, buildPaginatedList } from './paginated-list.model'; import { getClassForType } from '../cache/builders/build-decorators'; -import { RestRequest } from './request.models'; import { environment } from '../../../environments/environment'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { RestRequest } from './rest-request.model'; /* tslint:disable:max-classes-per-file */ diff --git a/src/app/core/data/bitstream-data.service.ts b/src/app/core/data/bitstream-data.service.ts index ca5e2761d8f..16f2cc16c26 100644 --- a/src/app/core/data/bitstream-data.service.ts +++ b/src/app/core/data/bitstream-data.service.ts @@ -9,7 +9,6 @@ import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { Bitstream } from '../shared/bitstream.model'; import { BITSTREAM } from '../shared/bitstream.resource-type'; import { Bundle } from '../shared/bundle.model'; @@ -20,7 +19,7 @@ import { DataService } from './data.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { buildPaginatedList, PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; -import { FindListOptions, PutRequest } from './request.models'; +import { PutRequest } from './request.models'; import { RequestService } from './request.service'; import { BitstreamFormatDataService } from './bitstream-format-data.service'; import { BitstreamFormat } from '../shared/bitstream-format.model'; @@ -29,6 +28,8 @@ import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.util import { PageInfo } from '../shared/page-info.model'; import { RequestParam } from '../cache/models/request-param.model'; import { sendRequest } from '../shared/request.operators'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * A service to retrieve {@link Bitstream}s from the REST API diff --git a/src/app/core/data/bitstream-format-data.service.spec.ts b/src/app/core/data/bitstream-format-data.service.spec.ts index c072803c83d..c1ebf90a471 100644 --- a/src/app/core/data/bitstream-format-data.service.spec.ts +++ b/src/app/core/data/bitstream-format-data.service.spec.ts @@ -1,5 +1,4 @@ import { BitstreamFormatDataService } from './bitstream-format-data.service'; -import { RequestEntry } from './request.reducer'; import { RestResponse } from '../cache/response.models'; import { Observable, of as observableOf } from 'rxjs'; import { Action, Store } from '@ngrx/store'; @@ -17,8 +16,9 @@ import { BitstreamFormatsRegistrySelectAction } from '../../admin/admin-registries/bitstream-formats/bitstream-format.actions'; import { TestScheduler } from 'rxjs/testing'; -import { CoreState } from '../core.reducers'; import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; +import { CoreState } from '../core-state.model'; +import { RequestEntry } from './request-entry.model'; describe('BitstreamFormatDataService', () => { let service: BitstreamFormatDataService; diff --git a/src/app/core/data/bitstream-format-data.service.ts b/src/app/core/data/bitstream-format-data.service.ts index 1f787f4bbcf..1af3db81035 100644 --- a/src/app/core/data/bitstream-format-data.service.ts +++ b/src/app/core/data/bitstream-format-data.service.ts @@ -13,7 +13,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { coreSelector } from '../core.selectors'; import { BitstreamFormat } from '../shared/bitstream-format.model'; import { BITSTREAM_FORMAT } from '../shared/bitstream-format.resource-type'; @@ -25,6 +24,7 @@ import { RemoteData } from './remote-data'; import { PostRequest, PutRequest } from './request.models'; import { RequestService } from './request.service'; import { sendRequest } from '../shared/request.operators'; +import { CoreState } from '../core-state.model'; const bitstreamFormatsStateSelector = createSelector( coreSelector, diff --git a/src/app/core/data/bundle-data.service.spec.ts b/src/app/core/data/bundle-data.service.spec.ts index ed149a624f2..12eec9e33d6 100644 --- a/src/app/core/data/bundle-data.service.spec.ts +++ b/src/app/core/data/bundle-data.service.spec.ts @@ -3,7 +3,6 @@ import { Store } from '@ngrx/store'; import { compare, Operation } from 'fast-json-patch'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; -import { CoreState } from '../core.reducers'; import { Item } from '../shared/item.model'; import { ChangeAnalyzer } from './change-analyzer'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; @@ -13,6 +12,7 @@ import { HALLink } from '../shared/hal-link.model'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createPaginatedList } from '../../shared/testing/utils.test'; import { Bundle } from '../shared/bundle.model'; +import { CoreState } from '../core-state.model'; class DummyChangeAnalyzer implements ChangeAnalyzer { diff(object1: Item, object2: Item): Operation[] { diff --git a/src/app/core/data/bundle-data.service.ts b/src/app/core/data/bundle-data.service.ts index 3aa4efda244..aedf5091930 100644 --- a/src/app/core/data/bundle-data.service.ts +++ b/src/app/core/data/bundle-data.service.ts @@ -9,7 +9,6 @@ import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { Bundle } from '../shared/bundle.model'; import { BUNDLE } from '../shared/bundle.resource-type'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -18,11 +17,13 @@ import { DataService } from './data.service'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; -import { FindListOptions, GetRequest } from './request.models'; +import { GetRequest } from './request.models'; import { RequestService } from './request.service'; import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model'; import { Bitstream } from '../shared/bitstream.model'; import { RequestEntryState } from './request-entry-state.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * A service to retrieve {@link Bundle}s from the REST API diff --git a/src/app/core/data/collection-data.service.ts b/src/app/core/data/collection-data.service.ts index e6255144b6a..c3a27f87a49 100644 --- a/src/app/core/data/collection-data.service.ts +++ b/src/app/core/data/collection-data.service.ts @@ -13,7 +13,6 @@ import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RequestParam } from '../cache/models/request-param.model'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { Collection } from '../shared/collection.model'; @@ -29,12 +28,13 @@ import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; import { ContentSourceRequest, - FindListOptions, - UpdateContentSourceRequest, - RestRequest + UpdateContentSourceRequest } from './request.models'; import { RequestService } from './request.service'; import { BitstreamDataService } from './bitstream-data.service'; +import { RestRequest } from './rest-request.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; @Injectable() @dataService(COLLECTION) diff --git a/src/app/core/data/comcol-data.service.spec.ts b/src/app/core/data/comcol-data.service.spec.ts index 35704878756..49c7d4620f1 100644 --- a/src/app/core/data/comcol-data.service.spec.ts +++ b/src/app/core/data/comcol-data.service.spec.ts @@ -7,13 +7,11 @@ import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { Community } from '../shared/community.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { ComColDataService } from './comcol-data.service'; import { CommunityDataService } from './community-data.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; -import { FindListOptions } from './request.models'; import { RequestService } from './request.service'; import { createFailedRemoteDataObject$, @@ -22,6 +20,8 @@ import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; import { BitstreamDataService } from './bitstream-data.service'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; const LINK_NAME = 'test'; diff --git a/src/app/core/data/comcol-data.service.ts b/src/app/core/data/comcol-data.service.ts index cf59c7ac745..01cd18df0cc 100644 --- a/src/app/core/data/comcol-data.service.ts +++ b/src/app/core/data/comcol-data.service.ts @@ -5,7 +5,6 @@ import { ObjectCacheService } from '../cache/object-cache.service'; import { Community } from '../shared/community.model'; import { HALLink } from '../shared/hal-link.model'; import { DataService } from './data.service'; -import { FindListOptions } from './request.models'; import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -17,6 +16,7 @@ import { NoContent } from '../shared/NoContent.model'; import { createFailedRemoteDataObject$ } from '../../shared/remote-data.utils'; import { URLCombiner } from '../url-combiner/url-combiner'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { FindListOptions } from './find-list-options.model'; export abstract class ComColDataService extends DataService { protected abstract objectCache: ObjectCacheService; diff --git a/src/app/core/data/community-data.service.ts b/src/app/core/data/community-data.service.ts index 82afe561a90..903d9bc79c4 100644 --- a/src/app/core/data/community-data.service.ts +++ b/src/app/core/data/community-data.service.ts @@ -8,7 +8,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { Community } from '../shared/community.model'; import { COMMUNITY } from '../shared/community.resource-type'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -16,11 +15,12 @@ import { ComColDataService } from './comcol-data.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; -import { FindListOptions } from './request.models'; import { RequestService } from './request.service'; import { BitstreamDataService } from './bitstream-data.service'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { isNotEmpty } from '../../shared/empty.util'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; @Injectable() @dataService(COMMUNITY) diff --git a/src/app/core/data/configuration-data.service.ts b/src/app/core/data/configuration-data.service.ts index 91d5af6ecc6..711eb6562f1 100644 --- a/src/app/core/data/configuration-data.service.ts +++ b/src/app/core/data/configuration-data.service.ts @@ -6,7 +6,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { DataService } from './data.service'; import { RemoteData } from './remote-data'; @@ -14,6 +13,7 @@ import { RequestService } from './request.service'; import { ConfigurationProperty } from '../shared/configuration-property.model'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { CONFIG_PROPERTY } from '../shared/config-property.resource-type'; +import { CoreState } from '../core-state.model'; /* tslint:disable:max-classes-per-file */ class DataServiceImpl extends DataService { diff --git a/src/app/core/data/content-source-response-parsing.service.ts b/src/app/core/data/content-source-response-parsing.service.ts index 42b8f85c421..066ccf28c9d 100644 --- a/src/app/core/data/content-source-response-parsing.service.ts +++ b/src/app/core/data/content-source-response-parsing.service.ts @@ -4,8 +4,8 @@ import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { ContentSource } from '../shared/content-source.model'; import { MetadataConfig } from '../shared/metadata-config.model'; -import { RestRequest } from './request.models'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; +import { RestRequest } from './rest-request.model'; @Injectable() /** diff --git a/src/app/core/data/data.service.spec.ts b/src/app/core/data/data.service.spec.ts index 56ef753a795..ee4810d79a1 100644 --- a/src/app/core/data/data.service.spec.ts +++ b/src/app/core/data/data.service.spec.ts @@ -7,14 +7,13 @@ import { followLink } from '../../shared/utils/follow-link-config.model'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { SortDirection, SortOptions } from '../cache/models/sort-options.model'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { DSpaceObject } from '../shared/dspace-object.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { Item } from '../shared/item.model'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { ChangeAnalyzer } from './change-analyzer'; import { DataService } from './data.service'; -import { FindListOptions, PatchRequest } from './request.models'; +import { PatchRequest } from './request.models'; import { RequestService } from './request.service'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; @@ -23,6 +22,8 @@ import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-bu import { TestScheduler } from 'rxjs/testing'; import { RemoteData } from './remote-data'; import { RequestEntryState } from './request-entry-state.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; const endpoint = 'https://rest.api/core'; diff --git a/src/app/core/data/data.service.ts b/src/app/core/data/data.service.ts index 12a66e50926..310ad704ecb 100644 --- a/src/app/core/data/data.service.ts +++ b/src/app/core/data/data.service.ts @@ -22,7 +22,6 @@ import { getClassForType } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RequestParam } from '../cache/models/request-param.model'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { DSpaceObject } from '../shared/dspace-object.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -34,7 +33,6 @@ import { RemoteData } from './remote-data'; import { CreateRequest, GetRequest, - FindListOptions, PatchRequest, PutRequest, DeleteRequest @@ -45,6 +43,8 @@ import { UpdateDataService } from './update-data.service'; import { GenericConstructor } from '../shared/generic-constructor'; import { NoContent } from '../shared/NoContent.model'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; export abstract class DataService implements UpdateDataService { protected abstract requestService: RequestService; diff --git a/src/app/core/data/debug-response-parsing.service.ts b/src/app/core/data/debug-response-parsing.service.ts index fbc07cbb395..992a29e4b84 100644 --- a/src/app/core/data/debug-response-parsing.service.ts +++ b/src/app/core/data/debug-response-parsing.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { RestResponse } from '../cache/response.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { ResponseParsingService } from './parsing.service'; -import { RestRequest } from './request.models'; +import { RestRequest } from './rest-request.model'; @Injectable() export class DebugResponseParsingService implements ResponseParsingService { diff --git a/src/app/core/data/dso-redirect-data.service.spec.ts b/src/app/core/data/dso-redirect-data.service.spec.ts index bcd25487c2e..3f3a799e457 100644 --- a/src/app/core/data/dso-redirect-data.service.spec.ts +++ b/src/app/core/data/dso-redirect-data.service.spec.ts @@ -6,13 +6,13 @@ import { NotificationsService } from '../../shared/notifications/notifications.s 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 { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { DsoRedirectDataService } from './dso-redirect-data.service'; import { GetRequest, IdentifierType } from './request.models'; import { RequestService } from './request.service'; import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; import { Item } from '../shared/item.model'; +import { CoreState } from '../core-state.model'; describe('DsoRedirectDataService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/data/dso-redirect-data.service.ts b/src/app/core/data/dso-redirect-data.service.ts index 83395d47193..6270689f035 100644 --- a/src/app/core/data/dso-redirect-data.service.ts +++ b/src/app/core/data/dso-redirect-data.service.ts @@ -9,7 +9,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { DataService } from './data.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; @@ -20,6 +19,7 @@ import { getFirstCompletedRemoteData } from '../shared/operators'; import { DSpaceObject } from '../shared/dspace-object.model'; import { Item } from '../shared/item.model'; import { getItemPageRoute } from '../../item-page/item-page-routing-paths'; +import { CoreState } from '../core-state.model'; @Injectable() export class DsoRedirectDataService extends DataService { diff --git a/src/app/core/data/dso-response-parsing.service.ts b/src/app/core/data/dso-response-parsing.service.ts index 7dde1f53a17..fd5a22fae96 100644 --- a/src/app/core/data/dso-response-parsing.service.ts +++ b/src/app/core/data/dso-response-parsing.service.ts @@ -3,12 +3,12 @@ import { Injectable } from '@angular/core'; import { ObjectCacheService } from '../cache/object-cache.service'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { RestResponse, DSOSuccessResponse } from '../cache/response.models'; -import { RestRequest } from './request.models'; import { ResponseParsingService } from './parsing.service'; import { BaseResponseParsingService } from './base-response-parsing.service'; import { hasNoValue, hasValue } from '../../shared/empty.util'; import { DSpaceObject } from '../shared/dspace-object.model'; +import { RestRequest } from './rest-request.model'; @Injectable() export class DSOResponseParsingService extends BaseResponseParsingService implements ResponseParsingService { diff --git a/src/app/core/data/dspace-object-data.service.ts b/src/app/core/data/dspace-object-data.service.ts index eb230e2f543..f78debf9cd2 100644 --- a/src/app/core/data/dspace-object-data.service.ts +++ b/src/app/core/data/dspace-object-data.service.ts @@ -7,7 +7,6 @@ import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { DSpaceObject } from '../shared/dspace-object.model'; import { DSPACE_OBJECT } from '../shared/dspace-object.resource-type'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -15,8 +14,9 @@ import { DataService } from './data.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { RemoteData } from './remote-data'; import { RequestService } from './request.service'; -import { FindListOptions } from './request.models'; import { PaginatedList } from './paginated-list.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /* tslint:disable:max-classes-per-file */ class DataServiceImpl extends DataService { diff --git a/src/app/core/data/dspace-rest-response-parsing.service.ts b/src/app/core/data/dspace-rest-response-parsing.service.ts index 27af802ce81..22506b7d7d7 100644 --- a/src/app/core/data/dspace-rest-response-parsing.service.ts +++ b/src/app/core/data/dspace-rest-response-parsing.service.ts @@ -6,7 +6,6 @@ import { ObjectCacheService } from '../cache/object-cache.service'; import { GenericConstructor } from '../shared/generic-constructor'; import { PaginatedList, buildPaginatedList } from './paginated-list.model'; import { getClassForType } from '../cache/builders/build-decorators'; -import { RestRequest } from './request.models'; import { environment } from '../../../environments/environment'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { DSpaceObject } from '../shared/dspace-object.model'; @@ -17,6 +16,7 @@ import { RestRequestMethod } from './rest-request-method'; import { getUrlWithoutEmbedParams, getEmbedSizeParams } from '../index/index.selectors'; import { URLCombiner } from '../url-combiner/url-combiner'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { RestRequest } from './rest-request.model'; /* tslint:disable:max-classes-per-file */ diff --git a/src/app/core/data/endpoint-map-response-parsing.service.ts b/src/app/core/data/endpoint-map-response-parsing.service.ts index 73396e78bbe..728714876c4 100644 --- a/src/app/core/data/endpoint-map-response-parsing.service.ts +++ b/src/app/core/data/endpoint-map-response-parsing.service.ts @@ -7,12 +7,12 @@ import { import { hasValue } from '../../shared/empty.util'; import { getClassForType } from '../cache/builders/build-decorators'; import { GenericConstructor } from '../shared/generic-constructor'; -import { RestRequest } from './request.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { ParsedResponse } from '../cache/response.models'; import { DSpaceObject } from '../shared/dspace-object.model'; import { environment } from '../../../environments/environment'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { RestRequest } from './rest-request.model'; /** * ResponseParsingService able to deal with HAL Endpoints that are only needed as steps diff --git a/src/app/core/data/entity-type.service.ts b/src/app/core/data/entity-type.service.ts index ca9ea15bc6c..cedad93a140 100644 --- a/src/app/core/data/entity-type.service.ts +++ b/src/app/core/data/entity-type.service.ts @@ -3,7 +3,6 @@ import { DataService } from './data.service'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { ObjectCacheService } from '../cache/object-cache.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -18,6 +17,7 @@ import { PaginatedList } from './paginated-list.model'; import { ItemType } from '../shared/item-relationships/item-type.model'; import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../shared/operators'; import { RelationshipTypeService } from './relationship-type.service'; +import { CoreState } from '../core-state.model'; /** * Service handling all ItemType requests diff --git a/src/app/core/data/eperson-registration.service.spec.ts b/src/app/core/data/eperson-registration.service.spec.ts index 768d83c0246..6f73813bd45 100644 --- a/src/app/core/data/eperson-registration.service.spec.ts +++ b/src/app/core/data/eperson-registration.service.spec.ts @@ -1,7 +1,6 @@ import { RequestService } from './request.service'; import { EpersonRegistrationService } from './eperson-registration.service'; import { RestResponse } from '../cache/response.models'; -import { RequestEntry } from './request.reducer'; import { cold } from 'jasmine-marbles'; import { PostRequest } from './request.models'; import { Registration } from '../shared/registration.model'; @@ -9,6 +8,7 @@ import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-servic import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; import { of as observableOf } from 'rxjs/internal/observable/of'; import { TestScheduler } from 'rxjs/testing'; +import { RequestEntry } from './request-entry.model'; describe('EpersonRegistrationService', () => { let testScheduler; diff --git a/src/app/core/data/external-source.service.ts b/src/app/core/data/external-source.service.ts index a3a0a532ec6..9c6f75e6b89 100644 --- a/src/app/core/data/external-source.service.ts +++ b/src/app/core/data/external-source.service.ts @@ -4,12 +4,10 @@ import { ExternalSource } from '../shared/external-source.model'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; -import { FindListOptions } from './request.models'; import { Observable } from 'rxjs'; import { distinctUntilChanged, map, switchMap, take } from 'rxjs/operators'; import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model'; @@ -19,6 +17,8 @@ import { PaginatedList } from './paginated-list.model'; import { ExternalSourceEntry } from '../shared/external-source-entry.model'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * A service handling all external source requests diff --git a/src/app/core/data/facet-config-response-parsing.service.ts b/src/app/core/data/facet-config-response-parsing.service.ts index fc543c9072f..1fb3848f2da 100644 --- a/src/app/core/data/facet-config-response-parsing.service.ts +++ b/src/app/core/data/facet-config-response-parsing.service.ts @@ -3,9 +3,9 @@ import { SearchFilterConfig } from '../../shared/search/search-filter-config.mod import { ParsedResponse } from '../cache/response.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; -import { RestRequest } from './request.models'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; import { FacetConfigResponse } from '../../shared/search/facet-config-response.model'; +import { RestRequest } from './rest-request.model'; @Injectable() export class FacetConfigResponseParsingService extends DspaceRestResponseParsingService { diff --git a/src/app/core/data/facet-value-response-parsing.service.ts b/src/app/core/data/facet-value-response-parsing.service.ts index 6b9e8326850..8053e97cf6c 100644 --- a/src/app/core/data/facet-value-response-parsing.service.ts +++ b/src/app/core/data/facet-value-response-parsing.service.ts @@ -3,9 +3,9 @@ import { FacetValue } from '../../shared/search/facet-value.model'; import { ParsedResponse } from '../cache/response.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; -import { RestRequest } from './request.models'; import { FacetValues } from '../../shared/search/facet-values.model'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; +import { RestRequest } from './rest-request.model'; @Injectable() export class FacetValueResponseParsingService extends DspaceRestResponseParsingService { diff --git a/src/app/core/data/feature-authorization/authorization-data.service.spec.ts b/src/app/core/data/feature-authorization/authorization-data.service.spec.ts index 01bd23d7c7c..df46d3f0a18 100644 --- a/src/app/core/data/feature-authorization/authorization-data.service.spec.ts +++ b/src/app/core/data/feature-authorization/authorization-data.service.spec.ts @@ -4,7 +4,6 @@ import { AuthService } from '../../auth/auth.service'; import { Site } from '../../shared/site.model'; import { EPerson } from '../../eperson/models/eperson.model'; import { of as observableOf } from 'rxjs'; -import { FindListOptions } from '../request.models'; import { FeatureID } from './feature-id'; import { hasValue } from '../../../shared/empty.util'; import { RequestParam } from '../../cache/models/request-param.model'; @@ -12,6 +11,7 @@ import { Authorization } from '../../shared/authorization.model'; import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { createPaginatedList } from '../../../shared/testing/utils.test'; import { Feature } from '../../shared/feature.model'; +import { FindListOptions } from '../find-list-options.model'; describe('AuthorizationDataService', () => { let service: AuthorizationDataService; diff --git a/src/app/core/data/feature-authorization/authorization-data.service.ts b/src/app/core/data/feature-authorization/authorization-data.service.ts index b9812cdbb31..1f8c8b2284d 100644 --- a/src/app/core/data/feature-authorization/authorization-data.service.ts +++ b/src/app/core/data/feature-authorization/authorization-data.service.ts @@ -7,7 +7,6 @@ import { Authorization } from '../../shared/authorization.model'; import { RequestService } from '../request.service'; import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { ObjectCacheService } from '../../cache/object-cache.service'; import { HALEndpointService } from '../../shared/hal-endpoint.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; @@ -15,7 +14,6 @@ import { HttpClient } from '@angular/common/http'; import { DSOChangeAnalyzer } from '../dso-change-analyzer.service'; import { AuthService } from '../../auth/auth.service'; import { SiteDataService } from '../site-data.service'; -import { FindListOptions } from '../request.models'; import { followLink, FollowLinkConfig } from '../../../shared/utils/follow-link-config.model'; import { RemoteData } from '../remote-data'; import { PaginatedList } from '../paginated-list.model'; @@ -26,6 +24,8 @@ import { AuthorizationSearchParams } from './authorization-search-params'; import { addSiteObjectUrlIfEmpty, oneAuthorizationMatchesFeature } from './authorization-utils'; import { FeatureID } from './feature-id'; import { getFirstCompletedRemoteData } from '../../shared/operators'; +import { CoreState } from '../../core-state.model'; +import { FindListOptions } from '../find-list-options.model'; /** * A service to retrieve {@link Authorization}s from the REST API diff --git a/src/app/core/data/feature-authorization/feature-data.service.ts b/src/app/core/data/feature-authorization/feature-data.service.ts index 12be6f84524..cbe83566607 100644 --- a/src/app/core/data/feature-authorization/feature-data.service.ts +++ b/src/app/core/data/feature-authorization/feature-data.service.ts @@ -6,12 +6,12 @@ import { Feature } from '../../shared/feature.model'; import { RequestService } from '../request.service'; import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { ObjectCacheService } from '../../cache/object-cache.service'; import { HALEndpointService } from '../../shared/hal-endpoint.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { DSOChangeAnalyzer } from '../dso-change-analyzer.service'; +import { CoreState } from '../../core-state.model'; /** * A service to retrieve {@link Feature}s from the REST API diff --git a/src/app/core/data/filtered-discovery-page-response-parsing.service.ts b/src/app/core/data/filtered-discovery-page-response-parsing.service.ts index 7a2ff7962d5..4f28a16318d 100644 --- a/src/app/core/data/filtered-discovery-page-response-parsing.service.ts +++ b/src/app/core/data/filtered-discovery-page-response-parsing.service.ts @@ -1,10 +1,10 @@ import { Injectable } from '@angular/core'; import { ResponseParsingService } from './parsing.service'; -import { RestRequest } from './request.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { BaseResponseParsingService } from './base-response-parsing.service'; import { ObjectCacheService } from '../cache/object-cache.service'; import { FilteredDiscoveryQueryResponse, RestResponse } from '../cache/response.models'; +import { RestRequest } from './rest-request.model'; /** * A ResponseParsingService used to parse RawRestResponse coming from the REST API to a discovery query (string) diff --git a/src/app/core/data/find-list-options.model.ts b/src/app/core/data/find-list-options.model.ts new file mode 100644 index 00000000000..52a527d9e07 --- /dev/null +++ b/src/app/core/data/find-list-options.model.ts @@ -0,0 +1,14 @@ +import { SortOptions } from '../cache/models/sort-options.model'; +import { RequestParam } from '../cache/models/request-param.model'; + +/** + * The options for a find list request + */ +export class FindListOptions { + scopeID?: string; + elementsPerPage?: number; + currentPage?: number; + sort?: SortOptions; + searchParams?: RequestParam[]; + startsWith?: string; +} diff --git a/src/app/core/data/href-only-data.service.spec.ts b/src/app/core/data/href-only-data.service.spec.ts index dd4be832038..64c451837d5 100644 --- a/src/app/core/data/href-only-data.service.spec.ts +++ b/src/app/core/data/href-only-data.service.spec.ts @@ -1,8 +1,8 @@ import { HrefOnlyDataService } from './href-only-data.service'; import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; -import { FindListOptions } from './request.models'; import { DataService } from './data.service'; +import { FindListOptions } from './find-list-options.model'; describe(`HrefOnlyDataService`, () => { let service: HrefOnlyDataService; diff --git a/src/app/core/data/href-only-data.service.ts b/src/app/core/data/href-only-data.service.ts index 4baffea5453..d5656e0eb62 100644 --- a/src/app/core/data/href-only-data.service.ts +++ b/src/app/core/data/href-only-data.service.ts @@ -2,7 +2,6 @@ import { DataService } from './data.service'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -10,7 +9,6 @@ import { HttpClient } from '@angular/common/http'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { Injectable } from '@angular/core'; import { VOCABULARY_ENTRY } from '../submission/vocabularies/models/vocabularies.resource-type'; -import { FindListOptions } from './request.models'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteData } from './remote-data'; @@ -19,6 +17,8 @@ import { PaginatedList } from './paginated-list.model'; import { ITEM_TYPE } from '../shared/item-relationships/item-type.resource-type'; import { LICENSE } from '../shared/license.resource-type'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /* tslint:disable:max-classes-per-file */ class DataServiceImpl extends DataService { diff --git a/src/app/core/data/item-data.service.spec.ts b/src/app/core/data/item-data.service.spec.ts index 30a132aeaeb..846d0e72eb0 100644 --- a/src/app/core/data/item-data.service.spec.ts +++ b/src/app/core/data/item-data.service.spec.ts @@ -8,13 +8,14 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { BrowseService } from '../browse/browse.service'; import { ObjectCacheService } from '../cache/object-cache.service'; import { RestResponse } from '../cache/response.models'; -import { CoreState } from '../core.reducers'; import { ExternalSourceEntry } from '../shared/external-source-entry.model'; import { ItemDataService } from './item-data.service'; -import { DeleteRequest, FindListOptions, PostRequest } from './request.models'; -import { RequestEntry } from './request.reducer'; +import { DeleteRequest, PostRequest } from './request.models'; import { RequestService } from './request.service'; import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-build.service.mock'; +import { CoreState } from '../core-state.model'; +import { RequestEntry } from './request-entry.model'; +import { FindListOptions } from './find-list-options.model'; describe('ItemDataService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/data/item-data.service.ts b/src/app/core/data/item-data.service.ts index 1c152701a10..db7c982303d 100644 --- a/src/app/core/data/item-data.service.ts +++ b/src/app/core/data/item-data.service.ts @@ -9,7 +9,6 @@ import { BrowseService } from '../browse/browse.service'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { Collection } from '../shared/collection.model'; import { ExternalSourceEntry } from '../shared/external-source-entry.model'; @@ -22,7 +21,7 @@ import { DataService } from './data.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; -import { DeleteRequest, FindListOptions, GetRequest, PostRequest, PutRequest, RestRequest } from './request.models'; +import { DeleteRequest, GetRequest, PostRequest, PutRequest} from './request.models'; import { RequestService } from './request.service'; import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model'; import { Bundle } from '../shared/bundle.model'; @@ -34,6 +33,9 @@ import { GenericConstructor } from '../shared/generic-constructor'; import { ResponseParsingService } from './parsing.service'; import { StatusCodeOnlyResponseParsingService } from './status-code-only-response-parsing.service'; import { sendRequest } from '../shared/request.operators'; +import { RestRequest } from './rest-request.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; @Injectable() @dataService(ITEM) diff --git a/src/app/core/data/item-template-data.service.spec.ts b/src/app/core/data/item-template-data.service.spec.ts index 14585275065..4b8aa362baa 100644 --- a/src/app/core/data/item-template-data.service.spec.ts +++ b/src/app/core/data/item-template-data.service.spec.ts @@ -1,12 +1,9 @@ import { ItemTemplateDataService } from './item-template-data.service'; -import { RestRequest } from './request.models'; -import { RequestEntry } from './request.reducer'; import { RestResponse } from '../cache/response.models'; import { RequestService } from './request.service'; import { Observable, of as observableOf } from 'rxjs'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { BrowseService } from '../browse/browse.service'; import { cold } from 'jasmine-marbles'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -15,6 +12,9 @@ import { HttpClient } from '@angular/common/http'; import { CollectionDataService } from './collection-data.service'; import { RestRequestMethod } from './rest-request-method'; import { Item } from '../shared/item.model'; +import { RestRequest } from './rest-request.model'; +import { CoreState } from '../core-state.model'; +import { RequestEntry } from './request-entry.model'; describe('ItemTemplateDataService', () => { let service: ItemTemplateDataService; diff --git a/src/app/core/data/item-template-data.service.ts b/src/app/core/data/item-template-data.service.ts index 19e6941385c..c391ce1a72d 100644 --- a/src/app/core/data/item-template-data.service.ts +++ b/src/app/core/data/item-template-data.service.ts @@ -9,7 +9,6 @@ import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -23,6 +22,7 @@ import { NoContent } from '../shared/NoContent.model'; import { hasValue } from '../../shared/empty.util'; import { Operation } from 'fast-json-patch'; import { getFirstCompletedRemoteData } from '../shared/operators'; +import { CoreState } from '../core-state.model'; /* tslint:disable:max-classes-per-file */ /** diff --git a/src/app/core/data/metadata-field-data.service.spec.ts b/src/app/core/data/metadata-field-data.service.spec.ts index bb621f74b3a..54a174e365a 100644 --- a/src/app/core/data/metadata-field-data.service.spec.ts +++ b/src/app/core/data/metadata-field-data.service.spec.ts @@ -4,12 +4,12 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { of as observableOf } from 'rxjs'; import { RestResponse } from '../cache/response.models'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; -import { FindListOptions } from './request.models'; import { MetadataFieldDataService } from './metadata-field-data.service'; import { MetadataSchema } from '../metadata/metadata-schema.model'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { RequestParam } from '../cache/models/request-param.model'; +import { FindListOptions } from './find-list-options.model'; describe('MetadataFieldDataService', () => { let metadataFieldService: MetadataFieldDataService; diff --git a/src/app/core/data/metadata-field-data.service.ts b/src/app/core/data/metadata-field-data.service.ts index 3b11859361e..5a78213c847 100644 --- a/src/app/core/data/metadata-field-data.service.ts +++ b/src/app/core/data/metadata-field-data.service.ts @@ -7,7 +7,6 @@ import { RemoteData } from './remote-data'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { ObjectCacheService } from '../cache/object-cache.service'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; @@ -16,11 +15,12 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { METADATA_FIELD } from '../metadata/metadata-field.resource-type'; import { MetadataField } from '../metadata/metadata-field.model'; import { MetadataSchema } from '../metadata/metadata-schema.model'; -import { FindListOptions } from './request.models'; 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 { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * A service responsible for fetching/sending data from/to the REST API on the metadatafields endpoint diff --git a/src/app/core/data/metadata-schema-data.service.ts b/src/app/core/data/metadata-schema-data.service.ts index ff1796313e4..f277f6cab6c 100644 --- a/src/app/core/data/metadata-schema-data.service.ts +++ b/src/app/core/data/metadata-schema-data.service.ts @@ -5,7 +5,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { MetadataSchema } from '../metadata/metadata-schema.model'; import { METADATA_SCHEMA } from '../metadata/metadata-schema.resource-type'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -16,6 +15,7 @@ import { Observable } from 'rxjs'; import { hasValue } from '../../shared/empty.util'; import { tap } from 'rxjs/operators'; import { RemoteData } from './remote-data'; +import { CoreState } from '../core-state.model'; /** * A service responsible for fetching/sending data from/to the REST API on the metadataschemas endpoint diff --git a/src/app/core/data/mydspace-response-parsing.service.ts b/src/app/core/data/mydspace-response-parsing.service.ts index f71eaeb811b..edb9e3c80fd 100644 --- a/src/app/core/data/mydspace-response-parsing.service.ts +++ b/src/app/core/data/mydspace-response-parsing.service.ts @@ -1,12 +1,12 @@ import { Injectable } from '@angular/core'; import { ParsedResponse } from '../cache/response.models'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; -import { RestRequest } from './request.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { hasValue } from '../../shared/empty.util'; import { SearchObjects } from '../../shared/search/search-objects.model'; import { MetadataMap, MetadataValue } from '../shared/metadata.models'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; +import { RestRequest } from './rest-request.model'; @Injectable() export class MyDSpaceResponseParsingService extends DspaceRestResponseParsingService { diff --git a/src/app/core/data/object-updates/object-updates.service.spec.ts b/src/app/core/data/object-updates/object-updates.service.spec.ts index b0c63851e3b..9cf856f03a0 100644 --- a/src/app/core/data/object-updates/object-updates.service.spec.ts +++ b/src/app/core/data/object-updates/object-updates.service.spec.ts @@ -1,5 +1,4 @@ import { Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { ObjectUpdatesService } from './object-updates.service'; import { DiscardObjectUpdatesAction, @@ -16,6 +15,7 @@ import { OBJECT_UPDATES_TRASH_PATH } from './object-updates.reducer'; import { Relationship } from '../../shared/item-relationships/relationship.model'; import { Injector } from '@angular/core'; import { FieldChangeType } from './field-change-type.model'; +import { CoreState } from '../../core-state.model'; describe('ObjectUpdatesService', () => { let service: ObjectUpdatesService; diff --git a/src/app/core/data/object-updates/object-updates.service.ts b/src/app/core/data/object-updates/object-updates.service.ts index 0bdae06ce26..2fb6d47d31c 100644 --- a/src/app/core/data/object-updates/object-updates.service.ts +++ b/src/app/core/data/object-updates/object-updates.service.ts @@ -1,6 +1,5 @@ import { Injectable, Injector } from '@angular/core'; import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { coreSelector } from '../../core.selectors'; import { FieldState, @@ -35,6 +34,7 @@ import { GenericConstructor } from '../../shared/generic-constructor'; import { Identifiable } from './identifiable.model'; import { FieldUpdates } from './field-updates.model'; import { FieldChangeType } from './field-change-type.model'; +import { CoreState } from '../../core-state.model'; function objectUpdatesStateSelector(): MemoizedSelector { return createSelector(coreSelector, (state: CoreState) => state['cache/object-updates']); diff --git a/src/app/core/data/parsing.service.ts b/src/app/core/data/parsing.service.ts index bebbd63fd79..fbebe75b2b5 100644 --- a/src/app/core/data/parsing.service.ts +++ b/src/app/core/data/parsing.service.ts @@ -1,6 +1,6 @@ import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; -import { RestRequest } from './request.models'; import { ParsedResponse } from '../cache/response.models'; +import { RestRequest } from './rest-request.model'; export interface ResponseParsingService { parse(request: RestRequest, data: RawRestResponse): ParsedResponse; diff --git a/src/app/core/data/processes/process-data.service.ts b/src/app/core/data/processes/process-data.service.ts index cadcdb3bfe4..81b4cbd5035 100644 --- a/src/app/core/data/processes/process-data.service.ts +++ b/src/app/core/data/processes/process-data.service.ts @@ -3,7 +3,6 @@ import { DataService } from '../data.service'; import { RequestService } from '../request.service'; import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { ObjectCacheService } from '../../cache/object-cache.service'; import { HALEndpointService } from '../../shared/hal-endpoint.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; @@ -18,6 +17,7 @@ import { PaginatedList } from '../paginated-list.model'; import { Bitstream } from '../../shared/bitstream.model'; import { RemoteData } from '../remote-data'; import { BitstreamDataService } from '../bitstream-data.service'; +import { CoreState } from '../../core-state.model'; @Injectable() @dataService(PROCESS) diff --git a/src/app/core/data/processes/script-data.service.ts b/src/app/core/data/processes/script-data.service.ts index 69b42701734..bf51fadea1b 100644 --- a/src/app/core/data/processes/script-data.service.ts +++ b/src/app/core/data/processes/script-data.service.ts @@ -2,7 +2,6 @@ import { Injectable } from '@angular/core'; import { DataService } from '../data.service'; import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { ObjectCacheService } from '../../cache/object-cache.service'; import { HALEndpointService } from '../../shared/hal-endpoint.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; @@ -13,12 +12,14 @@ import { ProcessParameter } from '../../../process-page/processes/process-parame import { map, take } from 'rxjs/operators'; import { URLCombiner } from '../../url-combiner/url-combiner'; import { RemoteData } from '../remote-data'; -import { MultipartPostRequest, RestRequest } from '../request.models'; +import { MultipartPostRequest} from '../request.models'; import { RequestService } from '../request.service'; import { Observable } from 'rxjs'; import { dataService } from '../../cache/builders/build-decorators'; import { SCRIPT } from '../../../process-page/scripts/script.resource-type'; import { Process } from '../../../process-page/processes/process.model'; +import { RestRequest } from '../rest-request.model'; +import { CoreState } from '../../core-state.model'; export const METADATA_IMPORT_SCRIPT_NAME = 'metadata-import'; export const METADATA_EXPORT_SCRIPT_NAME = 'metadata-export'; diff --git a/src/app/core/data/registration-response-parsing.service.ts b/src/app/core/data/registration-response-parsing.service.ts index e11838e0ac7..067deea557a 100644 --- a/src/app/core/data/registration-response-parsing.service.ts +++ b/src/app/core/data/registration-response-parsing.service.ts @@ -4,8 +4,8 @@ import { } from '../cache/response.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { ResponseParsingService } from './parsing.service'; -import { RestRequest } from './request.models'; import { Registration } from '../shared/registration.model'; +import { RestRequest } from './rest-request.model'; @Injectable({ providedIn: 'root', diff --git a/src/app/core/data/relationship-type.service.ts b/src/app/core/data/relationship-type.service.ts index 4dac0440903..07608b8cf9b 100644 --- a/src/app/core/data/relationship-type.service.ts +++ b/src/app/core/data/relationship-type.service.ts @@ -10,7 +10,6 @@ import { followLink } from '../../shared/utils/follow-link-config.model'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { ItemType } from '../shared/item-relationships/item-type.model'; import { RelationshipType } from '../shared/item-relationships/relationship-type.model'; @@ -22,6 +21,7 @@ import { ItemDataService } from './item-data.service'; import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; import { RequestService } from './request.service'; +import { CoreState } from '../core-state.model'; /** * Check if one side of a RelationshipType is the ItemType with the given label diff --git a/src/app/core/data/relationship.service.spec.ts b/src/app/core/data/relationship.service.spec.ts index 0f7dd319c37..d27c8dd6b25 100644 --- a/src/app/core/data/relationship.service.spec.ts +++ b/src/app/core/data/relationship.service.spec.ts @@ -6,15 +6,16 @@ import { Relationship } from '../shared/item-relationships/relationship.model'; import { Item } from '../shared/item.model'; import { PageInfo } from '../shared/page-info.model'; import { buildPaginatedList } from './paginated-list.model'; -import { DeleteRequest, FindListOptions } from './request.models'; +import { DeleteRequest} from './request.models'; import { RelationshipService } from './relationship.service'; import { RequestService } from './request.service'; -import { RequestEntry } from './request.reducer'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { getMockRemoteDataBuildServiceHrefMap } from '../../shared/mocks/remote-data-build.service.mock'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { createPaginatedList } from '../../shared/testing/utils.test'; +import { RequestEntry } from './request-entry.model'; +import { FindListOptions } from './find-list-options.model'; describe('RelationshipService', () => { let service: RelationshipService; diff --git a/src/app/core/data/relationship.service.ts b/src/app/core/data/relationship.service.ts index 7bd36d0cece..e9e99314080 100644 --- a/src/app/core/data/relationship.service.ts +++ b/src/app/core/data/relationship.service.ts @@ -21,7 +21,6 @@ import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RequestParam } from '../cache/models/request-param.model'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { RelationshipType } from '../shared/item-relationships/relationship-type.model'; @@ -39,11 +38,14 @@ import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { ItemDataService } from './item-data.service'; import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; -import { DeleteRequest, FindListOptions, PostRequest, RestRequest } from './request.models'; +import { DeleteRequest, PostRequest} from './request.models'; import { RequestService } from './request.service'; import { NoContent } from '../shared/NoContent.model'; import { RequestEntryState } from './request-entry-state.model'; import { sendRequest } from '../shared/request.operators'; +import { RestRequest } from './rest-request.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; const relationshipListsStateSelector = (state: AppState) => state.relationshipLists; diff --git a/src/app/core/data/request-entry.model.ts b/src/app/core/data/request-entry.model.ts new file mode 100644 index 00000000000..1555c99ed43 --- /dev/null +++ b/src/app/core/data/request-entry.model.ts @@ -0,0 +1,13 @@ +import { RestRequestWithResponseParser } from './rest-request-with-response-parser.model'; +import { RequestEntryState } from './request-entry-state.model'; +import { ResponseState } from './response-state.model'; + +/** + * An entry for a request in the NgRx store + */ +export class RequestEntry { + request: RestRequestWithResponseParser; + state: RequestEntryState; + response: ResponseState; + lastUpdated: number; +} diff --git a/src/app/core/data/request-state.model.ts b/src/app/core/data/request-state.model.ts new file mode 100644 index 00000000000..5872dab2940 --- /dev/null +++ b/src/app/core/data/request-state.model.ts @@ -0,0 +1,8 @@ +import { RequestEntry } from './request-entry.model'; + +/** + * The request sub-state of the NgRx store + */ +export interface RequestState { + [uuid: string]: RequestEntry; +} diff --git a/src/app/core/data/request.actions.ts b/src/app/core/data/request.actions.ts index 8b3511d3e40..cc5415afbef 100644 --- a/src/app/core/data/request.actions.ts +++ b/src/app/core/data/request.actions.ts @@ -1,8 +1,8 @@ import { Action } from '@ngrx/store'; import { type } from '../../shared/ngrx/type'; -import { RestRequest } from './request.models'; import { HALLink } from '../shared/hal-link.model'; import { UnCacheableObject } from '../shared/uncacheable-object.model'; +import { RestRequest } from './rest-request.model'; /** * The list of RequestAction type definitions diff --git a/src/app/core/data/request.effects.ts b/src/app/core/data/request.effects.ts index e5a4fc7df2a..b297ca6692a 100644 --- a/src/app/core/data/request.effects.ts +++ b/src/app/core/data/request.effects.ts @@ -16,11 +16,12 @@ import { RequestSuccessAction, ResetResponseTimestampsAction } from './request.actions'; -import { RestRequest } from './request.models'; -import { RequestEntry } from './request.reducer'; import { RequestService } from './request.service'; import { ParsedResponse } from '../cache/response.models'; import { RequestError } from './request-error.model'; +import { RestRequest } from './rest-request.model'; +import { RestRequestWithResponseParser } from './rest-request-with-response-parser.model'; +import { RequestEntry } from './request-entry.model'; @Injectable() export class RequestEffects { @@ -34,7 +35,7 @@ export class RequestEffects { }), filter((entry: RequestEntry) => hasValue(entry)), map((entry: RequestEntry) => entry.request), - mergeMap((request: RestRequest) => { + mergeMap((request: RestRequestWithResponseParser) => { let body = request.body; if (isNotEmpty(request.body) && !request.isMultipart) { const serializer = new DSpaceSerializer(getClassForType(request.body.type)); diff --git a/src/app/core/data/request.models.ts b/src/app/core/data/request.models.ts index 990c37d192b..45b9b4143dd 100644 --- a/src/app/core/data/request.models.ts +++ b/src/app/core/data/request.models.ts @@ -1,15 +1,16 @@ -import { SortOptions } from '../cache/models/sort-options.model'; import { GenericConstructor } from '../shared/generic-constructor'; import { ResponseParsingService } from './parsing.service'; import { EndpointMapResponseParsingService } from './endpoint-map-response-parsing.service'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; -import { SubmissionResponseParsingService } from '../submission/submission-response-parsing.service'; +import { + SubmissionResponseParsingService +} from '../submission/submission-response-parsing.service'; import { RestRequestMethod } from './rest-request-method'; -import { RequestParam } from '../cache/models/request-param.model'; import { TaskResponseParsingService } from '../tasks/task-response-parsing.service'; import { ContentSourceResponseParsingService } from './content-source-response-parsing.service'; +import { RestRequestWithResponseParser } from './rest-request-with-response-parser.model'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; -import { environment } from '../../../environments/environment'; +import { FindListOptions } from './find-list-options.model'; /* tslint:disable:max-classes-per-file */ @@ -19,25 +20,13 @@ export enum IdentifierType { HANDLE = 'handle' } -export abstract class RestRequest { - public responseMsToLive = environment.cache.msToLive.default; - public isMultipart = false; - - constructor( - public uuid: string, - public href: string, - public method: RestRequestMethod = RestRequestMethod.GET, - public body?: any, - public options?: HttpOptions, - ) { - } - +class DSpaceRestRequest extends RestRequestWithResponseParser { getResponseParser(): GenericConstructor { return DspaceRestResponseParsingService; } } -export class GetRequest extends RestRequest { +export class GetRequest extends DSpaceRestRequest { constructor( public uuid: string, public href: string, @@ -48,7 +37,7 @@ export class GetRequest extends RestRequest { } } -export class PostRequest extends RestRequest { +export class PostRequest extends DSpaceRestRequest { constructor( public uuid: string, public href: string, @@ -62,7 +51,7 @@ export class PostRequest extends RestRequest { /** * Request representing a multipart post request */ -export class MultipartPostRequest extends RestRequest { +export class MultipartPostRequest extends DSpaceRestRequest { public isMultipart = true; constructor( public uuid: string, @@ -74,7 +63,7 @@ export class MultipartPostRequest extends RestRequest { } } -export class PutRequest extends RestRequest { +export class PutRequest extends DSpaceRestRequest { constructor( public uuid: string, public href: string, @@ -85,7 +74,7 @@ export class PutRequest extends RestRequest { } } -export class DeleteRequest extends RestRequest { +export class DeleteRequest extends DSpaceRestRequest { constructor( public uuid: string, public href: string, @@ -96,7 +85,7 @@ export class DeleteRequest extends RestRequest { } } -export class OptionsRequest extends RestRequest { +export class OptionsRequest extends DSpaceRestRequest { constructor( public uuid: string, public href: string, @@ -107,7 +96,7 @@ export class OptionsRequest extends RestRequest { } } -export class HeadRequest extends RestRequest { +export class HeadRequest extends DSpaceRestRequest { constructor( public uuid: string, public href: string, @@ -118,7 +107,7 @@ export class HeadRequest extends RestRequest { } } -export class PatchRequest extends RestRequest { +export class PatchRequest extends DSpaceRestRequest { constructor( public uuid: string, public href: string, @@ -129,15 +118,6 @@ export class PatchRequest extends RestRequest { } } -export class FindListOptions { - scopeID?: string; - elementsPerPage?: number; - currentPage?: number; - sort?: SortOptions; - searchParams?: RequestParam[]; - startsWith?: string; -} - export class FindListRequest extends GetRequest { constructor( uuid: string, diff --git a/src/app/core/data/request.reducer.spec.ts b/src/app/core/data/request.reducer.spec.ts index 2073b4faa1a..f6f557ad8f7 100644 --- a/src/app/core/data/request.reducer.spec.ts +++ b/src/app/core/data/request.reducer.spec.ts @@ -9,8 +9,9 @@ import { ResetResponseTimestampsAction } from './request.actions'; import { GetRequest } from './request.models'; -import { requestReducer, RequestState } from './request.reducer'; +import { requestReducer} from './request.reducer'; import { RequestEntryState } from './request-entry-state.model'; +import { RequestState } from './request-state.model'; class NullAction extends RequestSuccessAction { type = null; diff --git a/src/app/core/data/request.reducer.ts b/src/app/core/data/request.reducer.ts index 8b6f50dda8e..5019fc2231c 100644 --- a/src/app/core/data/request.reducer.ts +++ b/src/app/core/data/request.reducer.ts @@ -9,31 +9,9 @@ import { RequestSuccessAction, ResetResponseTimestampsAction } from './request.actions'; -import { RestRequest } from './request.models'; -import { HALLink } from '../shared/hal-link.model'; -import { UnCacheableObject } from '../shared/uncacheable-object.model'; import { isNull } from '../../shared/empty.util'; import { hasSucceeded, isStale, RequestEntryState } from './request-entry-state.model'; - -export class ResponseState { - timeCompleted: number; - statusCode: number; - errorMessage?: string; - payloadLink?: HALLink; - unCacheableObject?: UnCacheableObject; -} - -// tslint:disable-next-line:max-classes-per-file -export class RequestEntry { - request: RestRequest; - state: RequestEntryState; - response: ResponseState; - lastUpdated: number; -} - -export interface RequestState { - [uuid: string]: RequestEntry; -} +import { RequestState } from './request-state.model'; // Object.create(null) ensures the object has no default js properties (e.g. `__proto__`) const initialState = Object.create(null); diff --git a/src/app/core/data/request.service.spec.ts b/src/app/core/data/request.service.spec.ts index 50d753ab456..a49761ae5da 100644 --- a/src/app/core/data/request.service.spec.ts +++ b/src/app/core/data/request.service.spec.ts @@ -6,7 +6,7 @@ import { TestScheduler } from 'rxjs/testing'; import { getMockObjectCacheService } from '../../shared/mocks/object-cache.service.mock'; import { defaultUUID, getMockUUIDService } from '../../shared/mocks/uuid.service.mock'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { coreReducers, CoreState } from '../core.reducers'; +import { coreReducers} from '../core.reducers'; import { UUIDService } from '../shared/uuid.service'; import { RequestConfigureAction, RequestExecuteAction } from './request.actions'; import { @@ -16,15 +16,16 @@ import { OptionsRequest, PatchRequest, PostRequest, - PutRequest, - RestRequest + PutRequest } from './request.models'; -import { RequestEntry} from './request.reducer'; import { RequestService } from './request.service'; import { TestBed, waitForAsync } from '@angular/core/testing'; import { storeModuleConfig } from '../../app.reducer'; import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { RequestEntryState } from './request-entry-state.model'; +import { RestRequest } from './rest-request.model'; +import { CoreState } from '../core-state.model'; +import { RequestEntry } from './request-entry.model'; describe('RequestService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/data/request.service.ts b/src/app/core/data/request.service.ts index b381fdd1fd1..3903bcfc99c 100644 --- a/src/app/core/data/request.service.ts +++ b/src/app/core/data/request.service.ts @@ -8,7 +8,6 @@ import { cloneDeep } from 'lodash'; import { hasValue, isEmpty, isNotEmpty, hasNoValue } from '../../shared/empty.util'; import { ObjectCacheEntry } from '../cache/object-cache.reducer'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { IndexState, MetaIndexState } from '../index/index.reducer'; import { requestIndexSelector, getUrlWithoutEmbedParams } from '../index/index.selectors'; import { UUIDService } from '../shared/uuid.service'; @@ -17,12 +16,15 @@ import { RequestExecuteAction, RequestStaleAction } from './request.actions'; -import { GetRequest, RestRequest } from './request.models'; -import { RequestEntry, RequestState} from './request.reducer'; +import { GetRequest} from './request.models'; import { CommitSSBAction } from '../cache/server-sync-buffer.actions'; import { RestRequestMethod } from './rest-request-method'; import { coreSelector } from '../core.selectors'; import { isLoading, isStale } from './request-entry-state.model'; +import { RestRequest } from './rest-request.model'; +import { CoreState } from '../core-state.model'; +import { RequestState } from './request-state.model'; +import { RequestEntry } from './request-entry.model'; /** * The base selector function to select the request state in the store @@ -145,7 +147,7 @@ export class RequestService { /** * Check if a GET request is currently pending */ - isPending(request: GetRequest): boolean { + isPending(request: RestRequest): boolean { // If the request is not a GET request, it will never be considered pending, because you may // want to execute the exact same e.g. POST multiple times if (request.method !== RestRequestMethod.GET) { @@ -242,7 +244,7 @@ export class RequestService { if (this.shouldDispatchRequest(request, useCachedVersionIfAvailable)) { this.dispatchRequest(request); if (request.method === RestRequestMethod.GET) { - this.trackRequestsOnTheirWayToTheStore(request); + this.trackRequestsOnTheirWayToTheStore(request as GetRequest); } return true; } else { @@ -315,7 +317,7 @@ export class RequestService { * @param {boolean} useCachedVersionIfAvailable Whether or not to allow the use of a cached version * @returns {boolean} True if the request is cached or still pending */ - public shouldDispatchRequest(request: GetRequest, useCachedVersionIfAvailable: boolean): boolean { + public shouldDispatchRequest(request: RestRequest, useCachedVersionIfAvailable: boolean): boolean { // if it's not a GET request if (request.method !== RestRequestMethod.GET) { return true; diff --git a/src/app/core/data/response-state.model.ts b/src/app/core/data/response-state.model.ts new file mode 100644 index 00000000000..97203fcdd55 --- /dev/null +++ b/src/app/core/data/response-state.model.ts @@ -0,0 +1,13 @@ +import { HALLink } from '../shared/hal-link.model'; +import { UnCacheableObject } from '../shared/uncacheable-object.model'; + +/** + * The response substate in the NgRx store + */ +export class ResponseState { + timeCompleted: number; + statusCode: number; + errorMessage?: string; + payloadLink?: HALLink; + unCacheableObject?: UnCacheableObject; +} diff --git a/src/app/core/data/rest-request-with-response-parser.model.ts b/src/app/core/data/rest-request-with-response-parser.model.ts new file mode 100644 index 00000000000..1c9677ebb17 --- /dev/null +++ b/src/app/core/data/rest-request-with-response-parser.model.ts @@ -0,0 +1,14 @@ +import { RestRequest } from './rest-request.model'; +import { GenericConstructor } from '../shared/generic-constructor'; +import { ResponseParsingService } from './parsing.service'; + +/** + * A RestRequest with a method to retrieve the ResponseParsingService needed for its response + */ +export abstract class RestRequestWithResponseParser extends RestRequest { + + /** + * Get the ResponseParsingService needed to parse the response to this request + */ + abstract getResponseParser(): GenericConstructor; +} diff --git a/src/app/core/data/rest-request.model.ts b/src/app/core/data/rest-request.model.ts new file mode 100644 index 00000000000..05b583639b0 --- /dev/null +++ b/src/app/core/data/rest-request.model.ts @@ -0,0 +1,20 @@ +import { environment } from '../../../environments/environment'; +import { RestRequestMethod } from './rest-request-method'; +import { HttpOptions } from '../dspace-rest/dspace-rest.service'; + +/** + * A request to the DSpace REST API + */ +export abstract class RestRequest { + public responseMsToLive = environment.cache.msToLive.default; + public isMultipart = false; + + constructor( + public uuid: string, + public href: string, + public method: RestRequestMethod = RestRequestMethod.GET, + public body?: any, + public options?: HttpOptions, + ) { + } +} diff --git a/src/app/core/data/root-data.service.ts b/src/app/core/data/root-data.service.ts index 8b4e8366716..b5245c8d48c 100644 --- a/src/app/core/data/root-data.service.ts +++ b/src/app/core/data/root-data.service.ts @@ -6,7 +6,6 @@ import { dataService } from '../cache/builders/build-decorators'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; @@ -15,8 +14,9 @@ import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { Observable } from 'rxjs'; import { RemoteData } from './remote-data'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; -import { FindListOptions } from './request.models'; import { PaginatedList } from './paginated-list.model'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /* tslint:disable:max-classes-per-file */ diff --git a/src/app/core/data/search-response-parsing.service.ts b/src/app/core/data/search-response-parsing.service.ts index be2fbe90fc9..e5100aba66e 100644 --- a/src/app/core/data/search-response-parsing.service.ts +++ b/src/app/core/data/search-response-parsing.service.ts @@ -5,8 +5,8 @@ import { ParsedResponse } from '../cache/response.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { MetadataMap, MetadataValue } from '../shared/metadata.models'; -import { RestRequest } from './request.models'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; +import { RestRequest } from './rest-request.model'; @Injectable() export class SearchResponseParsingService extends DspaceRestResponseParsingService { diff --git a/src/app/core/data/site-data.service.spec.ts b/src/app/core/data/site-data.service.spec.ts index c6b69914884..1e8b135db85 100644 --- a/src/app/core/data/site-data.service.spec.ts +++ b/src/app/core/data/site-data.service.spec.ts @@ -5,14 +5,14 @@ import { RemoteDataBuildService } from '../cache/builders/remote-data-build.serv import { ObjectCacheService } from '../cache/object-cache.service'; import { Site } from '../shared/site.model'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { HALEndpointService } from '../shared/hal-endpoint.service'; -import { FindListOptions } from './request.models'; import { TestScheduler } from 'rxjs/testing'; import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; import { createPaginatedList } from '../../shared/testing/utils.test'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; describe('SiteDataService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/data/site-data.service.ts b/src/app/core/data/site-data.service.ts index a91b599e58f..b2ba9d6dfb6 100644 --- a/src/app/core/data/site-data.service.ts +++ b/src/app/core/data/site-data.service.ts @@ -7,7 +7,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { getFirstSucceededRemoteData } from '../shared/operators'; import { Site } from '../shared/site.model'; @@ -17,6 +16,7 @@ import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { PaginatedList } from './paginated-list.model'; import { RemoteData } from './remote-data'; import { RequestService } from './request.service'; +import { CoreState } from '../core-state.model'; /** * Service responsible for handling requests related to the Site object diff --git a/src/app/core/data/status-code-only-response-parsing.service.ts b/src/app/core/data/status-code-only-response-parsing.service.ts index 4f0030371f6..ad6a01429d4 100644 --- a/src/app/core/data/status-code-only-response-parsing.service.ts +++ b/src/app/core/data/status-code-only-response-parsing.service.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { RestResponse } from '../cache/response.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { ResponseParsingService } from './parsing.service'; -import { RestRequest } from './request.models'; +import { RestRequest } from './rest-request.model'; /** * A responseparser that will only look at the status code and status diff --git a/src/app/core/data/version-data.service.ts b/src/app/core/data/version-data.service.ts index 11a3838eb0a..14dd94c7745 100644 --- a/src/app/core/data/version-data.service.ts +++ b/src/app/core/data/version-data.service.ts @@ -4,16 +4,16 @@ import { Version } from '../shared/version.model'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; -import { FindListOptions } from './request.models'; import { Observable } from 'rxjs'; import { dataService } from '../cache/builders/build-decorators'; import { VERSION } from '../shared/version.resource-type'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * Service responsible for handling requests related to the Version object diff --git a/src/app/core/data/version-history-data.service.ts b/src/app/core/data/version-history-data.service.ts index 8f148f168df..42977aa67e5 100644 --- a/src/app/core/data/version-history-data.service.ts +++ b/src/app/core/data/version-history-data.service.ts @@ -4,13 +4,11 @@ import { Injectable } from '@angular/core'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; -import { FindListOptions } from './request.models'; import { Observable } from 'rxjs'; import { PaginatedSearchOptions } from '../../shared/search/paginated-search-options.model'; import { RemoteData } from './remote-data'; @@ -21,6 +19,8 @@ import { dataService } from '../cache/builders/build-decorators'; import { VERSION_HISTORY } from '../shared/version-history.resource-type'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { VersionDataService } from './version-data.service'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * Service responsible for handling requests related to the VersionHistory object diff --git a/src/app/core/data/workflow-action-data.service.ts b/src/app/core/data/workflow-action-data.service.ts index c5a2980d9f6..ab8f187b2ff 100644 --- a/src/app/core/data/workflow-action-data.service.ts +++ b/src/app/core/data/workflow-action-data.service.ts @@ -3,17 +3,17 @@ import { WorkflowAction } from '../tasks/models/workflow-action-object.model'; import { RequestService } from './request.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; -import { FindListOptions } from './request.models'; import { Observable } from 'rxjs'; import { Injectable } from '@angular/core'; import { dataService } from '../cache/builders/build-decorators'; import { WORKFLOW_ACTION } from '../tasks/models/workflow-action-object.resource-type'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from './find-list-options.model'; /** * A service responsible for fetching/sending data from/to the REST API on the workflowactions endpoint diff --git a/src/app/core/eperson/eperson-data.service.spec.ts b/src/app/core/eperson/eperson-data.service.spec.ts index cd7b664379e..2cf849b8310 100644 --- a/src/app/core/eperson/eperson-data.service.spec.ts +++ b/src/app/core/eperson/eperson-data.service.spec.ts @@ -12,9 +12,8 @@ import { EPeopleRegistryEditEPersonAction } from '../../access-control/epeople-registry/epeople-registry.actions'; import { RequestParam } from '../cache/models/request-param.model'; -import { CoreState } from '../core.reducers'; import { ChangeAnalyzer } from '../data/change-analyzer'; -import { DeleteRequest, FindListOptions, PatchRequest, PostRequest } from '../data/request.models'; +import { DeleteRequest, PatchRequest, PostRequest } from '../data/request.models'; import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { Item } from '../shared/item.model'; @@ -27,6 +26,8 @@ import { getMockRemoteDataBuildServiceHrefMap } from '../../shared/mocks/remote- import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { createPaginatedList, createRequestEntry$ } from '../../shared/testing/utils.test'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; describe('EPersonDataService', () => { let service: EPersonDataService; diff --git a/src/app/core/eperson/eperson-data.service.ts b/src/app/core/eperson/eperson-data.service.ts index bceb38f163f..d801ab6fa47 100644 --- a/src/app/core/eperson/eperson-data.service.ts +++ b/src/app/core/eperson/eperson-data.service.ts @@ -21,7 +21,7 @@ import { DataService } from '../data/data.service'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; import { PaginatedList, buildPaginatedList } from '../data/paginated-list.model'; import { RemoteData } from '../data/remote-data'; -import { FindListOptions, PatchRequest, PostRequest, } from '../data/request.models'; +import { PatchRequest, PostRequest, } from '../data/request.models'; import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { getRemoteDataPayload, getFirstSucceededRemoteData, } from '../shared/operators'; @@ -29,6 +29,7 @@ import { EPerson } from './models/eperson.model'; import { EPERSON } from './models/eperson.resource-type'; import { NoContent } from '../shared/NoContent.model'; import { PageInfo } from '../shared/page-info.model'; +import { FindListOptions } from '../data/find-list-options.model'; const ePeopleRegistryStateSelector = (state: AppState) => state.epeopleRegistry; const editEPersonSelector = createSelector(ePeopleRegistryStateSelector, (ePeopleRegistryState: EPeopleRegistryState) => ePeopleRegistryState.editEPerson); diff --git a/src/app/core/eperson/group-data.service.spec.ts b/src/app/core/eperson/group-data.service.spec.ts index 378c3c96671..c30b74e966f 100644 --- a/src/app/core/eperson/group-data.service.spec.ts +++ b/src/app/core/eperson/group-data.service.spec.ts @@ -11,9 +11,8 @@ import { } from '../../access-control/group-registry/group-registry.actions'; import { GroupMock, GroupMock2 } from '../../shared/testing/group-mock'; import { RequestParam } from '../cache/models/request-param.model'; -import { CoreState } from '../core.reducers'; import { ChangeAnalyzer } from '../data/change-analyzer'; -import { DeleteRequest, FindListOptions, PostRequest } from '../data/request.models'; +import { DeleteRequest, PostRequest } from '../data/request.models'; import { RequestService } from '../data/request.service'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { Item } from '../shared/item.model'; @@ -25,6 +24,8 @@ import { TranslateLoaderMock } from '../../shared/testing/translate-loader.mock' import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { EPersonMock, EPersonMock2 } from '../../shared/testing/eperson.mock'; import { createPaginatedList, createRequestEntry$ } from '../../shared/testing/utils.test'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; describe('GroupDataService', () => { let service: GroupDataService; diff --git a/src/app/core/eperson/group-data.service.ts b/src/app/core/eperson/group-data.service.ts index 5b8f474d1ad..bc09c5b9737 100644 --- a/src/app/core/eperson/group-data.service.ts +++ b/src/app/core/eperson/group-data.service.ts @@ -19,7 +19,7 @@ import { DataService } from '../data/data.service'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; import { PaginatedList } from '../data/paginated-list.model'; import { RemoteData } from '../data/remote-data'; -import { CreateRequest, DeleteRequest, FindListOptions, PostRequest } from '../data/request.models'; +import { CreateRequest, DeleteRequest, PostRequest } from '../data/request.models'; import { RequestService } from '../data/request.service'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; @@ -33,6 +33,7 @@ import { DSONameService } from '../breadcrumbs/dso-name.service'; import { Community } from '../shared/community.model'; import { Collection } from '../shared/collection.model'; import { NoContent } from '../shared/NoContent.model'; +import { FindListOptions } from '../data/find-list-options.model'; const groupRegistryStateSelector = (state: AppState) => state.groupRegistry; const editGroupSelector = createSelector(groupRegistryStateSelector, (groupRegistryState: GroupRegistryState) => groupRegistryState.editGroup); diff --git a/src/app/core/history/selectors.ts b/src/app/core/history/selectors.ts index 5c77cd65f0f..925b56c795d 100644 --- a/src/app/core/history/selectors.ts +++ b/src/app/core/history/selectors.ts @@ -1,6 +1,6 @@ -import { CoreState } from '../core.reducers'; import { createSelector } from '@ngrx/store'; import { coreSelector } from '../core.selectors'; +import { CoreState } from '../core-state.model'; export const historySelector = createSelector( coreSelector, diff --git a/src/app/core/index/index.effects.ts b/src/app/core/index/index.effects.ts index 58acc08acc6..60e9af6129e 100644 --- a/src/app/core/index/index.effects.ts +++ b/src/app/core/index/index.effects.ts @@ -17,9 +17,9 @@ import { hasValue } from '../../shared/empty.util'; import { RestRequestMethod } from '../data/rest-request-method'; import { getUrlWithoutEmbedParams, uuidFromHrefSelector } from './index.selectors'; import { Store, select } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { NoOpAction } from '../../shared/ngrx/no-op.action'; import { IndexName } from './index-name.model'; +import { CoreState } from '../core-state.model'; @Injectable() export class UUIDIndexEffects { diff --git a/src/app/core/index/index.selectors.ts b/src/app/core/index/index.selectors.ts index 435398d0a42..697616c3210 100644 --- a/src/app/core/index/index.selectors.ts +++ b/src/app/core/index/index.selectors.ts @@ -1,11 +1,11 @@ import { createSelector, MemoizedSelector } from '@ngrx/store'; import { hasValue, isNotEmpty } from '../../shared/empty.util'; -import { CoreState } from '../core.reducers'; import { coreSelector } from '../core.selectors'; import { URLCombiner } from '../url-combiner/url-combiner'; import { IndexState, MetaIndexState } from './index.reducer'; import * as parse from 'url-parse'; import { IndexName } from './index-name.model'; +import { CoreState } from '../core-state.model'; /** * Return the given url without `embed` params. diff --git a/src/app/core/json-patch/builder/json-patch-operations-builder.ts b/src/app/core/json-patch/builder/json-patch-operations-builder.ts index d3896c4a6c2..f5a584fd3d0 100644 --- a/src/app/core/json-patch/builder/json-patch-operations-builder.ts +++ b/src/app/core/json-patch/builder/json-patch-operations-builder.ts @@ -1,5 +1,4 @@ import { Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { NewPatchAddOperationAction, NewPatchMoveOperationAction, @@ -13,6 +12,7 @@ import { dateToISOFormat, dateToString, isNgbDateStruct } from '../../../shared/ import { VocabularyEntry } from '../../submission/vocabularies/models/vocabulary-entry.model'; import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model'; import { FormFieldLanguageValueObject } from '../../../shared/form/builder/models/form-field-language-value.model'; +import { CoreState } from '../../core-state.model'; /** * Provides methods to dispatch JsonPatch Operations Actions diff --git a/src/app/core/json-patch/json-patch-operations.service.spec.ts b/src/app/core/json-patch/json-patch-operations.service.spec.ts index d1b29487770..10fc2f2ed84 100644 --- a/src/app/core/json-patch/json-patch-operations.service.spec.ts +++ b/src/app/core/json-patch/json-patch-operations.service.spec.ts @@ -12,7 +12,6 @@ import { RemoteDataBuildService } from '../cache/builders/remote-data-build.serv import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-build.service.mock'; import { JsonPatchOperationsService } from './json-patch-operations.service'; import { SubmitDataResponseDefinitionObject } from '../shared/submit-data-response-definition.model'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { JsonPatchOperationsEntry, JsonPatchOperationsResourceEntry } from './json-patch-operations.reducer'; import { @@ -21,9 +20,10 @@ import { RollbacktPatchOperationsAction, StartTransactionPatchOperationsAction } from './json-patch-operations.actions'; -import { RequestEntry } from '../data/request.reducer'; import { createFailedRemoteDataObject, createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; import { deepClone } from 'fast-json-patch'; +import { CoreState } from '../core-state.model'; +import { RequestEntry } from '../data/request-entry.model'; class TestService extends JsonPatchOperationsService { diff --git a/src/app/core/json-patch/json-patch-operations.service.ts b/src/app/core/json-patch/json-patch-operations.service.ts index c3363f4db4a..1dfbd404cc6 100644 --- a/src/app/core/json-patch/json-patch-operations.service.ts +++ b/src/app/core/json-patch/json-patch-operations.service.ts @@ -6,7 +6,6 @@ import { hasValue, isEmpty, isNotEmpty, isNotUndefined, isUndefined } from '../. import { PatchRequest } from '../data/request.models'; import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; -import { CoreState } from '../core.reducers'; import { jsonPatchOperationsByResourceType } from './selectors'; import { JsonPatchOperationsResourceEntry } from './json-patch-operations.reducer'; import { @@ -18,6 +17,7 @@ import { JsonPatchOperationModel } from './json-patch.model'; import { getFirstCompletedRemoteData } from '../shared/operators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteData } from '../data/remote-data'; +import { CoreState } from '../core-state.model'; /** * An abstract class that provides methods to make JSON Patch requests. diff --git a/src/app/core/json-patch/selectors.ts b/src/app/core/json-patch/selectors.ts index 1ccde294de2..20eb8538916 100644 --- a/src/app/core/json-patch/selectors.ts +++ b/src/app/core/json-patch/selectors.ts @@ -1,8 +1,8 @@ import { MemoizedSelector } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { coreSelector } from '../core.selectors'; import { JsonPatchOperationsEntry, JsonPatchOperationsResourceEntry } from './json-patch-operations.reducer'; import { keySelector, subStateSelector } from '../../submission/selectors'; +import { CoreState } from '../core-state.model'; /** * Return MemoizedSelector to select all jsonPatchOperations for a specified resource type, stored in the state diff --git a/src/app/core/metadata/metadata.service.ts b/src/app/core/metadata/metadata.service.ts index 1c6946b0d3e..469a908ab59 100644 --- a/src/app/core/metadata/metadata.service.ts +++ b/src/app/core/metadata/metadata.service.ts @@ -31,7 +31,7 @@ import { MetaTagState } from './meta-tag.reducer'; import { createSelector, select, Store } from '@ngrx/store'; import { AddMetaTagAction, ClearMetaTagAction } from './meta-tag.actions'; import { coreSelector } from '../core.selectors'; -import { CoreState } from '../core.reducers'; +import { CoreState } from '../core-state.model'; /** * The base selector function to select the metaTag section in the store diff --git a/src/app/core/pagination/pagination.service.spec.ts b/src/app/core/pagination/pagination.service.spec.ts index 18f94cc84c6..94b6b48d59d 100644 --- a/src/app/core/pagination/pagination.service.spec.ts +++ b/src/app/core/pagination/pagination.service.spec.ts @@ -3,7 +3,7 @@ import { RouterStub } from '../../shared/testing/router.stub'; import { of as observableOf } from 'rxjs'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../cache/models/sort-options.model'; -import { FindListOptions } from '../data/request.models'; +import { FindListOptions } from '../data/find-list-options.model'; describe('PaginationService', () => { diff --git a/src/app/core/pagination/pagination.service.ts b/src/app/core/pagination/pagination.service.ts index dae69918346..bddb565c899 100644 --- a/src/app/core/pagination/pagination.service.ts +++ b/src/app/core/pagination/pagination.service.ts @@ -5,10 +5,10 @@ import { PaginationComponentOptions } from '../../shared/pagination/pagination-c import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; import { filter, map, take } from 'rxjs/operators'; import { SortDirection, SortOptions } from '../cache/models/sort-options.model'; -import { FindListOptions } from '../data/request.models'; import { hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util'; import { difference } from '../../shared/object.util'; import { isNumeric } from 'rxjs/internal-compatibility'; +import { FindListOptions } from '../data/find-list-options.model'; @Injectable({ diff --git a/src/app/core/registry/registry.service.spec.ts b/src/app/core/registry/registry.service.spec.ts index 199f43e98e2..db52a0547ec 100644 --- a/src/app/core/registry/registry.service.spec.ts +++ b/src/app/core/registry/registry.service.spec.ts @@ -23,13 +23,13 @@ import { MetadataField } from '../metadata/metadata-field.model'; import { MetadataSchema } from '../metadata/metadata-schema.model'; import { RegistryService } from './registry.service'; 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 { 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'; @Component({ template: '' }) class DummyComponent { diff --git a/src/app/core/registry/registry.service.ts b/src/app/core/registry/registry.service.ts index 0046dbdb19c..7a377405bd0 100644 --- a/src/app/core/registry/registry.service.ts +++ b/src/app/core/registry/registry.service.ts @@ -2,7 +2,6 @@ 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 { FindListOptions } from '../data/request.models'; import { hasValue, hasValueOperator, isNotEmptyOperator } from '../../shared/empty.util'; import { getFirstSucceededRemoteDataPayload } from '../shared/operators'; import { createSelector, select, Store } from '@ngrx/store'; @@ -30,6 +29,7 @@ import { MetadataFieldDataService } from '../data/metadata-field-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'; const metadataRegistryStateSelector = (state: AppState) => state.metadataRegistry; const editMetadataSchemaSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.editSchema); diff --git a/src/app/core/resource-policy/resource-policy.service.spec.ts b/src/app/core/resource-policy/resource-policy.service.spec.ts index 9330def8e88..59316c00981 100644 --- a/src/app/core/resource-policy/resource-policy.service.spec.ts +++ b/src/app/core/resource-policy/resource-policy.service.spec.ts @@ -12,13 +12,13 @@ import { RequestService } from '../data/request.service'; import { ResourcePolicyService } from './resource-policy.service'; import { PolicyType } from './models/policy-type.model'; import { ActionType } from './models/action-type.model'; -import { FindListOptions } from '../data/request.models'; import { RequestParam } from '../cache/models/request-param.model'; import { PageInfo } from '../shared/page-info.model'; import { buildPaginatedList } from '../data/paginated-list.model'; import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; -import { RequestEntry } from '../data/request.reducer'; import { RestResponse } from '../cache/response.models'; +import { RequestEntry } from '../data/request-entry.model'; +import { FindListOptions } from '../data/find-list-options.model'; describe('ResourcePolicyService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/resource-policy/resource-policy.service.ts b/src/app/core/resource-policy/resource-policy.service.ts index 0f4c6a78f8d..eeba5a10118 100644 --- a/src/app/core/resource-policy/resource-policy.service.ts +++ b/src/app/core/resource-policy/resource-policy.service.ts @@ -8,13 +8,11 @@ import { dataService } from '../cache/builders/build-decorators'; import { DataService } from '../data/data.service'; import { RequestService } from '../data/request.service'; -import { FindListOptions } from '../data/request.models'; import { Collection } from '../shared/collection.model'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { ResourcePolicy } from './models/resource-policy.model'; import { RemoteData } from '../data/remote-data'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { RESOURCE_POLICY } from './models/resource-policy.resource-type'; @@ -27,6 +25,8 @@ import { isNotEmpty } from '../../shared/empty.util'; import { map } from 'rxjs/operators'; import { NoContent } from '../shared/NoContent.model'; import { getFirstCompletedRemoteData } from '../shared/operators'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; /* tslint:disable:max-classes-per-file */ diff --git a/src/app/core/services/route.service.ts b/src/app/core/services/route.service.ts index 23b7ccec85e..b84bb40373a 100644 --- a/src/app/core/services/route.service.ts +++ b/src/app/core/services/route.service.ts @@ -7,11 +7,11 @@ import { createSelector, MemoizedSelector, select, Store } from '@ngrx/store'; import { isEqual } from 'lodash'; import { AddParameterAction, SetParameterAction, SetParametersAction, SetQueryParameterAction, SetQueryParametersAction } from './route.actions'; -import { CoreState } from '../core.reducers'; import { coreSelector } from '../core.selectors'; import { hasValue } from '../../shared/empty.util'; import { historySelector } from '../history/selectors'; import { AddUrlToHistoryAction } from '../history/history.actions'; +import { CoreState } from '../core-state.model'; /** * Selector to select all route parameters from the store diff --git a/src/app/core/shared/operators.spec.ts b/src/app/core/shared/operators.spec.ts index eb102065cd7..872c087325e 100644 --- a/src/app/core/shared/operators.spec.ts +++ b/src/app/core/shared/operators.spec.ts @@ -2,7 +2,6 @@ import { cold, getTestScheduler, hot } from 'jasmine-marbles'; import { TestScheduler } from 'rxjs/testing'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { GetRequest } from '../data/request.models'; -import { RequestEntry } from '../data/request.reducer'; import { RequestService } from '../data/request.service'; import { getAllSucceededRemoteData, @@ -16,6 +15,7 @@ import { } from '../../shared/remote-data.utils'; import { getRequestFromRequestHref, getRequestFromRequestUUID, getResponseFromEntry, sendRequest } from './request.operators'; import { redirectOn4xx } from './authorized.operators'; +import { RequestEntry } from '../data/request-entry.model'; // tslint:disable:no-shadowed-variable diff --git a/src/app/core/shared/request.operators.ts b/src/app/core/shared/request.operators.ts index 3caba824b94..c529259f035 100644 --- a/src/app/core/shared/request.operators.ts +++ b/src/app/core/shared/request.operators.ts @@ -1,9 +1,10 @@ import { RequestService } from '../data/request.service'; import { Observable } from 'rxjs'; -import { RestRequest } from '../data/request.models'; import { filter, map, mergeMap, tap } from 'rxjs/operators'; -import { RequestEntry, ResponseState } from '../data/request.reducer'; import { hasValue, hasValueOperator } from '../../shared/empty.util'; +import { RestRequest } from '../data/rest-request.model'; +import { RequestEntry } from '../data/request-entry.model'; +import { ResponseState } from '../data/response-state.model'; /** * This file contains custom RxJS operators that can be used in multiple places diff --git a/src/app/core/shared/search/search-configuration.service.spec.ts b/src/app/core/shared/search/search-configuration.service.spec.ts index 30be28f65fd..0cb97630725 100644 --- a/src/app/core/shared/search/search-configuration.service.spec.ts +++ b/src/app/core/shared/search/search-configuration.service.spec.ts @@ -8,12 +8,12 @@ import { combineLatest as observableCombineLatest, Observable, of as observableO import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; import { HALEndpointServiceStub } from '../../../shared/testing/hal-endpoint-service.stub'; import { getMockRemoteDataBuildService } from '../../../shared/mocks/remote-data-build.service.mock'; -import { RequestEntry } from '../../data/request.reducer'; import { map } from 'rxjs/operators'; import { RemoteData } from '../../data/remote-data'; import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { SearchObjects } from '../../../shared/search/search-objects.model'; import { getMockRequestService } from '../../../shared/mocks/request.service.mock'; +import { RequestEntry } from '../../data/request-entry.model'; describe('SearchConfigurationService', () => { let service: SearchConfigurationService; diff --git a/src/app/core/shared/search/search-configuration.service.ts b/src/app/core/shared/search/search-configuration.service.ts index d62e5ea01bb..0a2afe61830 100644 --- a/src/app/core/shared/search/search-configuration.service.ts +++ b/src/app/core/shared/search/search-configuration.service.ts @@ -491,7 +491,7 @@ export class SearchConfigurationService implements OnDestroy { let filters: SearchFilterConfig[]; if (isNotEmpty(rd.payload.filters)) { filters = rd.payload.filters - .map((filter: any) => Object.assign(new SearchFilterConfig(), filter)); + .map((f: any) => Object.assign(new SearchFilterConfig(), f)); } else { filters = []; } diff --git a/src/app/core/shared/search/search.service.spec.ts b/src/app/core/shared/search/search.service.spec.ts index d41f6d8d721..c9b6152efdd 100644 --- a/src/app/core/shared/search/search.service.spec.ts +++ b/src/app/core/shared/search/search.service.spec.ts @@ -11,7 +11,6 @@ import { HALEndpointService } from '../hal-endpoint.service'; import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; import { PaginatedSearchOptions } from '../../../shared/search/paginated-search-options.model'; import { RemoteData } from '../../data/remote-data'; -import { RequestEntry } from '../../data/request.reducer'; import { getMockRequestService } from '../../../shared/mocks/request.service.mock'; import { CommunityDataService } from '../../data/community-data.service'; import { ViewMode } from '../view-mode.model'; @@ -25,9 +24,10 @@ import { SearchObjects } from '../../../shared/search/search-objects.model'; import { PaginationService } from '../../pagination/pagination.service'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../cache/models/sort-options.model'; -import { FindListOptions } from '../../data/request.models'; import { SearchConfigurationService } from './search-configuration.service'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; +import { RequestEntry } from '../../data/request-entry.model'; +import { FindListOptions } from '../../data/find-list-options.model'; @Component({ template: '' }) class DummyComponent { diff --git a/src/app/core/shared/search/search.service.ts b/src/app/core/shared/search/search.service.ts index 13340874e72..8219cb803c8 100644 --- a/src/app/core/shared/search/search.service.ts +++ b/src/app/core/shared/search/search.service.ts @@ -7,7 +7,7 @@ import { LinkService } from '../../cache/builders/link.service'; import { PaginatedList } from '../../data/paginated-list.model'; import { ResponseParsingService } from '../../data/parsing.service'; import { RemoteData } from '../../data/remote-data'; -import { GetRequest, RestRequest } from '../../data/request.models'; +import { GetRequest} from '../../data/request.models'; import { RequestService } from '../../data/request.service'; import { DSpaceObject } from '../dspace-object.model'; import { GenericConstructor } from '../generic-constructor'; @@ -43,11 +43,12 @@ import { SearchConfigurationService } from './search-configuration.service'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { DataService } from '../../data/data.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../../core.reducers'; import { ObjectCacheService } from '../../cache/object-cache.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { HttpClient } from '@angular/common/http'; import { DSOChangeAnalyzer } from '../../data/dso-change-analyzer.service'; +import { RestRequest } from '../../data/rest-request.model'; +import { CoreState } from '../../core-state.model'; /* tslint:disable:max-classes-per-file */ /** diff --git a/src/app/core/statistics/usage-report-data.service.ts b/src/app/core/statistics/usage-report-data.service.ts index 74385777b1b..be23f71c48c 100644 --- a/src/app/core/statistics/usage-report-data.service.ts +++ b/src/app/core/statistics/usage-report-data.service.ts @@ -5,7 +5,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { DataService } from '../data/data.service'; import { RequestService } from '../data/request.service'; @@ -15,6 +14,7 @@ import { UsageReport } from './models/usage-report.model'; import { Observable } from 'rxjs'; import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../shared/operators'; import { map } from 'rxjs/operators'; +import { CoreState } from '../core-state.model'; /** * A service to retrieve {@link UsageReport}s from the REST API diff --git a/src/app/core/submission/submission-cc-license-data.service.ts b/src/app/core/submission/submission-cc-license-data.service.ts index 5a3fa1ec2b0..4c92ad708a9 100644 --- a/src/app/core/submission/submission-cc-license-data.service.ts +++ b/src/app/core/submission/submission-cc-license-data.service.ts @@ -5,13 +5,13 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { DataService } from '../data/data.service'; import { RequestService } from '../data/request.service'; import { SUBMISSION_CC_LICENSE } from './models/submission-cc-licence.resource-type'; import { SubmissionCcLicence } from './models/submission-cc-license.model'; import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service'; +import { CoreState } from '../core-state.model'; @Injectable() @dataService(SUBMISSION_CC_LICENSE) diff --git a/src/app/core/submission/submission-cc-license-url-data.service.ts b/src/app/core/submission/submission-cc-license-url-data.service.ts index 0ca3853d0e3..1e72f791937 100644 --- a/src/app/core/submission/submission-cc-license-url-data.service.ts +++ b/src/app/core/submission/submission-cc-license-url-data.service.ts @@ -5,7 +5,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { DataService } from '../data/data.service'; import { RequestService } from '../data/request.service'; @@ -17,6 +16,7 @@ import { Observable } from 'rxjs'; import { filter, map, switchMap } from 'rxjs/operators'; import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../shared/operators'; import { isNotEmpty } from '../../shared/empty.util'; +import { CoreState } from '../core-state.model'; @Injectable() @dataService(SUBMISSION_CC_LICENSE_URL) diff --git a/src/app/core/submission/submission-json-patch-operations.service.spec.ts b/src/app/core/submission/submission-json-patch-operations.service.spec.ts index 72c807ffa1d..5472e868563 100644 --- a/src/app/core/submission/submission-json-patch-operations.service.spec.ts +++ b/src/app/core/submission/submission-json-patch-operations.service.spec.ts @@ -3,12 +3,12 @@ import { Store } from '@ngrx/store'; import { getTestScheduler } from 'jasmine-marbles'; import { TestScheduler } from 'rxjs/testing'; -import { CoreState } from '../core.reducers'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { SubmissionJsonPatchOperationsService } from './submission-json-patch-operations.service'; import { RequestService } from '../data/request.service'; import { SubmissionPatchRequest } from '../data/request.models'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { CoreState } from '../core-state.model'; describe('SubmissionJsonPatchOperationsService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/submission/submission-json-patch-operations.service.ts b/src/app/core/submission/submission-json-patch-operations.service.ts index cd6308f7f3d..5771c85b574 100644 --- a/src/app/core/submission/submission-json-patch-operations.service.ts +++ b/src/app/core/submission/submission-json-patch-operations.service.ts @@ -7,8 +7,8 @@ import { HALEndpointService } from '../shared/hal-endpoint.service'; import { JsonPatchOperationsService } from '../json-patch/json-patch-operations.service'; import { SubmitDataResponseDefinitionObject } from '../shared/submit-data-response-definition.model'; import { SubmissionPatchRequest } from '../data/request.models'; -import { CoreState } from '../core.reducers'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; +import { CoreState } from '../core-state.model'; /** * A service that provides methods to make JSON Patch requests. diff --git a/src/app/core/submission/submission-response-parsing.service.ts b/src/app/core/submission/submission-response-parsing.service.ts index 3b028c67cc3..ff847762357 100644 --- a/src/app/core/submission/submission-response-parsing.service.ts +++ b/src/app/core/submission/submission-response-parsing.service.ts @@ -3,7 +3,6 @@ import { deepClone } from 'fast-json-patch'; import { DSOResponseParsingService } from '../data/dso-response-parsing.service'; import { ResponseParsingService } from '../data/parsing.service'; -import { RestRequest } from '../data/request.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { ParsedResponse } from '../cache/response.models'; import { isEmpty, isNotEmpty, isNotNull } from '../../shared/empty.util'; @@ -14,6 +13,7 @@ import { FormFieldMetadataValueObject } from '../../shared/form/builder/models/f import { SubmissionObject } from './models/submission-object.model'; import { WorkflowItem } from './models/workflowitem.model'; import { WorkspaceItem } from './models/workspaceitem.model'; +import { RestRequest } from '../data/rest-request.model'; /** * Export a function to check if object has same properties of FormFieldMetadataValueObject diff --git a/src/app/core/submission/submission-rest.service.ts b/src/app/core/submission/submission-rest.service.ts index 000f8396f82..cf4b741af23 100644 --- a/src/app/core/submission/submission-rest.service.ts +++ b/src/app/core/submission/submission-rest.service.ts @@ -8,7 +8,6 @@ import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { DeleteRequest, PostRequest, - RestRequest, SubmissionDeleteRequest, SubmissionPatchRequest, SubmissionPostRequest, @@ -22,6 +21,7 @@ import { getFirstCompletedRemoteData } from '../shared/operators'; import { URLCombiner } from '../url-combiner/url-combiner'; import { RemoteData } from '../data/remote-data'; import { SubmissionResponse } from './submission-response.model'; +import { RestRequest } from '../data/rest-request.model'; /** * The service handling all submission REST requests diff --git a/src/app/core/submission/vocabularies/models/vocabulary-find-options.model.ts b/src/app/core/submission/vocabularies/models/vocabulary-find-options.model.ts index 977228ea9df..7feacd591bc 100644 --- a/src/app/core/submission/vocabularies/models/vocabulary-find-options.model.ts +++ b/src/app/core/submission/vocabularies/models/vocabulary-find-options.model.ts @@ -1,7 +1,7 @@ import { SortOptions } from '../../../cache/models/sort-options.model'; -import { FindListOptions } from '../../../data/request.models'; import { RequestParam } from '../../../cache/models/request-param.model'; import { isNotEmpty } from '../../../../shared/empty.util'; +import { FindListOptions } from '../../../data/find-list-options.model'; /** * Representing properties used to build a vocabulary find request diff --git a/src/app/core/submission/vocabularies/vocabulary.service.spec.ts b/src/app/core/submission/vocabularies/vocabulary.service.spec.ts index 9f8bec307f2..8f733e01491 100644 --- a/src/app/core/submission/vocabularies/vocabulary.service.spec.ts +++ b/src/app/core/submission/vocabularies/vocabulary.service.spec.ts @@ -16,7 +16,6 @@ import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; -import { RequestEntry } from '../../data/request.reducer'; import { RestResponse } from '../../cache/response.models'; import { VocabularyService } from './vocabulary.service'; import { getMockRequestService } from '../../../shared/mocks/request.service.mock'; @@ -26,6 +25,7 @@ import { VocabularyFindOptions } from './models/vocabulary-find-options.model'; import { HrefOnlyDataService } from '../../data/href-only-data.service'; import { getMockHrefOnlyDataService } from '../../../shared/mocks/href-only-data.service.mock'; import { createPaginatedList } from '../../../shared/testing/utils.test'; +import { RequestEntry } from '../../data/request-entry.model'; describe('VocabularyService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/submission/vocabularies/vocabulary.service.ts b/src/app/core/submission/vocabularies/vocabulary.service.ts index da58512441d..2e7f1911ca7 100644 --- a/src/app/core/submission/vocabularies/vocabulary.service.ts +++ b/src/app/core/submission/vocabularies/vocabulary.service.ts @@ -9,11 +9,9 @@ import { FollowLinkConfig, followLink } from '../../../shared/utils/follow-link- import { dataService } from '../../cache/builders/build-decorators'; import { DataService } from '../../data/data.service'; import { RequestService } from '../../data/request.service'; -import { FindListOptions } from '../../data/request.models'; import { HALEndpointService } from '../../shared/hal-endpoint.service'; import { RemoteData } from '../../data/remote-data'; import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; -import { CoreState } from '../../core.reducers'; import { ObjectCacheService } from '../../cache/object-cache.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { ChangeAnalyzer } from '../../data/change-analyzer'; @@ -33,6 +31,8 @@ import { RequestParam } from '../../cache/models/request-param.model'; import { VocabularyOptions } from './models/vocabulary-options.model'; import { PageInfo } from '../../shared/page-info.model'; import { HrefOnlyDataService } from '../../data/href-only-data.service'; +import { CoreState } from '../../core-state.model'; +import { FindListOptions } from '../../data/find-list-options.model'; /* tslint:disable:max-classes-per-file */ diff --git a/src/app/core/submission/workflowitem-data.service.ts b/src/app/core/submission/workflowitem-data.service.ts index 099cfa8627f..c97426e681d 100644 --- a/src/app/core/submission/workflowitem-data.service.ts +++ b/src/app/core/submission/workflowitem-data.service.ts @@ -4,7 +4,6 @@ import { HttpClient } from '@angular/common/http'; import { Store } from '@ngrx/store'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; -import { CoreState } from '../core.reducers'; import { DataService } from '../data/data.service'; import { RequestService } from '../data/request.service'; import { WorkflowItem } from './models/workflowitem.model'; @@ -19,6 +18,7 @@ import { hasValue } from '../../shared/empty.util'; import { RemoteData } from '../data/remote-data'; import { NoContent } from '../shared/NoContent.model'; import { getFirstCompletedRemoteData } from '../shared/operators'; +import { CoreState } from '../core-state.model'; /** * A service that provides methods to make REST requests with workflow items endpoint. diff --git a/src/app/core/submission/workspaceitem-data.service.ts b/src/app/core/submission/workspaceitem-data.service.ts index 2fc95bdd007..f4a4321b01d 100644 --- a/src/app/core/submission/workspaceitem-data.service.ts +++ b/src/app/core/submission/workspaceitem-data.service.ts @@ -4,7 +4,6 @@ import { HttpClient } from '@angular/common/http'; import { Store } from '@ngrx/store'; import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; -import { CoreState } from '../core.reducers'; import { DataService } from '../data/data.service'; import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -12,6 +11,7 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { ObjectCacheService } from '../cache/object-cache.service'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; import { WorkspaceItem } from './models/workspaceitem.model'; +import { CoreState } from '../core-state.model'; /** * A service that provides methods to make REST requests with workspaceitems endpoint. diff --git a/src/app/core/tasks/claimed-task-data.service.spec.ts b/src/app/core/tasks/claimed-task-data.service.spec.ts index ab9727592e9..722324d94ca 100644 --- a/src/app/core/tasks/claimed-task-data.service.spec.ts +++ b/src/app/core/tasks/claimed-task-data.service.spec.ts @@ -6,15 +6,15 @@ import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; -import { CoreState } from '../core.reducers'; import { ClaimedTaskDataService } from './claimed-task-data.service'; import { of as observableOf } from 'rxjs/internal/observable/of'; -import { FindListOptions } from '../data/request.models'; import { RequestParam } from '../cache/models/request-param.model'; import { getTestScheduler } from 'jasmine-marbles'; import { TestScheduler } from 'rxjs/testing'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; describe('ClaimedTaskDataService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/tasks/claimed-task-data.service.ts b/src/app/core/tasks/claimed-task-data.service.ts index 9cfd5a44d65..3860f848702 100644 --- a/src/app/core/tasks/claimed-task-data.service.ts +++ b/src/app/core/tasks/claimed-task-data.service.ts @@ -7,7 +7,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -16,10 +15,11 @@ import { CLAIMED_TASK } from './models/claimed-task-object.resource-type'; import { ProcessTaskResponse } from './models/process-task-response'; import { TasksService } from './tasks.service'; import { RemoteData } from '../data/remote-data'; -import { FindListOptions } from '../data/request.models'; import { RequestParam } from '../cache/models/request-param.model'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { getFirstSucceededRemoteData } from '../shared/operators'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; /** * The service handling all REST requests for ClaimedTask diff --git a/src/app/core/tasks/pool-task-data.service.spec.ts b/src/app/core/tasks/pool-task-data.service.spec.ts index 7279c96e5c7..d06076009ed 100644 --- a/src/app/core/tasks/pool-task-data.service.spec.ts +++ b/src/app/core/tasks/pool-task-data.service.spec.ts @@ -6,15 +6,15 @@ import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; -import { CoreState } from '../core.reducers'; import { PoolTaskDataService } from './pool-task-data.service'; import { getTestScheduler } from 'jasmine-marbles'; import { TestScheduler } from 'rxjs/testing'; import { of as observableOf } from 'rxjs/internal/observable/of'; -import { FindListOptions } from '../data/request.models'; import { RequestParam } from '../cache/models/request-param.model'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; describe('PoolTaskDataService', () => { let scheduler: TestScheduler; diff --git a/src/app/core/tasks/pool-task-data.service.ts b/src/app/core/tasks/pool-task-data.service.ts index d44e402e7f0..042c9a3455a 100644 --- a/src/app/core/tasks/pool-task-data.service.ts +++ b/src/app/core/tasks/pool-task-data.service.ts @@ -7,7 +7,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s import { dataService } from '../cache/builders/build-decorators'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../cache/object-cache.service'; -import { CoreState } from '../core.reducers'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; import { RequestService } from '../data/request.service'; import { HALEndpointService } from '../shared/hal-endpoint.service'; @@ -15,9 +14,10 @@ import { PoolTask } from './models/pool-task-object.model'; import { POOL_TASK } from './models/pool-task-object.resource-type'; import { TasksService } from './tasks.service'; import { RemoteData } from '../data/remote-data'; -import { FindListOptions } from '../data/request.models'; import { RequestParam } from '../cache/models/request-param.model'; import { getFirstCompletedRemoteData } from '../shared/operators'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; /** * The service handling all REST requests for PoolTask diff --git a/src/app/core/tasks/task-response-parsing.service.ts b/src/app/core/tasks/task-response-parsing.service.ts index 75c40567189..e2e009386fe 100644 --- a/src/app/core/tasks/task-response-parsing.service.ts +++ b/src/app/core/tasks/task-response-parsing.service.ts @@ -1,12 +1,12 @@ import { Injectable } from '@angular/core'; import { ResponseParsingService } from '../data/parsing.service'; -import { RestRequest } from '../data/request.models'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { BaseResponseParsingService } from '../data/base-response-parsing.service'; import { ObjectCacheService } from '../cache/object-cache.service'; import { ParsedResponse } from '../cache/response.models'; +import { RestRequest } from '../data/rest-request.model'; /** * Provides methods to parse response for a task request. diff --git a/src/app/core/tasks/tasks.service.spec.ts b/src/app/core/tasks/tasks.service.spec.ts index f0c86d2abfb..aa267b90769 100644 --- a/src/app/core/tasks/tasks.service.spec.ts +++ b/src/app/core/tasks/tasks.service.spec.ts @@ -4,13 +4,12 @@ import { TestScheduler } from 'rxjs/testing'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { TasksService } from './tasks.service'; import { RequestService } from '../data/request.service'; -import { FindListOptions, TaskDeleteRequest, TaskPostRequest } from '../data/request.models'; +import { TaskDeleteRequest, TaskPostRequest } from '../data/request.models'; import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; import { TaskObject } from './models/task-object.model'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { Store } from '@ngrx/store'; -import { CoreState } from '../core.reducers'; import { ObjectCacheService } from '../cache/object-cache.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { HttpClient, HttpHeaders } from '@angular/common/http'; @@ -22,6 +21,8 @@ import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-build.service.mock'; import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub'; import { of } from 'rxjs'; +import { CoreState } from '../core-state.model'; +import { FindListOptions } from '../data/find-list-options.model'; const LINK_NAME = 'test'; diff --git a/src/app/core/tasks/tasks.service.ts b/src/app/core/tasks/tasks.service.ts index d96e3320f2f..2b76412a9c6 100644 --- a/src/app/core/tasks/tasks.service.ts +++ b/src/app/core/tasks/tasks.service.ts @@ -6,7 +6,6 @@ import { distinctUntilChanged, filter, find, map, mergeMap, tap } from 'rxjs/ope import { DataService } from '../data/data.service'; import { DeleteRequest, - FindListOptions, PostRequest, TaskDeleteRequest, TaskPostRequest @@ -18,6 +17,7 @@ import { getAllCompletedRemoteData, getFirstCompletedRemoteData } from '../share import { RemoteData } from '../data/remote-data'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { CacheableObject } from '../cache/cacheable-object.model'; +import { FindListOptions } from '../data/find-list-options.model'; /** * An abstract class that provides methods to handle task requests. diff --git a/src/app/forgot-password/forgot-password-form/forgot-password-form.component.spec.ts b/src/app/forgot-password/forgot-password-form/forgot-password-form.component.spec.ts index 30048acc6d6..55abd5edd87 100644 --- a/src/app/forgot-password/forgot-password-form/forgot-password-form.component.spec.ts +++ b/src/app/forgot-password/forgot-password-form/forgot-password-form.component.spec.ts @@ -11,12 +11,12 @@ import { Store } from '@ngrx/store'; import { EPersonDataService } from '../../core/eperson/eperson-data.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; -import { CoreState } from '../../core/core.reducers'; import { Registration } from '../../core/shared/registration.model'; import { ForgotPasswordFormComponent } from './forgot-password-form.component'; import { By } from '@angular/platform-browser'; import { AuthenticateAction } from '../../core/auth/auth.actions'; import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; +import { CoreState } from '../../core/core-state.model'; describe('ForgotPasswordFormComponent', () => { let comp: ForgotPasswordFormComponent; diff --git a/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts b/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts index 707c70f19cf..e6e5e5cb06f 100644 --- a/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts +++ b/src/app/forgot-password/forgot-password-form/forgot-password-form.component.ts @@ -8,10 +8,10 @@ import { map } from 'rxjs/operators'; import { ActivatedRoute, Router } from '@angular/router'; import { AuthenticateAction } from '../../core/auth/auth.actions'; import { Store } from '@ngrx/store'; -import { CoreState } from '../../core/core.reducers'; import { RemoteData } from '../../core/data/remote-data'; import { EPerson } from '../../core/eperson/models/eperson.model'; import { getFirstCompletedRemoteData } from '../../core/shared/operators'; +import { CoreState } from '../../core/core-state.model'; @Component({ selector: 'ds-forgot-password-form', diff --git a/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts b/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts index 00408e46966..eb52ca9243e 100644 --- a/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts +++ b/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts @@ -13,7 +13,6 @@ import { buildPaginatedList } from '../../core/data/paginated-list.model'; import { PageInfo } from '../../core/shared/page-info.model'; import { SharedModule } from '../../shared/shared.module'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; -import { FindListOptions } from '../../core/data/request.models'; import { HostWindowService } from '../../shared/host-window.service'; import { HostWindowServiceStub } from '../../shared/testing/host-window-service.stub'; import { CommunityDataService } from '../../core/data/community-data.service'; @@ -25,6 +24,7 @@ import { PaginationService } from '../../core/pagination/pagination.service'; import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { ThemeService } from '../../shared/theme-support/theme.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('TopLevelCommunityList Component', () => { let comp: TopLevelCommunityListComponent; diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.spec.ts index 807d9f83574..133b13cb279 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.spec.ts @@ -19,8 +19,8 @@ import { RequestService } from '../../../../../core/data/request.service'; import { PaginationService } from '../../../../../core/pagination/pagination.service'; import { PaginationComponentOptions } from '../../../../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../../../core/data/request.models'; import { PaginationServiceStub } from '../../../../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../../../../core/data/find-list-options.model'; describe('PaginatedDragAndDropBitstreamListComponent', () => { let comp: PaginatedDragAndDropBitstreamListComponent; diff --git a/src/app/item-page/full/field-components/file-section/full-file-section.component.spec.ts b/src/app/item-page/full/field-components/file-section/full-file-section.component.spec.ts index 9b225632dfe..396e6c32160 100644 --- a/src/app/item-page/full/field-components/file-section/full-file-section.component.spec.ts +++ b/src/app/item-page/full/field-components/file-section/full-file-section.component.spec.ts @@ -18,9 +18,9 @@ import { NotificationsService } from '../../../../shared/notifications/notificat import { NotificationsServiceStub } from '../../../../shared/testing/notifications-service.stub'; import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../../core/data/request.models'; import { PaginationService } from '../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../../../core/data/find-list-options.model'; describe('FullFileSectionComponent', () => { let comp: FullFileSectionComponent; diff --git a/src/app/item-page/simple/related-items/related-items-component.ts b/src/app/item-page/simple/related-items/related-items-component.ts index f752d3589e6..e0d65b9a6dc 100644 --- a/src/app/item-page/simple/related-items/related-items-component.ts +++ b/src/app/item-page/simple/related-items/related-items-component.ts @@ -3,10 +3,10 @@ import { Item } from '../../../core/shared/item.model'; import { Observable } from 'rxjs'; import { RemoteData } from '../../../core/data/remote-data'; import { PaginatedList } from '../../../core/data/paginated-list.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { ViewMode } from '../../../core/shared/view-mode.model'; import { RelationshipService } from '../../../core/data/relationship.service'; import { AbstractIncrementalListComponent } from '../abstract-incremental-list/abstract-incremental-list.component'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; @Component({ selector: 'ds-related-items', diff --git a/src/app/my-dspace-page/collection-selector/collection-selector.component.spec.ts b/src/app/my-dspace-page/collection-selector/collection-selector.component.spec.ts index 53646a27d81..c33d27ec77f 100644 --- a/src/app/my-dspace-page/collection-selector/collection-selector.component.spec.ts +++ b/src/app/my-dspace-page/collection-selector/collection-selector.component.spec.ts @@ -15,13 +15,13 @@ import { CollectionDropdownComponent } from '../../shared/collection-dropdown/co import { Collection } from '../../core/shared/collection.model'; import { RemoteData } from '../../core/data/remote-data'; import { Community } from '../../core/shared/community.model'; -import { FindListOptions } from '../../core/data/request.models'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { PaginatedList } from '../../core/data/paginated-list.model'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; import { CollectionDataService } from '../../core/data/collection-data.service'; import { MockElementRef } from '../../shared/testing/element-ref.mock'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('CollectionSelectorComponent', () => { diff --git a/src/app/my-dspace-page/my-dspace-page.component.spec.ts b/src/app/my-dspace-page/my-dspace-page.component.spec.ts index a7f16d41844..d2d742f9408 100644 --- a/src/app/my-dspace-page/my-dspace-page.component.spec.ts +++ b/src/app/my-dspace-page/my-dspace-page.component.spec.ts @@ -139,7 +139,7 @@ describe('MyDSpacePageComponent', () => { fixture.detectChanges(); searchServiceObject = (comp as any).service; searchConfigurationServiceObject = (comp as any).searchConfigService; - console.log(searchConfigurationServiceObject) + console.log(searchConfigurationServiceObject); }); afterEach(() => { diff --git a/src/app/process-page/overview/process-overview.component.spec.ts b/src/app/process-page/overview/process-overview.component.spec.ts index 98e78f6b36f..4cbd7e34539 100644 --- a/src/app/process-page/overview/process-overview.component.spec.ts +++ b/src/app/process-page/overview/process-overview.component.spec.ts @@ -16,8 +16,8 @@ import { of as observableOf } from 'rxjs'; import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../core/data/request.models'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('ProcessOverviewComponent', () => { let component: ProcessOverviewComponent; diff --git a/src/app/process-page/overview/process-overview.component.ts b/src/app/process-page/overview/process-overview.component.ts index 03fcf27222a..7afcd9cb766 100644 --- a/src/app/process-page/overview/process-overview.component.ts +++ b/src/app/process-page/overview/process-overview.component.ts @@ -4,13 +4,13 @@ import { RemoteData } from '../../core/data/remote-data'; import { PaginatedList } from '../../core/data/paginated-list.model'; import { Process } from '../processes/process.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; -import { FindListOptions } from '../../core/data/request.models'; import { EPersonDataService } from '../../core/eperson/eperson-data.service'; import { getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; import { EPerson } from '../../core/eperson/models/eperson.model'; import { map, switchMap } from 'rxjs/operators'; import { ProcessDataService } from '../../core/data/processes/process-data.service'; import { PaginationService } from '../../core/pagination/pagination.service'; +import { FindListOptions } from '../../core/data/find-list-options.model'; @Component({ selector: 'ds-process-overview', diff --git a/src/app/register-page/create-profile/create-profile.component.spec.ts b/src/app/register-page/create-profile/create-profile.component.spec.ts index 63710442297..06b04995427 100644 --- a/src/app/register-page/create-profile/create-profile.component.spec.ts +++ b/src/app/register-page/create-profile/create-profile.component.spec.ts @@ -12,7 +12,6 @@ import { EPersonDataService } from '../../core/eperson/eperson-data.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { of as observableOf } from 'rxjs'; import { By } from '@angular/platform-browser'; -import { CoreState } from '../../core/core.reducers'; import { EPerson } from '../../core/eperson/models/eperson.model'; import { AuthenticateAction } from '../../core/auth/auth.actions'; import { RouterStub } from '../../shared/testing/router.stub'; @@ -22,6 +21,7 @@ import { EndUserAgreementService } from '../../core/end-user-agreement/end-user-agreement.service'; import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; +import { CoreState } from '../../core/core-state.model'; describe('CreateProfileComponent', () => { let comp: CreateProfileComponent; diff --git a/src/app/register-page/create-profile/create-profile.component.ts b/src/app/register-page/create-profile/create-profile.component.ts index 790e1d6fc5d..8c38e3a5468 100644 --- a/src/app/register-page/create-profile/create-profile.component.ts +++ b/src/app/register-page/create-profile/create-profile.component.ts @@ -9,7 +9,6 @@ import { EPersonDataService } from '../../core/eperson/eperson-data.service'; import { EPerson } from '../../core/eperson/models/eperson.model'; import { LangConfig } from '../../../config/lang-config.interface'; import { Store } from '@ngrx/store'; -import { CoreState } from '../../core/core.reducers'; import { AuthenticateAction } from '../../core/auth/auth.actions'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { environment } from '../../../environments/environment'; @@ -20,6 +19,7 @@ import { EndUserAgreementService } from '../../core/end-user-agreement/end-user-agreement.service'; import { getFirstCompletedRemoteData } from '../../core/shared/operators'; +import { CoreState } from '../../core/core-state.model'; /** * Component that renders the create profile page to be used by a user registering through a token diff --git a/src/app/shared/browse-by/browse-by.component.spec.ts b/src/app/shared/browse-by/browse-by.component.spec.ts index 806f4bdb6f9..e266c613784 100644 --- a/src/app/shared/browse-by/browse-by.component.spec.ts +++ b/src/app/shared/browse-by/browse-by.component.spec.ts @@ -18,9 +18,9 @@ import { PaginationComponentOptions } from '../pagination/pagination-component-o import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; import { storeModuleConfig } from '../../app.reducer'; -import { FindListOptions } from '../../core/data/request.models'; import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('BrowseByComponent', () => { let comp: BrowseByComponent; diff --git a/src/app/shared/collection-dropdown/collection-dropdown.component.spec.ts b/src/app/shared/collection-dropdown/collection-dropdown.component.spec.ts index f08df65ca45..ce90d5d6a74 100644 --- a/src/app/shared/collection-dropdown/collection-dropdown.component.spec.ts +++ b/src/app/shared/collection-dropdown/collection-dropdown.component.spec.ts @@ -18,8 +18,8 @@ import { TranslateLoaderMock } from '../mocks/translate-loader.mock'; import { Community } from '../../core/shared/community.model'; import { MockElementRef } from '../testing/element-ref.mock'; import { FollowLinkConfig } from '../utils/follow-link-config.model'; -import { FindListOptions } from '../../core/data/request.models'; import { Observable } from 'rxjs/internal/Observable'; +import { FindListOptions } from '../../core/data/find-list-options.model'; const community: Community = Object.assign(new Community(), { id: 'ce64f48e-2c9b-411a-ac36-ee429c0e6a88', diff --git a/src/app/shared/collection-dropdown/collection-dropdown.component.ts b/src/app/shared/collection-dropdown/collection-dropdown.component.ts index c91ddbdb0a9..4a5fc705a82 100644 --- a/src/app/shared/collection-dropdown/collection-dropdown.component.ts +++ b/src/app/shared/collection-dropdown/collection-dropdown.component.ts @@ -15,7 +15,6 @@ import { debounceTime, distinctUntilChanged, map, mergeMap, reduce, startWith, s import { hasValue } from '../empty.util'; import { RemoteData } from '../../core/data/remote-data'; -import { FindListOptions } from '../../core/data/request.models'; import { PaginatedList } from '../../core/data/paginated-list.model'; import { Community } from '../../core/shared/community.model'; import { CollectionDataService } from '../../core/data/collection-data.service'; @@ -25,6 +24,7 @@ import { getFirstSucceededRemoteDataPayload, getFirstSucceededRemoteWithNotEmptyData } from '../../core/shared/operators'; +import { FindListOptions } from '../../core/data/find-list-options.model'; /** * An interface to represent a collection entry diff --git a/src/app/shared/log-in/log-in.component.ts b/src/app/shared/log-in/log-in.component.ts index c0df6adec8f..120f3ac4fad 100644 --- a/src/app/shared/log-in/log-in.component.ts +++ b/src/app/shared/log-in/log-in.component.ts @@ -8,12 +8,12 @@ import { isAuthenticated, isAuthenticationLoading } from '../../core/auth/selectors'; -import { CoreState } from '../../core/core.reducers'; import { getForgotPasswordRoute, getRegisterRoute } from '../../app-routing-paths'; import { hasValue } from '../empty.util'; import { AuthService } from '../../core/auth/auth.service'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../../core/data/feature-authorization/feature-id'; +import { CoreState } from '../../core/core-state.model'; /** * /users/sign-in diff --git a/src/app/shared/log-in/methods/password/log-in-password.component.ts b/src/app/shared/log-in/methods/password/log-in-password.component.ts index c72881d3bfc..e4a92ded296 100644 --- a/src/app/shared/log-in/methods/password/log-in-password.component.ts +++ b/src/app/shared/log-in/methods/password/log-in-password.component.ts @@ -7,7 +7,6 @@ import { Observable } from 'rxjs'; import { AuthenticateAction, ResetAuthenticationMessagesAction } from '../../../../core/auth/auth.actions'; import { getAuthenticationError, getAuthenticationInfo, } from '../../../../core/auth/selectors'; -import { CoreState } from '../../../../core/core.reducers'; import { isNotEmpty } from '../../../empty.util'; import { fadeOut } from '../../../animations/fade'; import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; @@ -15,6 +14,7 @@ import { renderAuthMethodFor } from '../log-in.methods-decorator'; import { AuthMethod } from '../../../../core/auth/models/auth.method'; import { AuthService } from '../../../../core/auth/auth.service'; import { HardRedirectService } from '../../../../core/services/hard-redirect.service'; +import { CoreState } from '../../../../core/core-state.model'; /** * /users/sign-in diff --git a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts b/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts index b0704d5cb15..d218a7ca4ed 100644 --- a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts +++ b/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts @@ -7,7 +7,6 @@ import { renderAuthMethodFor } from '../log-in.methods-decorator'; import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; import { AuthMethod } from '../../../../core/auth/models/auth.method'; -import { CoreState } from '../../../../core/core.reducers'; import { isAuthenticated, isAuthenticationLoading } from '../../../../core/auth/selectors'; import { RouteService } from '../../../../core/services/route.service'; import { NativeWindowRef, NativeWindowService } from '../../../../core/services/window.service'; @@ -16,6 +15,7 @@ import { AuthService } from '../../../../core/auth/auth.service'; import { HardRedirectService } from '../../../../core/services/hard-redirect.service'; import { take } from 'rxjs/operators'; import { URLCombiner } from '../../../../core/url-combiner/url-combiner'; +import { CoreState } from '../../../../core/core-state.model'; @Component({ selector: 'ds-log-in-shibboleth', diff --git a/src/app/shared/mocks/remote-data-build.service.mock.ts b/src/app/shared/mocks/remote-data-build.service.mock.ts index 90071f8dc66..7b96c5a67ab 100644 --- a/src/app/shared/mocks/remote-data-build.service.mock.ts +++ b/src/app/shared/mocks/remote-data-build.service.mock.ts @@ -3,10 +3,10 @@ import { map, switchMap } from 'rxjs/operators'; import { RemoteDataBuildService } from '../../core/cache/builders/remote-data-build.service'; import { PaginatedList, buildPaginatedList } from '../../core/data/paginated-list.model'; import { RemoteData } from '../../core/data/remote-data'; -import { RequestEntry } from '../../core/data/request.reducer'; import { PageInfo } from '../../core/shared/page-info.model'; import { hasValue } from '../empty.util'; import { createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; +import { RequestEntry } from '../../core/data/request-entry.model'; export function getMockRemoteDataBuildService(toRemoteDataObservable$?: Observable>, buildList$?: Observable>>): RemoteDataBuildService { return { diff --git a/src/app/shared/mocks/request.service.mock.ts b/src/app/shared/mocks/request.service.mock.ts index 106fa8b6c77..f07aec587e6 100644 --- a/src/app/shared/mocks/request.service.mock.ts +++ b/src/app/shared/mocks/request.service.mock.ts @@ -1,7 +1,7 @@ import {of as observableOf, Observable } from 'rxjs'; import { RequestService } from '../../core/data/request.service'; -import { RequestEntry } from '../../core/data/request.reducer'; import SpyObj = jasmine.SpyObj; +import { RequestEntry } from '../../core/data/request-entry.model'; export function getMockRequestService(requestEntry$: Observable = observableOf(new RequestEntry())): SpyObj { return jasmine.createSpyObj('requestService', { diff --git a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts index 07acf3ea75a..0b5acd343bd 100644 --- a/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts +++ b/src/app/shared/object-detail/my-dspace-result-detail-element/item-detail-preview/item-detail-preview.component.spec.ts @@ -15,7 +15,6 @@ import { DefaultChangeAnalyzer } from '../../../../core/data/default-change-anal import { DSOChangeAnalyzer } from '../../../../core/data/dso-change-analyzer.service'; import { PaginatedList } from '../../../../core/data/paginated-list.model'; import { RemoteData } from '../../../../core/data/remote-data'; -import { FindListOptions } from '../../../../core/data/request.models'; import { Bitstream } from '../../../../core/shared/bitstream.model'; import { FileService } from '../../../../core/shared/file.service'; import { HALEndpointService } from '../../../../core/shared/hal-endpoint.service'; @@ -32,6 +31,7 @@ import { VarDirective } from '../../../utils/var.directive'; import { ItemDetailPreviewFieldComponent } from './item-detail-preview-field/item-detail-preview-field.component'; import { ItemDetailPreviewComponent } from './item-detail-preview.component'; import { createPaginatedList } from '../../../testing/utils.test'; +import { FindListOptions } from '../../../../core/data/find-list-options.model'; function getMockFileService(): FileService { return jasmine.createSpyObj('FileService', { diff --git a/src/app/shared/pagination/pagination.component.spec.ts b/src/app/shared/pagination/pagination.component.spec.ts index cf2d1c13fde..0edab7c662c 100644 --- a/src/app/shared/pagination/pagination.component.spec.ts +++ b/src/app/shared/pagination/pagination.component.spec.ts @@ -32,9 +32,9 @@ import { SortDirection, SortOptions } from '../../core/cache/models/sort-options import { createTestComponent } from '../testing/utils.test'; import { storeModuleConfig } from '../../app.reducer'; import { PaginationService } from '../../core/pagination/pagination.service'; -import { FindListOptions } from '../../core/data/request.models'; import { BehaviorSubject, of as observableOf } from 'rxjs'; import { PaginationServiceStub } from '../testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; function expectPages(fixture: ComponentFixture, pagesDef: string[]): void { const de = fixture.debugElement.query(By.css('.pagination')); diff --git a/src/app/shared/pagination/pagination.utils.ts b/src/app/shared/pagination/pagination.utils.ts index 5701c96b54c..f70a3d1030b 100644 --- a/src/app/shared/pagination/pagination.utils.ts +++ b/src/app/shared/pagination/pagination.utils.ts @@ -1,5 +1,5 @@ import { PaginationComponentOptions } from './pagination-component-options.model'; -import { FindListOptions } from '../../core/data/request.models'; +import { FindListOptions } from '../../core/data/find-list-options.model'; /** * Transform a PaginationComponentOptions object into a FindListOptions object diff --git a/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.spec.ts b/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.spec.ts index 73aaab5170b..91d9200c2da 100644 --- a/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.spec.ts +++ b/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.spec.ts @@ -20,9 +20,9 @@ import { buildPaginatedList } from '../../../../core/data/paginated-list.model'; import { PageInfo } from '../../../../core/shared/page-info.model'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { SortDirection, SortOptions } from '../../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../../core/data/request.models'; import { PaginationService } from '../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../testing/pagination-service.stub'; +import { FindListOptions } from '../../../../core/data/find-list-options.model'; describe('EpersonGroupListComponent test suite', () => { let comp: EpersonGroupListComponent; diff --git a/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.ts b/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.ts index 11b5b5e7b36..3277f724a22 100644 --- a/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.ts +++ b/src/app/shared/resource-policies/form/eperson-group-list/eperson-group-list.component.ts @@ -10,7 +10,6 @@ import { DSpaceObject } from '../../../../core/shared/dspace-object.model'; import { PaginationComponentOptions } from '../../../pagination/pagination-component-options.model'; import { DataService } from '../../../../core/data/data.service'; import { hasValue, isNotEmpty } from '../../../empty.util'; -import { FindListOptions } from '../../../../core/data/request.models'; import { DSONameService } from '../../../../core/breadcrumbs/dso-name.service'; import { getDataServiceFor } from '../../../../core/cache/builders/build-decorators'; import { EPERSON } from '../../../../core/eperson/models/eperson.resource-type'; @@ -21,6 +20,7 @@ import { GroupDataService } from '../../../../core/eperson/group-data.service'; import { fadeInOut } from '../../../animations/fade'; import { getFirstCompletedRemoteData } from '../../../../core/shared/operators'; import { PaginationService } from '../../../../core/pagination/pagination.service'; +import { FindListOptions } from '../../../../core/data/find-list-options.model'; export interface SearchEvent { scope: string; diff --git a/src/app/shared/search-form/search-form.component.spec.ts b/src/app/shared/search-form/search-form.component.spec.ts index 1469eac5663..77b51d813d8 100644 --- a/src/app/shared/search-form/search-form.component.spec.ts +++ b/src/app/shared/search-form/search-form.component.spec.ts @@ -10,11 +10,11 @@ import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { SearchService } from '../../core/shared/search/search.service'; import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../core/data/request.models'; import { of as observableOf } from 'rxjs'; import { PaginationService } from '../../core/pagination/pagination.service'; import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; import { PaginationServiceStub } from '../testing/pagination-service.stub'; +import { FindListOptions } from '../../core/data/find-list-options.model'; describe('SearchFormComponent', () => { let comp: SearchFormComponent; diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts index 7299a39c325..59b14776a28 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-option/search-facet-option.component.spec.ts @@ -17,9 +17,9 @@ import { SearchFilterConfig } from '../../../../search-filter-config.model'; import { SearchFacetOptionComponent } from './search-facet-option.component'; import { PaginationComponentOptions } from '../../../../../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../../../../core/data/request.models'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../../../testing/pagination-service.stub'; +import { FindListOptions } from '../../../../../../core/data/find-list-options.model'; describe('SearchFacetOptionComponent', () => { let comp: SearchFacetOptionComponent; diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts index 9ed8dee0ea6..324773192fe 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-range-option/search-facet-range-option.component.spec.ts @@ -21,9 +21,9 @@ import { } from '../../search-range-filter/search-range-filter.component'; import { PaginationComponentOptions } from '../../../../../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../../../../core/data/request.models'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../../../testing/pagination-service.stub'; +import { FindListOptions } from '../../../../../../core/data/find-list-options.model'; describe('SearchFacetRangeOptionComponent', () => { let comp: SearchFacetRangeOptionComponent; diff --git a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts index 8f422b41bff..2fb9b67fcac 100644 --- a/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-facet-filter-options/search-facet-selected-option/search-facet-selected-option.component.spec.ts @@ -16,9 +16,9 @@ import { SearchFilterConfig } from '../../../../search-filter-config.model'; import { SearchFacetSelectedOptionComponent } from './search-facet-selected-option.component'; import { PaginationComponentOptions } from '../../../../../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../../../../core/data/request.models'; import { PaginationService } from '../../../../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../../../../testing/pagination-service.stub'; +import { FindListOptions } from '../../../../../../core/data/find-list-options.model'; describe('SearchFacetSelectedOptionComponent', () => { let comp: SearchFacetSelectedOptionComponent; diff --git a/src/app/shared/search/search-labels/search-label/search-label.component.spec.ts b/src/app/shared/search/search-labels/search-label/search-label.component.spec.ts index b3f9471cbdb..50bcbc69381 100644 --- a/src/app/shared/search/search-labels/search-label/search-label.component.spec.ts +++ b/src/app/shared/search/search-labels/search-label/search-label.component.spec.ts @@ -13,10 +13,10 @@ import { SearchConfigurationServiceStub } from '../../../testing/search-configur import { SearchService } from '../../../../core/shared/search/search.service'; import { PaginationComponentOptions } from '../../../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../../core/data/request.models'; import { PaginationService } from '../../../../core/pagination/pagination.service'; import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { PaginationServiceStub } from '../../../testing/pagination-service.stub'; +import { FindListOptions } from '../../../../core/data/find-list-options.model'; describe('SearchLabelComponent', () => { let comp: SearchLabelComponent; diff --git a/src/app/shared/starts-with/date/starts-with-date.component.spec.ts b/src/app/shared/starts-with/date/starts-with-date.component.spec.ts index dfee88c9550..138f8d43ac3 100644 --- a/src/app/shared/starts-with/date/starts-with-date.component.spec.ts +++ b/src/app/shared/starts-with/date/starts-with-date.component.spec.ts @@ -13,9 +13,9 @@ import { EnumKeysPipe } from '../../utils/enum-keys-pipe'; import { RouterStub } from '../../testing/router.stub'; import { PaginationComponentOptions } from '../../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../testing/pagination-service.stub'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; describe('StartsWithDateComponent', () => { let comp: StartsWithDateComponent; diff --git a/src/app/shared/starts-with/text/starts-with-text.component.spec.ts b/src/app/shared/starts-with/text/starts-with-text.component.spec.ts index 9f9d9d6d426..f8715e6ebfd 100644 --- a/src/app/shared/starts-with/text/starts-with-text.component.spec.ts +++ b/src/app/shared/starts-with/text/starts-with-text.component.spec.ts @@ -10,10 +10,10 @@ import { By } from '@angular/platform-browser'; import { StartsWithTextComponent } from './starts-with-text.component'; import { PaginationComponentOptions } from '../../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { of as observableOf } from 'rxjs'; import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../testing/pagination-service.stub'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; describe('StartsWithTextComponent', () => { let comp: StartsWithTextComponent; diff --git a/src/app/shared/testing/pagination-service.stub.ts b/src/app/shared/testing/pagination-service.stub.ts index 985a5bfc4a8..3ea8e732c8f 100644 --- a/src/app/shared/testing/pagination-service.stub.ts +++ b/src/app/shared/testing/pagination-service.stub.ts @@ -1,7 +1,7 @@ import { of as observableOf } from 'rxjs'; import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; -import { FindListOptions } from '../../core/data/request.models'; +import { FindListOptions } from '../../core/data/find-list-options.model'; export class PaginationServiceStub { diff --git a/src/app/shared/testing/submission-rest-service.stub.ts b/src/app/shared/testing/submission-rest-service.stub.ts index 53b2341b507..b6ec9a86a2a 100644 --- a/src/app/shared/testing/submission-rest-service.stub.ts +++ b/src/app/shared/testing/submission-rest-service.stub.ts @@ -2,8 +2,8 @@ import { of as observableOf } from 'rxjs'; import { Store } from '@ngrx/store'; import { RequestService } from '../../core/data/request.service'; -import { CoreState } from '../../core/core.reducers'; import { HALEndpointService } from '../../core/shared/hal-endpoint.service'; +import { CoreState } from '../../core/core-state.model'; export class SubmissionRestServiceStub { protected linkPath = 'workspaceitems'; diff --git a/src/app/shared/testing/utils.test.ts b/src/app/shared/testing/utils.test.ts index 1e62ee8f004..2f3b85d7911 100644 --- a/src/app/shared/testing/utils.test.ts +++ b/src/app/shared/testing/utils.test.ts @@ -2,10 +2,10 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model'; import { PageInfo } from '../../core/shared/page-info.model'; import { Observable } from 'rxjs/internal/Observable'; -import { RequestEntry} from '../../core/data/request.reducer'; import { of as observableOf } from 'rxjs/internal/observable/of'; import { UnCacheableObject } from '../../core/shared/uncacheable-object.model'; import { RequestEntryState } from '../../core/data/request-entry-state.model'; +import { RequestEntry } from '../../core/data/request-entry.model'; /** * Returns true if a Native Element has a specified css class. diff --git a/src/app/shared/utils/follow-link-config.model.ts b/src/app/shared/utils/follow-link-config.model.ts index 08153e1217b..8d785dbaaf5 100644 --- a/src/app/shared/utils/follow-link-config.model.ts +++ b/src/app/shared/utils/follow-link-config.model.ts @@ -1,6 +1,6 @@ -import { FindListOptions } from '../../core/data/request.models'; import { HALResource } from '../../core/shared/hal-resource.model'; import { hasValue } from '../empty.util'; +import { FindListOptions } from '../../core/data/find-list-options.model'; /** * A class to send the retrieval of a {@link HALLink} diff --git a/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.ts b/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.ts index 41ba7751716..48c60e005cc 100644 --- a/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.ts +++ b/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.ts @@ -10,7 +10,6 @@ import { TranslateService } from '@ngx-translate/core'; import { VocabularyEntryDetail } from '../../core/submission/vocabularies/models/vocabulary-entry-detail.model'; import { hasValue, isEmpty, isNotEmpty } from '../empty.util'; import { isAuthenticated } from '../../core/auth/selectors'; -import { CoreState } from '../../core/core.reducers'; import { VocabularyTreeviewService } from './vocabulary-treeview.service'; import { LOAD_MORE, LOAD_MORE_ROOT, TreeviewFlatNode, TreeviewNode } from './vocabulary-treeview-node.model'; import { VocabularyOptions } from '../../core/submission/vocabularies/models/vocabulary-options.model'; @@ -18,6 +17,7 @@ import { PageInfo } from '../../core/shared/page-info.model'; import { VocabularyEntry } from '../../core/submission/vocabularies/models/vocabulary-entry.model'; import { VocabularyTreeFlattener } from './vocabulary-tree-flattener'; import { VocabularyTreeFlatDataSource } from './vocabulary-tree-flat-data-source'; +import { CoreState } from '../../core/core-state.model'; /** * Component that show a hierarchical vocabulary in a tree view diff --git a/src/app/statistics/statistics.service.spec.ts b/src/app/statistics/statistics.service.spec.ts index cdf81afdb6d..347d3afb5ed 100644 --- a/src/app/statistics/statistics.service.spec.ts +++ b/src/app/statistics/statistics.service.spec.ts @@ -2,10 +2,10 @@ import { StatisticsService } from './statistics.service'; import { RequestService } from '../core/data/request.service'; import { HALEndpointServiceStub } from '../shared/testing/hal-endpoint-service.stub'; import { getMockRequestService } from '../shared/mocks/request.service.mock'; -import { TrackRequest } from './track-request.model'; import { isEqual } from 'lodash'; import { DSpaceObjectType } from '../core/shared/dspace-object-type.model'; import { SearchOptions } from '../shared/search/search-options.model'; +import { RestRequest } from '../core/data/rest-request.model'; describe('StatisticsService', () => { let service: StatisticsService; @@ -27,7 +27,7 @@ describe('StatisticsService', () => { it('should send a request to track an item view ', () => { const mockItem: any = {uuid: 'mock-item-uuid', type: 'item'}; service.trackViewEvent(mockItem); - const request: TrackRequest = requestService.send.calls.mostRecent().args[0]; + const request: RestRequest = requestService.send.calls.mostRecent().args[0]; expect(request.body).toBeDefined('request.body'); const body = JSON.parse(request.body); expect(body.targetId).toBe('mock-item-uuid'); @@ -51,7 +51,7 @@ describe('StatisticsService', () => { }; const sort = {by: 'search-field', order: 'ASC'}; service.trackSearchEvent(mockSearch, page, sort); - const request: TrackRequest = requestService.send.calls.mostRecent().args[0]; + const request: RestRequest = requestService.send.calls.mostRecent().args[0]; const body = JSON.parse(request.body); it('should specify the right query', () => { @@ -108,7 +108,7 @@ describe('StatisticsService', () => { } ]; service.trackSearchEvent(mockSearch, page, sort, filters); - const request: TrackRequest = requestService.send.calls.mostRecent().args[0]; + const request: RestRequest = requestService.send.calls.mostRecent().args[0]; const body = JSON.parse(request.body); it('should specify the dsoType', () => { diff --git a/src/app/statistics/statistics.service.ts b/src/app/statistics/statistics.service.ts index 9e12e627b57..0031773f766 100644 --- a/src/app/statistics/statistics.service.ts +++ b/src/app/statistics/statistics.service.ts @@ -5,8 +5,8 @@ import { map, take } from 'rxjs/operators'; import { TrackRequest } from './track-request.model'; import { hasValue, isNotEmpty } from '../shared/empty.util'; import { HALEndpointService } from '../core/shared/hal-endpoint.service'; -import { RestRequest } from '../core/data/request.models'; import { SearchOptions } from '../shared/search/search-options.model'; +import { RestRequest } from '../core/data/rest-request.model'; /** * The statistics service diff --git a/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.spec.ts b/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.spec.ts index 983e0355afa..08b746ebdca 100644 --- a/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.spec.ts +++ b/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.spec.ts @@ -18,11 +18,11 @@ import { PageInfo } from '../../../core/shared/page-info.model'; import { PaginatedList, buildPaginatedList } from '../../../core/data/paginated-list.model'; import { createSuccessfulRemoteDataObject } from '../../../shared/remote-data.utils'; import { ExternalSource } from '../../../core/shared/external-source.model'; -import { FindListOptions } from '../../../core/data/request.models'; import { HostWindowService } from '../../../shared/host-window.service'; import { HostWindowServiceStub } from '../../../shared/testing/host-window-service.stub'; import { getTestScheduler } from 'jasmine-marbles'; import { TestScheduler } from 'rxjs/testing'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; describe('SubmissionImportExternalSearchbarComponent test suite', () => { let comp: SubmissionImportExternalSearchbarComponent; diff --git a/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.ts b/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.ts index 30f5184d578..0f1128243aa 100644 --- a/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.ts +++ b/src/app/submission/import-external/import-external-searchbar/submission-import-external-searchbar.component.ts @@ -17,10 +17,10 @@ import { PaginatedList, buildPaginatedList } from '../../../core/data/paginated- import { RemoteData } from '../../../core/data/remote-data'; import { PageInfo } from '../../../core/shared/page-info.model'; import { createSuccessfulRemoteDataObject } from '../../../shared/remote-data.utils'; -import { FindListOptions } from '../../../core/data/request.models'; import { getFirstSucceededRemoteData, getFirstSucceededRemoteDataPayload } from '../../../core/shared/operators'; import { HostWindowService } from '../../../shared/host-window.service'; import { hasValue } from '../../../shared/empty.util'; +import { FindListOptions } from '../../../core/data/find-list-options.model'; /** * Interface for the selected external source element. From 41ad1727963b6e4ef70d36e7dfc939fc9a79d2a8 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Tue, 22 Mar 2022 14:00:55 +0100 Subject: [PATCH 0099/2129] add github actions check for circular dependencies --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6f4a11acc8d..c08299c584d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -78,6 +78,9 @@ jobs: - name: Run lint run: yarn run lint + - name: Check for circular dependencies + run: npx madge --exclude '(bitstream|bundle|collection|config-submission-form|eperson|item|version)\.model\.ts$' --circular --extensions ts ./ + - name: Run build run: yarn run build:prod From c5110f89bc17290b6e224f9366cfa14dfa431d58 Mon Sep 17 00:00:00 2001 From: reetagithub <51482276+reetagithub@users.noreply.github.com> Date: Thu, 24 Mar 2022 11:18:18 +0200 Subject: [PATCH 0100/2129] Update fi.json5 Modified some keys to harmonize the translations of term 'administrative'. Also, translated "Administer Workflow" to a verb instead of a noun. --- src/assets/i18n/fi.json5 | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/assets/i18n/fi.json5 b/src/assets/i18n/fi.json5 index 02f020a45d1..860062fa67c 100644 --- a/src/assets/i18n/fi.json5 +++ b/src/assets/i18n/fi.json5 @@ -107,7 +107,7 @@ "admin.registries.bitstream-formats.edit.head": "Tiedostoformaatti: {{ format }}", // "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.", - "admin.registries.bitstream-formats.edit.internal.hint": "Sisäisiksi merkittyjä formaatteja käytetään hallinnollisiin tarkoituksiin, ja ne on piilotettu käyttäjiltä.", + "admin.registries.bitstream-formats.edit.internal.hint": "Sisäisiksi merkittyjä formaatteja käytetään ylläpitotarkoituksiin, ja ne on piilotettu käyttäjiltä.", // "admin.registries.bitstream-formats.edit.internal.label": "Internal", "admin.registries.bitstream-formats.edit.internal.label": "Sisäinen", @@ -662,7 +662,7 @@ // "admin.search.breadcrumbs": "Administrative Search", - "admin.search.breadcrumbs": "Hallinnollinen haku", + "admin.search.breadcrumbs": "Ylläpitäjän haku", // "admin.search.collection.edit": "Edit", "admin.search.collection.edit": "Muokkaa", @@ -692,19 +692,19 @@ "admin.search.item.withdraw": "Poista käytöstä", // "admin.search.title": "Administrative Search", - "admin.search.title": "Hallinnollinen haku", + "admin.search.title": "Ylläpitäjän haku", // "administrativeView.search.results.head": "Administrative Search", - "administrativeView.search.results.head": "Hallinnollinen haku", + "administrativeView.search.results.head": "Ylläpitäjän haku", // "admin.workflow.breadcrumbs": "Administer Workflow", - "admin.workflow.breadcrumbs": "Hallinnointityönkulku", + "admin.workflow.breadcrumbs": "Hallinnoi työnkulkua", // "admin.workflow.title": "Administer Workflow", - "admin.workflow.title": "Hallinnointityönkulku", + "admin.workflow.title": "Hallinnoi työnkulkua", // "admin.workflow.item.workflow": "Workflow", "admin.workflow.item.workflow": "Työnkulku", @@ -2954,7 +2954,7 @@ // "menu.section.admin_search": "Admin Search", - "menu.section.admin_search": "Admin-haku", + "menu.section.admin_search": "Ylläpitäjän haku", @@ -3033,7 +3033,7 @@ "menu.section.icon.access_control": "Pääsyoikeudet", // "menu.section.icon.admin_search": "Admin search menu section", - "menu.section.icon.admin_search": "Admin-haku", + "menu.section.icon.admin_search": "Ylläpitäjän haku", // "menu.section.icon.control_panel": "Control Panel menu section", "menu.section.icon.control_panel": "Hallintapaneeli", @@ -3168,7 +3168,7 @@ // "menu.section.workflow": "Administer Workflow", - "menu.section.workflow": "Hallinnointityönkulku", + "menu.section.workflow": "Hallinnoi työnkulkua", // "mydspace.description": "", @@ -5079,7 +5079,7 @@ // "workflowAdmin.search.results.head": "Administer Workflow", - "workflowAdmin.search.results.head": "Hallinnointityönkulku", + "workflowAdmin.search.results.head": "Hallinnoi työnkulkua", From 521e4ddb8de450841698102f17131f6364bd9c45 Mon Sep 17 00:00:00 2001 From: Marie Verdonck Date: Thu, 24 Mar 2022 11:42:04 +0100 Subject: [PATCH 0101/2129] 88248: Theming alert --- src/app/shared/alert/alert.component.html | 2 +- src/app/shared/item/item-alerts/item-alerts.component.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/shared/alert/alert.component.html b/src/app/shared/alert/alert.component.html index 0b30edb5cc9..3bc4782a779 100644 --- a/src/app/shared/alert/alert.component.html +++ b/src/app/shared/alert/alert.component.html @@ -1,4 +1,4 @@ - diff --git a/src/app/submission/sections/sherpa-policies/publication-information/publication-information.component.html b/src/app/submission/sections/sherpa-policies/publication-information/publication-information.component.html index 2e6da459aeb..079535b2fb7 100644 --- a/src/app/submission/sections/sherpa-policies/publication-information/publication-information.component.html +++ b/src/app/submission/sections/sherpa-policies/publication-information/publication-information.component.html @@ -1,8 +1,7 @@
-

{{'submission.sections.sherpa.publication.information.title' - | translate}}

+

{{'submission.sections.sherpa.publication.information.title' | translate}}

{{title}} @@ -11,8 +10,7 @@

-

{{'submission.sections.sherpa.publication.information.issns' - | translate}}

+

{{'submission.sections.sherpa.publication.information.issns' | translate}}

{{issn}} @@ -21,12 +19,11 @@

-

{{'submission.sections.sherpa.publication.information.url' - | translate}}

+

{{'submission.sections.sherpa.publication.information.url' | translate}}

- + {{journal.url}}

@@ -34,12 +31,11 @@
-

{{'submission.sections.sherpa.publication.information.publishers' - | translate}}

+

{{'submission.sections.sherpa.publication.information.publishers' | translate}}

- + {{publisher.name}}

@@ -47,8 +43,7 @@
-

{{'submission.sections.sherpa.publication.information.romeoPub' - | translate}}

+

{{'submission.sections.sherpa.publication.information.romeoPub' | translate}}

@@ -58,8 +53,7 @@

-

{{'submission.sections.sherpa.publication.information.zetoPub' - | translate}}

+

{{'submission.sections.sherpa.publication.information.zetoPub' | translate}}

@@ -67,4 +61,4 @@

-
\ No newline at end of file +
diff --git a/src/app/submission/sections/sherpa-policies/publisher-policy/publisher-policy.component.html b/src/app/submission/sections/sherpa-policies/publisher-policy/publisher-policy.component.html index 4a03bae735f..ada6613aa2c 100644 --- a/src/app/submission/sections/sherpa-policies/publisher-policy/publisher-policy.component.html +++ b/src/app/submission/sections/sherpa-policies/publisher-policy/publisher-policy.component.html @@ -15,9 +15,9 @@

-
\ No newline at end of file +
From aa7ceec15aaa331335a67e6d595c075d14918c25 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Fri, 29 Apr 2022 19:15:40 +0200 Subject: [PATCH 0309/2129] [CST-5738] Fix retrieving of embed from auth status model --- src/app/core/auth/auth-request.service.ts | 19 +++++++++++-------- src/app/core/auth/auth.service.ts | 3 ++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/app/core/auth/auth-request.service.ts b/src/app/core/auth/auth-request.service.ts index 516502ca6e2..d0fec5fa716 100644 --- a/src/app/core/auth/auth-request.service.ts +++ b/src/app/core/auth/auth-request.service.ts @@ -12,6 +12,7 @@ import { AuthStatus } from './models/auth-status.model'; import { ShortLivedToken } from './models/short-lived-token.model'; import { URLCombiner } from '../url-combiner/url-combiner'; import { RestRequest } from '../data/rest-request.model'; +import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; /** * Abstract service to send authentication requests @@ -26,16 +27,18 @@ export abstract class AuthRequestService { ) { } - protected fetchRequest(request: RestRequest): Observable> { - return this.rdbService.buildFromRequestUUID(request.uuid).pipe( + protected fetchRequest(request: RestRequest, ...linksToFollow: FollowLinkConfig[]): Observable> { + return this.rdbService.buildFromRequestUUID(request.uuid, ...linksToFollow).pipe( getFirstCompletedRemoteData(), ); } - protected getEndpointByMethod(endpoint: string, method: string, embed = false): string { + protected getEndpointByMethod(endpoint: string, method: string, ...linksToFollow: FollowLinkConfig[]): string { let url = isNotEmpty(method) ? `${endpoint}/${method}` : `${endpoint}`; - if (embed) { - url += '?embed=specialGroups'; + if (linksToFollow && linksToFollow.length > 0) { + linksToFollow.forEach((link: FollowLinkConfig, index: number) => { + url += ((index === 0) ? '?' : '&') + `embed=${link.name}`; + }); } return url; @@ -52,14 +55,14 @@ export abstract class AuthRequestService { distinctUntilChanged()); } - public getRequest(method: string, options?: HttpOptions, embed = false): Observable> { + public getRequest(method: string, options?: HttpOptions, ...linksToFollow: FollowLinkConfig[]): Observable> { return this.halService.getEndpoint(this.linkName).pipe( filter((href: string) => isNotEmpty(href)), - map((endpointURL) => this.getEndpointByMethod(endpointURL, method)), + map((endpointURL) => this.getEndpointByMethod(endpointURL, method, ...linksToFollow)), distinctUntilChanged(), map((endpointURL: string) => new GetRequest(this.requestService.generateRequestId(), endpointURL, undefined, options)), tap((request: GetRequest) => this.requestService.send(request)), - mergeMap((request: GetRequest) => this.fetchRequest(request)), + mergeMap((request: GetRequest) => this.fetchRequest(request, ...linksToFollow)), distinctUntilChanged()); } diff --git a/src/app/core/auth/auth.service.ts b/src/app/core/auth/auth.service.ts index 2d2c61490c3..7796094e397 100644 --- a/src/app/core/auth/auth.service.ts +++ b/src/app/core/auth/auth.service.ts @@ -55,6 +55,7 @@ import { buildPaginatedList, PaginatedList } from '../data/paginated-list.model' import { Group } from '../eperson/models/group.model'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { PageInfo } from '../shared/page-info.model'; +import { followLink } from '../../shared/utils/follow-link-config.model'; export const LOGIN_ROUTE = '/login'; export const LOGOUT_ROUTE = '/logout'; @@ -219,7 +220,7 @@ export class AuthService { * Return the special groups list embedded in the AuthStatus model */ public getSpecialGroupsFromAuthStatus(): Observable>> { - return this.authRequestService.getRequest('status', null, true).pipe( + return this.authRequestService.getRequest('status', null, followLink('specialGroups')).pipe( getFirstCompletedRemoteData(), switchMap((status: RemoteData) => { if (status.hasSucceeded) { From 5fd692ce1bb46f918fc2e567bbc606c5719fe64b Mon Sep 17 00:00:00 2001 From: myrza1 Date: Sun, 1 May 2022 02:07:01 +0600 Subject: [PATCH 0310/2129] Update kz.json5 translated all --- src/assets/i18n/kz.json5 | 710 +++++++++++++-------------------------- 1 file changed, 231 insertions(+), 479 deletions(-) diff --git a/src/assets/i18n/kz.json5 b/src/assets/i18n/kz.json5 index fd611712e6a..a35a88de0be 100644 --- a/src/assets/i18n/kz.json5 +++ b/src/assets/i18n/kz.json5 @@ -30,959 +30,711 @@ "404.page-not-found": "Бұл бет табылмады", // "admin.curation-tasks.breadcrumbs": "System curation tasks", - // TODO New key - Add a translation - "admin.curation-tasks.breadcrumbs": "System curation tasks", + "admin.curation-tasks.breadcrumbs": "Тапсырмаларға жетекшілік ету жүйесі", // "admin.curation-tasks.title": "System curation tasks", - // TODO New key - Add a translation - "admin.curation-tasks.title": "System curation tasks", + "admin.curation-tasks.title": "Тапсырмаларға жетекшілік ету жүйесі", // "admin.curation-tasks.header": "System curation tasks", - // TODO New key - Add a translation - "admin.curation-tasks.header": "System curation tasks", + "admin.curation-tasks.header": "Тапсырмаларға жетекшілік ету жүйесі", // "admin.registries.bitstream-formats.breadcrumbs": "Format registry", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.breadcrumbs": "Format registry", + "admin.registries.bitstream-formats.breadcrumbs": "Тізілім форматы", // "admin.registries.bitstream-formats.create.breadcrumbs": "Bitstream format", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.create.breadcrumbs": "Bitstream format", + "admin.registries.bitstream-formats.create.breadcrumbs": "Бит ағынының форматы", // "admin.registries.bitstream-formats.create.failure.content": "An error occurred while creating the new bitstream format.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.create.failure.content": "An error occurred while creating the new bitstream format.", + "admin.registries.bitstream-formats.create.failure.content": "Бит ағынының жаңа форматын құру қатесі.", // "admin.registries.bitstream-formats.create.failure.head": "Failure", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.create.failure.head": "Failure", + "admin.registries.bitstream-formats.create.failure.head": "Ақау", // "admin.registries.bitstream-formats.create.head": "Create Bitstream format", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.create.head": "Create Bitstream format", + "admin.registries.bitstream-formats.create.head": "Бит ағынының форматын жасау", // "admin.registries.bitstream-formats.create.new": "Add a new bitstream format", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.create.new": "Add a new bitstream format", + "admin.registries.bitstream-formats.create.new": "Бит ағынының жаңа форматын қосыңыз", // "admin.registries.bitstream-formats.create.success.content": "The new bitstream format was successfully created.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.create.success.content": "The new bitstream format was successfully created.", + "admin.registries.bitstream-formats.create.success.content": "Жаңа бит ағынының форматы сәтті жасалды.", // "admin.registries.bitstream-formats.create.success.head": "Success", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.create.success.head": "Success", + "admin.registries.bitstream-formats.create.success.head": "Сәтті", // "admin.registries.bitstream-formats.delete.failure.amount": "Failed to remove {{ amount }} format(s)", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.delete.failure.amount": "Failed to remove {{ amount }} format(s)", + "admin.registries.bitstream-formats.delete.failure.amount": "{{ amount }} пішімін (лерін) жою мүмкін емес", // "admin.registries.bitstream-formats.delete.failure.head": "Failure", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.delete.failure.head": "Failure", + "admin.registries.bitstream-formats.delete.failure.head": "Сәтсіздік", // "admin.registries.bitstream-formats.delete.success.amount": "Successfully removed {{ amount }} format(s)", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.delete.success.amount": "Successfully removed {{ amount }} format(s)", + "admin.registries.bitstream-formats.delete.success.amount":"{{ amount }} пішімі (лері) сәтті жойылды", // "admin.registries.bitstream-formats.delete.success.head": "Success", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.delete.success.head": "Success", + "admin.registries.bitstream-formats.delete.success.head": "Сәтті", // "admin.registries.bitstream-formats.description": "This list of bitstream formats provides information about known formats and their support level.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.description": "This list of bitstream formats provides information about known formats and their support level.", + "admin.registries.bitstream-formats.description": "Бит ағынының форматтарының бұл тізімінде белгілі форматтар және оларды қолдау деңгейі туралы ақпарат бар.", // "admin.registries.bitstream-formats.edit.breadcrumbs": "Bitstream format", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.breadcrumbs": "Bitstream format", + "admin.registries.bitstream-formats.edit.breadcrumbs": "Бит ағынының форматы", // "admin.registries.bitstream-formats.edit.description.hint": "", - // TODO New key - Add a translation "admin.registries.bitstream-formats.edit.description.hint": "", // "admin.registries.bitstream-formats.edit.description.label": "Description", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.description.label": "Description", + "admin.registries.bitstream-formats.edit.description.label": "Сипаттама", // "admin.registries.bitstream-formats.edit.extensions.hint": "Extensions are file extensions that are used to automatically identify the format of uploaded files. You can enter several extensions for each format.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.extensions.hint": "Extensions are file extensions that are used to automatically identify the format of uploaded files. You can enter several extensions for each format.", + "admin.registries.bitstream-formats.edit.extensions.hint": "Кеңейтімдер-бұл жүктелетін файл пішімін автоматты түрде анықтау үшін қолданылатын файл кеңейтімдері. Әр формат үшін бірнеше кеңейтімдерді енгізуге болады.", // "admin.registries.bitstream-formats.edit.extensions.label": "File extensions", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.extensions.label": "File extensions", + "admin.registries.bitstream-formats.edit.extensions.label": "Файл кеңейтімдері", // "admin.registries.bitstream-formats.edit.extensions.placeholder": "Enter a file extension without the dot", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.extensions.placeholder": "Enter a file extension without the dot", + "admin.registries.bitstream-formats.edit.extensions.placeholder": "Файл кеңейтімін нүктесіз енгізіңіз", // "admin.registries.bitstream-formats.edit.failure.content": "An error occurred while editing the bitstream format.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.failure.content": "An error occurred while editing the bitstream format.", + "admin.registries.bitstream-formats.edit.failure.content": "Бит ағынының форматын өңдеу кезінде қате пайда болды.", // "admin.registries.bitstream-formats.edit.failure.head": "Failure", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.failure.head": "Failure", + "admin.registries.bitstream-formats.edit.failure.head": "Сәтсіздік", // "admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.head": "Bitstream format: {{ format }}", + "admin.registries.bitstream-formats.edit.head": "Бит ағынының пішімі: {{ format }}", // "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.internal.hint": "Formats marked as internal are hidden from the user, and used for administrative purposes.", + "admin.registries.bitstream-formats.edit.internal.hint": "Ішкі деп белгіленген форматтар қолданушыдан жасырылған және әкімшілік мақсатта қолданылады", // "admin.registries.bitstream-formats.edit.internal.label": "Internal", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.internal.label": "Internal", + "admin.registries.bitstream-formats.edit.internal.label": "Ішкі", // "admin.registries.bitstream-formats.edit.mimetype.hint": "The MIME type associated with this format, does not have to be unique.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.mimetype.hint": "The MIME type associated with this format, does not have to be unique.", + "admin.registries.bitstream-formats.edit.mimetype.hint": "Осы форматпен байланысты MIME түрі ерекше болуы міндетті емес.", // "admin.registries.bitstream-formats.edit.mimetype.label": "MIME Type", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.mimetype.label": "MIME Type", + "admin.registries.bitstream-formats.edit.mimetype.label": "Пантомима түрі", // "admin.registries.bitstream-formats.edit.shortDescription.hint": "A unique name for this format, (e.g. Microsoft Word XP or Microsoft Word 2000)", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.shortDescription.hint": "A unique name for this format, (e.g. Microsoft Word XP or Microsoft Word 2000)", + "admin.registries.bitstream-formats.edit.shortDescription.hint":"Бұл форматтың ерекше атауы,(e.g. Microsoft Word XP or Microsoft Word 2000)", // "admin.registries.bitstream-formats.edit.shortDescription.label": "Name", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.shortDescription.label": "Name", + "admin.registries.bitstream-formats.edit.shortDescription.label": "Аты", // "admin.registries.bitstream-formats.edit.success.content": "The bitstream format was successfully edited.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.success.content": "The bitstream format was successfully edited.", + "admin.registries.bitstream-formats.edit.success.content": "Бит ағынының форматы сәтті өңделді", // "admin.registries.bitstream-formats.edit.success.head": "Success", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.success.head": "Success", + "admin.registries.bitstream-formats.edit.success.head": "Cәтті", // "admin.registries.bitstream-formats.edit.supportLevel.hint": "The level of support your institution pledges for this format.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.supportLevel.hint": "The level of support your institution pledges for this format.", + "admin.registries.bitstream-formats.edit.supportLevel.hint": "Сіздің мекеме осы форматқа уәде беретін қолдау деңгейі", // "admin.registries.bitstream-formats.edit.supportLevel.label": "Support level", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.edit.supportLevel.label": "Support level", + "admin.registries.bitstream-formats.edit.supportLevel.label": "Қолдау деңгейі", // "admin.registries.bitstream-formats.head": "Bitstream Format Registry", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.head": "Bitstream Format Registry", + "admin.registries.bitstream-formats.head": "Бит ағыны форматтарының тізілімі", // "admin.registries.bitstream-formats.no-items": "No bitstream formats to show.", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.no-items": "No bitstream formats to show.", + "admin.registries.bitstream-formats.no-items": "Көрсету үшін бит ағынының форматтары жоқ", // "admin.registries.bitstream-formats.table.delete": "Delete selected", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.delete": "Delete selected", + "admin.registries.bitstream-formats.table.delete": "Жою таңдалған", // "admin.registries.bitstream-formats.table.deselect-all": "Deselect all", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.deselect-all": "Deselect all", + "admin.registries.bitstream-formats.table.deselect-all": "Барлығын таңдаудан бас тарту", // "admin.registries.bitstream-formats.table.internal": "internal", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.internal": "internal", + "admin.registries.bitstream-formats.table.internal": "ішкі", // "admin.registries.bitstream-formats.table.mimetype": "MIME Type", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.mimetype": "MIME Type", + "admin.registries.bitstream-formats.table.mimetype": "Пантомима түрі", // "admin.registries.bitstream-formats.table.name": "Name", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.name": "Name", + "admin.registries.bitstream-formats.table.name":"Аты", // "admin.registries.bitstream-formats.table.return": "Return", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.return": "Return", + "admin.registries.bitstream-formats.table.return": "Қайтару", // "admin.registries.bitstream-formats.table.supportLevel.KNOWN": "Known", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.supportLevel.KNOWN": "Known", + "admin.registries.bitstream-formats.table.supportLevel.KNOWN": "Белгілі", // "admin.registries.bitstream-formats.table.supportLevel.SUPPORTED": "Supported", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.supportLevel.SUPPORTED": "Supported", + "admin.registries.bitstream-formats.table.supportLevel.SUPPORTED":"Қолдау", // "admin.registries.bitstream-formats.table.supportLevel.UNKNOWN": "Unknown", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.supportLevel.UNKNOWN": "Unknown", + "admin.registries.bitstream-formats.table.supportLevel.UNKNOWN": "Белгісіз", // "admin.registries.bitstream-formats.table.supportLevel.head": "Support Level", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.table.supportLevel.head": "Support Level", + "admin.registries.bitstream-formats.table.supportLevel.head": "Қолдау деңгейі", // "admin.registries.bitstream-formats.title": "DSpace Angular :: Bitstream Format Registry", - // TODO New key - Add a translation - "admin.registries.bitstream-formats.title": "DSpace Angular :: Bitstream Format Registry", - - + "admin.registries.bitstream-formats.title": "DSpace Angular ::Бит ағыны форматтарының тізілімі", // "admin.registries.metadata.breadcrumbs": "Metadata registry", - // TODO New key - Add a translation - "admin.registries.metadata.breadcrumbs": "Metadata registry", + "admin.registries.metadata.breadcrumbs": "Метадеректер тізілімі", // "admin.registries.metadata.description": "The metadata registry maintains a list of all metadata fields available in the repository. These fields may be divided amongst multiple schemas. However, DSpace requires the qualified Dublin Core schema.", - // TODO New key - Add a translation - "admin.registries.metadata.description": "The metadata registry maintains a list of all metadata fields available in the repository. These fields may be divided amongst multiple schemas. However, DSpace requires the qualified Dublin Core schema.", + "admin.registries.metadata.description": "Метадеректер тізілімі репозиторийде қол жетімді барлық метадеректер өрістерінің тізімін жүргізеді. Бұл өрістерді бірнеше тізбектер арасында бөлуге болады. Алайда, DSpace білікті Dublin Core схемасын қажет етеді.", // "admin.registries.metadata.form.create": "Create metadata schema", - // TODO New key - Add a translation - "admin.registries.metadata.form.create": "Create metadata schema", + "admin.registries.metadata.form.create": "Метадеректер схемасын құру", // "admin.registries.metadata.form.edit": "Edit metadata schema", - // TODO New key - Add a translation - "admin.registries.metadata.form.edit": "Edit metadata schema", + "admin.registries.metadata.form.edit":"Метадеректер схемасын өңдеу", // "admin.registries.metadata.form.name": "Name", - // TODO New key - Add a translation - "admin.registries.metadata.form.name": "Name", + "admin.registries.metadata.form.name": "Аты", // "admin.registries.metadata.form.namespace": "Namespace", - // TODO New key - Add a translation - "admin.registries.metadata.form.namespace": "Namespace", + "admin.registries.metadata.form.namespace": "Аттар кеңістігі", // "admin.registries.metadata.head": "Metadata Registry", - // TODO New key - Add a translation - "admin.registries.metadata.head": "Metadata Registry", + "admin.registries.metadata.head": "Метадеректер тізілімі", // "admin.registries.metadata.schemas.no-items": "No metadata schemas to show.", - // TODO New key - Add a translation - "admin.registries.metadata.schemas.no-items": "No metadata schemas to show.", + "admin.registries.metadata.schemas.no-items":"Көрсету үшін метадеректер схемасы жоқ", // "admin.registries.metadata.schemas.table.delete": "Delete selected", - // TODO New key - Add a translation - "admin.registries.metadata.schemas.table.delete": "Delete selected", + "admin.registries.metadata.schemas.table.delete": "Жою таңдалған", // "admin.registries.metadata.schemas.table.id": "ID", - // TODO New key - Add a translation - "admin.registries.metadata.schemas.table.id": "ID", + "admin.registries.metadata.schemas.table.id": "Жеке куәлік", // "admin.registries.metadata.schemas.table.name": "Name", - // TODO New key - Add a translation - "admin.registries.metadata.schemas.table.name": "Name", + "admin.registries.metadata.schemas.table.name": "Аты", // "admin.registries.metadata.schemas.table.namespace": "Namespace", - // TODO New key - Add a translation - "admin.registries.metadata.schemas.table.namespace": "Namespace", + "admin.registries.metadata.schemas.table.namespace": "Аттар кеңістігі", // "admin.registries.metadata.title": "DSpace Angular :: Metadata Registry", - // TODO New key - Add a translation - "admin.registries.metadata.title": "DSpace Angular :: Metadata Registry", - - + "admin.registries.metadata.title": "DSpace Angular :: Метадеректер тізілімі", // "admin.registries.schema.breadcrumbs": "Metadata schema", - // TODO New key - Add a translation - "admin.registries.schema.breadcrumbs": "Metadata schema", + "admin.registries.schema.breadcrumbs":"Метадеректер схемасы", // "admin.registries.schema.description": "This is the metadata schema for \"{{namespace}}\".", - // TODO New key - Add a translation - "admin.registries.schema.description": "This is the metadata schema for \"{{namespace}}\".", + "admin.registries.schema.description": "Бұл \" {{аттар кеңістігі}} \" үшін метадеректер схемасы.", // "admin.registries.schema.fields.head": "Schema metadata fields", - // TODO New key - Add a translation - "admin.registries.schema.fields.head": "Schema metadata fields", + "admin.registries.schema.fields.head": "Схема метадеректерінің өрістері", // "admin.registries.schema.fields.no-items": "No metadata fields to show.", - // TODO New key - Add a translation - "admin.registries.schema.fields.no-items": "No metadata fields to show.", + "admin.registries.schema.fields.no-items": "Көрсету үшін метадеректер өрісі жоқ", // "admin.registries.schema.fields.table.delete": "Delete selected", - // TODO New key - Add a translation - "admin.registries.schema.fields.table.delete": "Delete selected", + "admin.registries.schema.fields.table.delete": "Жою таңдалған", // "admin.registries.schema.fields.table.field": "Field", - // TODO New key - Add a translation - "admin.registries.schema.fields.table.field": "Field", + "admin.registries.schema.fields.table.field": "Өріс", // "admin.registries.schema.fields.table.scopenote": "Scope Note", - // TODO New key - Add a translation - "admin.registries.schema.fields.table.scopenote": "Scope Note", + "admin.registries.schema.fields.table.scopenote": "Қолдану саласы бойынша ескертпе", // "admin.registries.schema.form.create": "Create metadata field", - // TODO New key - Add a translation - "admin.registries.schema.form.create": "Create metadata field", + "admin.registries.schema.form.create": "Метадеректер өрісін құру", // "admin.registries.schema.form.edit": "Edit metadata field", - // TODO New key - Add a translation - "admin.registries.schema.form.edit": "Edit metadata field", + "admin.registries.schema.form.edit": "Метадеректер өрісін өңдеу", // "admin.registries.schema.form.element": "Element", - // TODO New key - Add a translation - "admin.registries.schema.form.element": "Element", + "admin.registries.schema.form.element": "Элемент", // "admin.registries.schema.form.qualifier": "Qualifier", - // TODO New key - Add a translation - "admin.registries.schema.form.qualifier": "Qualifier", + "admin.registries.schema.form.qualifier": "Квалификатор", // "admin.registries.schema.form.scopenote": "Scope Note", - // TODO New key - Add a translation - "admin.registries.schema.form.scopenote": "Scope Note", + "admin.registries.schema.form.scopenote": "Қолдану саласы бойынша ескертпе", // "admin.registries.schema.head": "Metadata Schema", - // TODO New key - Add a translation - "admin.registries.schema.head": "Metadata Schema", + "admin.registries.schema.head": "Метадеректер схемасы", // "admin.registries.schema.notification.created": "Successfully created metadata schema \"{{prefix}}\"", - // TODO New key - Add a translation - "admin.registries.schema.notification.created": "Successfully created metadata schema \"{{prefix}}\"", + "admin.registries.schema.notification.created": "Сәтті құрылған метадеректер схемасы \"{{prefix}}\"", // "admin.registries.schema.notification.deleted.failure": "Failed to delete {{amount}} metadata schemas", - // TODO New key - Add a translation - "admin.registries.schema.notification.deleted.failure": "Failed to delete {{amount}} metadata schemas", + "admin.registries.schema.notification.deleted.failure": "Жою мүмкін емес{{amount}} метадеректер схемалары", // "admin.registries.schema.notification.deleted.success": "Successfully deleted {{amount}} metadata schemas", - // TODO New key - Add a translation - "admin.registries.schema.notification.deleted.success": "Successfully deleted {{amount}} metadata schemas", + "admin.registries.schema.notification.deleted.success": "Сәтті жойылды{{amount}} метадеректер схемалары", // "admin.registries.schema.notification.edited": "Successfully edited metadata schema \"{{prefix}}\"", - // TODO New key - Add a translation - "admin.registries.schema.notification.edited": "Successfully edited metadata schema \"{{prefix}}\"", + "admin.registries.schema.notification.edited": "Сәтті өңделген метадеректер схемасы \"{{prefix}}\"", // "admin.registries.schema.notification.failure": "Error", - // TODO New key - Add a translation - "admin.registries.schema.notification.failure": "Error", + "admin.registries.schema.notification.failure": "Қате", // "admin.registries.schema.notification.field.created": "Successfully created metadata field \"{{field}}\"", - // TODO New key - Add a translation - "admin.registries.schema.notification.field.created": "Successfully created metadata field \"{{field}}\"", + "admin.registries.schema.notification.field.created": "Сәтті құрылған метадеректер өрісі\"{{field}}\"", // "admin.registries.schema.notification.field.deleted.failure": "Failed to delete {{amount}} metadata fields", - // TODO New key - Add a translation - "admin.registries.schema.notification.field.deleted.failure": "Failed to delete {{amount}} metadata fields", + "admin.registries.schema.notification.field.deleted.failure": "Жою мүмкін емес {{amount}}метадеректер өрісі", // "admin.registries.schema.notification.field.deleted.success": "Successfully deleted {{amount}} metadata fields", - // TODO New key - Add a translation - "admin.registries.schema.notification.field.deleted.success": "Successfully deleted {{amount}} metadata fields", + "admin.registries.schema.notification.field.deleted.success":"Сәтті жойылды {{amount}} метадеректер өрісі", // "admin.registries.schema.notification.field.edited": "Successfully edited metadata field \"{{field}}\"", - // TODO New key - Add a translation - "admin.registries.schema.notification.field.edited": "Successfully edited metadata field \"{{field}}\"", + "admin.registries.schema.notification.field.edited": "Сәтті өңделген метадеректер өрісі\"{{field}}\"", // "admin.registries.schema.notification.success": "Success", - // TODO New key - Add a translation - "admin.registries.schema.notification.success": "Success", + "admin.registries.schema.notification.success": "Успех", // "admin.registries.schema.return": "Return", - // TODO New key - Add a translation - "admin.registries.schema.return": "Return", + "admin.registries.schema.return": "Қайтару", // "admin.registries.schema.title": "DSpace Angular :: Metadata Schema Registry", - // TODO New key - Add a translation - "admin.registries.schema.title": "DSpace Angular :: Metadata Schema Registry", - - + "admin.registries.schema.title": "DSpace Angular:: метадеректер тізбегінің тізілімі", // "admin.access-control.epeople.actions.delete": "Delete EPerson", - // TODO New key - Add a translation - "admin.access-control.epeople.actions.delete": "Delete EPerson", + "admin.access-control.epeople.actions.delete": "Адамды жою", // "admin.access-control.epeople.actions.impersonate": "Impersonate EPerson", - // TODO New key - Add a translation - "admin.access-control.epeople.actions.impersonate": "Impersonate EPerson", + "admin.access-control.epeople.actions.impersonate": "Өзіңді басқа адам ретінде көрсету", // "admin.access-control.epeople.actions.reset": "Reset password", - // TODO New key - Add a translation - "admin.access-control.epeople.actions.reset": "Reset password", + "admin.access-control.epeople.actions.reset": "Құпия сөзді қалпына келтіру", // "admin.access-control.epeople.actions.stop-impersonating": "Stop impersonating EPerson", - // TODO New key - Add a translation - "admin.access-control.epeople.actions.stop-impersonating": "Stop impersonating EPerson", + "admin.access-control.epeople.actions.stop-impersonating": "Адам туралы ойлауды доғарыңыз", // "admin.access-control.epeople.title": "DSpace Angular :: EPeople", - // TODO New key - Add a translation - "admin.access-control.epeople.title": "DSpace Angular :: EPeople", + "admin.access-control.epeople.title": "DSpace Angular :: Адамдар", // "admin.access-control.epeople.head": "EPeople", - // TODO New key - Add a translation - "admin.access-control.epeople.head": "EPeople", + "admin.access-control.epeople.head": "Адамдар", // "admin.access-control.epeople.search.head": "Search", "admin.access-control.epeople.search.head": "Іздеу", // "admin.access-control.epeople.button.see-all": "Browse All", - // TODO New key - Add a translation - "admin.access-control.epeople.button.see-all": "Browse All", + "admin.access-control.epeople.button.see-all": "Барлығын қарау", // "admin.access-control.epeople.search.scope.metadata": "Metadata", - // TODO New key - Add a translation - "admin.access-control.epeople.search.scope.metadata": "Metadata", + "admin.access-control.epeople.search.scope.metadata": "Метадеректер", // "admin.access-control.epeople.search.scope.email": "E-mail (exact)", - // TODO New key - Add a translation - "admin.access-control.epeople.search.scope.email": "E-mail (exact)", + "admin.access-control.epeople.search.scope.email": "Электрондық пошта (exact)", // "admin.access-control.epeople.search.button": "Search", - // TODO New key - Add a translation - "admin.access-control.epeople.search.button": "Search", + "admin.access-control.epeople.search.button": "Іздеу", // "admin.access-control.epeople.button.add": "Add EPerson", - // TODO New key - Add a translation - "admin.access-control.epeople.button.add": "Add EPerson", + "admin.access-control.epeople.button.add": "Адамды қосу", // "admin.access-control.epeople.table.id": "ID", - // TODO New key - Add a translation "admin.access-control.epeople.table.id": "ID", // "admin.access-control.epeople.table.name": "Name", - // TODO New key - Add a translation - "admin.access-control.epeople.table.name": "Name", + "admin.access-control.epeople.table.name": "Аты", // "admin.access-control.epeople.table.email": "E-mail (exact)", - // TODO New key - Add a translation - "admin.access-control.epeople.table.email": "E-mail (exact)", + "admin.access-control.epeople.table.email": "Электрондық пошта (exact)", // "admin.access-control.epeople.table.edit": "Edit", - // TODO New key - Add a translation - "admin.access-control.epeople.table.edit": "Edit", + "admin.access-control.epeople.table.edit": "Өңдеу", // "admin.access-control.epeople.table.edit.buttons.edit": "Edit \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.table.edit.buttons.edit": "Edit \"{{name}}\"", + "admin.access-control.epeople.table.edit.buttons.edit": "Өңдеу \"{{name}}\"", // "admin.access-control.epeople.table.edit.buttons.remove": "Delete \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.table.edit.buttons.remove": "Delete \"{{name}}\"", + "admin.access-control.epeople.table.edit.buttons.remove": "Жою\"{{name}}\"", // "admin.access-control.epeople.no-items": "No EPeople to show.", - // TODO New key - Add a translation - "admin.access-control.epeople.no-items": "No EPeople to show.", + "admin.access-control.epeople.no-items": "Көрсетуге болатын адамдар жоқ", // "admin.access-control.epeople.form.create": "Create EPerson", - // TODO New key - Add a translation - "admin.access-control.epeople.form.create": "Create EPerson", + "admin.access-control.epeople.form.create": "Адамды құру", // "admin.access-control.epeople.form.edit": "Edit EPerson", - // TODO New key - Add a translation - "admin.access-control.epeople.form.edit": "Edit EPerson", + "admin.access-control.epeople.form.edit": "Адамды редакциялау", // "admin.access-control.epeople.form.firstName": "First name", - // TODO New key - Add a translation - "admin.access-control.epeople.form.firstName": "First name", + "admin.access-control.epeople.form.firstName": "Аты", // "admin.access-control.epeople.form.lastName": "Last name", - // TODO New key - Add a translation - "admin.access-control.epeople.form.lastName": "Last name", + "admin.access-control.epeople.form.lastName": "Тегі", // "admin.access-control.epeople.form.email": "E-mail", - // TODO New key - Add a translation - "admin.access-control.epeople.form.email": "E-mail", + "admin.access-control.epeople.form.email": "Электрондық пошта", // "admin.access-control.epeople.form.emailHint": "Must be valid e-mail address", - // TODO New key - Add a translation - "admin.access-control.epeople.form.emailHint": "Must be valid e-mail address", + "admin.access-control.epeople.form.emailHint": "Жарамды электрондық пошта мекенжайы болуы керек", // "admin.access-control.epeople.form.canLogIn": "Can log in", - // TODO New key - Add a translation - "admin.access-control.epeople.form.canLogIn": "Can log in", + "admin.access-control.epeople.form.canLogIn": "Мен кіре аламын", // "admin.access-control.epeople.form.requireCertificate": "Requires certificate", - // TODO New key - Add a translation - "admin.access-control.epeople.form.requireCertificate": "Requires certificate", + "admin.access-control.epeople.form.requireCertificate": "Сертификат қажет", // "admin.access-control.epeople.form.notification.created.success": "Successfully created EPerson \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.form.notification.created.success": "Successfully created EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.created.success": "Сәтті құрылған Эпперсон \"{{name}}\"", // "admin.access-control.epeople.form.notification.created.failure": "Failed to create EPerson \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.form.notification.created.failure": "Failed to create EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.created.failure": "Адамды құру мүмкін емес \"{{name}}\"", // "admin.access-control.epeople.form.notification.created.failure.emailInUse": "Failed to create EPerson \"{{name}}\", email \"{{email}}\" already in use.", - // TODO New key - Add a translation - "admin.access-control.epeople.form.notification.created.failure.emailInUse": "Failed to create EPerson \"{{name}}\", email \"{{email}}\" already in use.", + "admin.access-control.epeople.form.notification.created.failure.emailInUse": "Адамды құру мүмкін емес\"{{name}}\", email \"{{email}}\" қазірдің өзінде қолданылады.", // "admin.access-control.epeople.form.notification.edited.failure.emailInUse": "Failed to edit EPerson \"{{name}}\", email \"{{email}}\" already in use.", - // TODO New key - Add a translation - "admin.access-control.epeople.form.notification.edited.failure.emailInUse": "Failed to edit EPerson \"{{name}}\", email \"{{email}}\" already in use.", + "admin.access-control.epeople.form.notification.edited.failure.emailInUse": "Адамды өңдеу мүмкін емес\"{{name}}\", email \"{{email}}\" қазірдің өзінде қолданылады.", // "admin.access-control.epeople.form.notification.edited.success": "Successfully edited EPerson \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.form.notification.edited.success": "Successfully edited EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.edited.success": "Сәтті өңделген адам \"{{name}}\"", // "admin.access-control.epeople.form.notification.edited.failure": "Failed to edit EPerson \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.form.notification.edited.failure": "Failed to edit EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.edited.failure":"Адамды өңдеу мүмкін емес\"{{name}}\"", // "admin.access-control.epeople.form.notification.deleted.success": "Successfully deleted EPerson \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.form.notification.deleted.success": "Successfully deleted EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.deleted.success": "Сәтті жойылған тұлға \"{{name}}\"", // "admin.access-control.epeople.form.notification.deleted.failure": "Failed to delete EPerson \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.form.notification.deleted.failure": "Failed to delete EPerson \"{{name}}\"", + "admin.access-control.epeople.form.notification.deleted.failure": "Пайдаланушыны жою мүмкін емес\"{{name}}\"", // "admin.access-control.epeople.form.groupsEPersonIsMemberOf": "Member of these groups:", - // TODO New key - Add a translation - "admin.access-control.epeople.form.groupsEPersonIsMemberOf": "Member of these groups:", + "admin.access-control.epeople.form.groupsEPersonIsMemberOf": "Осы топтардың мүшесі:", // "admin.access-control.epeople.form.table.id": "ID", - // TODO New key - Add a translation - "admin.access-control.epeople.form.table.id": "ID", + "admin.access-control.epeople.form.table.id": "Жеке куәлік", // "admin.access-control.epeople.form.table.name": "Name", - // TODO New key - Add a translation - "admin.access-control.epeople.form.table.name": "Name", + "admin.access-control.epeople.form.table.name": "Аты", // "admin.access-control.epeople.form.memberOfNoGroups": "This EPerson is not a member of any groups", - // TODO New key - Add a translation - "admin.access-control.epeople.form.memberOfNoGroups": "This EPerson is not a member of any groups", + "admin.access-control.epeople.form.memberOfNoGroups": "Бұл адам ешқандай топтың мүшесі емес", // "admin.access-control.epeople.form.goToGroups": "Add to groups", - // TODO New key - Add a translation - "admin.access-control.epeople.form.goToGroups": "Add to groups", + "admin.access-control.epeople.form.goToGroups": "Топтарға қосу", // "admin.access-control.epeople.notification.deleted.failure": "Failed to delete EPerson: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.notification.deleted.failure": "Failed to delete EPerson: \"{{name}}\"", + "admin.access-control.epeople.notification.deleted.failure": "Пайдаланушыны өшіру мүмкін емес: \"{{name}}\"", // "admin.access-control.epeople.notification.deleted.success": "Successfully deleted EPerson: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.epeople.notification.deleted.success": "Successfully deleted EPerson: \"{{name}}\"", - - + "admin.access-control.epeople.notification.deleted.success": "Сәтті жойылған тұлға: \"{{name}}\"", // "admin.access-control.groups.title": "DSpace Angular :: Groups", - // TODO New key - Add a translation - "admin.access-control.groups.title": "DSpace Angular :: Groups", + "admin.access-control.groups.title": "DSpace Angular :: Топтар", // "admin.access-control.groups.title.singleGroup": "DSpace Angular :: Edit Group", - // TODO New key - Add a translation - "admin.access-control.groups.title.singleGroup": "DSpace Angular :: Edit Group", + "admin.access-control.groups.title.singleGroup": "DSpace Angular:: редакциялау тобы", // "admin.access-control.groups.title.addGroup": "DSpace Angular :: New Group", - // TODO New key - Add a translation - "admin.access-control.groups.title.addGroup": "DSpace Angular :: New Group", + "admin.access-control.groups.title.addGroup": "DSpace Angular :: Жаңа топ", // "admin.access-control.groups.head": "Groups", - // TODO New key - Add a translation - "admin.access-control.groups.head": "Groups", + "admin.access-control.groups.head": "Топтар", // "admin.access-control.groups.button.add": "Add group", - // TODO New key - Add a translation - "admin.access-control.groups.button.add": "Add group", + "admin.access-control.groups.button.add": "Топты қосу", // "admin.access-control.groups.search.head": "Search groups", - // TODO New key - Add a translation - "admin.access-control.groups.search.head": "Search groups", + "admin.access-control.groups.search.head": "Іздеу топтары", // "admin.access-control.groups.button.see-all": "Browse all", - // TODO New key - Add a translation - "admin.access-control.groups.button.see-all": "Browse all", + "admin.access-control.groups.button.see-all": "Барлығын қарау", // "admin.access-control.groups.search.button": "Search", - // TODO New key - Add a translation - "admin.access-control.groups.search.button": "Search", + "admin.access-control.groups.search.button": "Іздеу", // "admin.access-control.groups.table.id": "ID", - // TODO New key - Add a translation - "admin.access-control.groups.table.id": "ID", + "admin.access-control.groups.table.id": "Жеке куәлік", // "admin.access-control.groups.table.name": "Name", - // TODO New key - Add a translation - "admin.access-control.groups.table.name": "Name", + "admin.access-control.groups.table.name": "Аты", // "admin.access-control.groups.table.members": "Members", - // TODO New key - Add a translation - "admin.access-control.groups.table.members": "Members", + "admin.access-control.groups.table.members": "Қатысушылар", // "admin.access-control.groups.table.edit": "Edit", - // TODO New key - Add a translation - "admin.access-control.groups.table.edit": "Edit", + "admin.access-control.groups.table.edit": "Өңдеу", // "admin.access-control.groups.table.edit.buttons.edit": "Edit \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.table.edit.buttons.edit": "Edit \"{{name}}\"", + "admin.access-control.groups.table.edit.buttons.edit": "Редакциялау \"{{name}}\"", // "admin.access-control.groups.table.edit.buttons.remove": "Delete \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.table.edit.buttons.remove": "Delete \"{{name}}\"", + "admin.access-control.groups.table.edit.buttons.remove": "Өшіру \"{{name}}\"", // "admin.access-control.groups.no-items": "No groups found with this in their name or this as UUID", - // TODO New key - Add a translation - "admin.access-control.groups.no-items": "No groups found with this in their name or this as UUID", + "admin.access-control.groups.no-items": "Бұл атаумен немесе UUID сияқты топтар табылған жоқ", // "admin.access-control.groups.notification.deleted.success": "Successfully deleted group \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.notification.deleted.success": "Successfully deleted group \"{{name}}\"", + "admin.access-control.groups.notification.deleted.success": "Сәтті қашықтағы топ \"{{name}}\"", // "admin.access-control.groups.notification.deleted.failure.title": "Failed to delete group \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.notification.deleted.failure.title": "Failed to delete group \"{{name}}\"", + "admin.access-control.groups.notification.deleted.failure.title": "Топты жою мүмкін емес \"{{name}}\"", // "admin.access-control.groups.notification.deleted.failure.content": "Cause: \"{{cause}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.notification.deleted.failure.content": "Cause: \"{{cause}}\"", - - + "admin.access-control.groups.notification.deleted.failure.content": "Себебі: \"{{cause}}\"", // "admin.access-control.groups.form.alert.permanent": "This group is permanent, so it can't be edited or deleted. You can still add and remove group members using this page.", - // TODO New key - Add a translation - "admin.access-control.groups.form.alert.permanent": "This group is permanent, so it can't be edited or deleted. You can still add and remove group members using this page.", + "admin.access-control.groups.form.alert.permanent": "Бұл топ тұрақты, сондықтан оны өңдеуге немесе жоюға болмайды. Осы бетті қолдана отырып, топ мүшелерін қосуға және жоюға болады.", // "admin.access-control.groups.form.alert.workflowGroup": "This group can’t be modified or deleted because it corresponds to a role in the submission and workflow process in the \"{{name}}\" {{comcol}}. You can delete it from the \"assign roles\" tab on the edit {{comcol}} page. You can still add and remove group members using this page.", - // TODO New key - Add a translation - "admin.access-control.groups.form.alert.workflowGroup": "This group can’t be modified or deleted because it corresponds to a role in the submission and workflow process in the \"{{name}}\" {{comcol}}. You can delete it from the \"assign roles\" tab on the edit {{comcol}} page. You can still add and remove group members using this page.", + "admin.access-control.groups.form.alert.workflowGroup": "Бұл топты өзгерту немесе жою мүмкін емес, өйткені ол жіберу және жұмыс процесінің рөліне сәйкес келеді \"{{name}}\" {{comcol}}. Сіз оны \"рөлдерді тағайындау\" өңдеу қойындысы {{comcol}} page. You can still add and remove group members using this page.", // "admin.access-control.groups.form.head.create": "Create group", - // TODO New key - Add a translation - "admin.access-control.groups.form.head.create": "Create group", + "admin.access-control.groups.form.head.create": "Топ құру", // "admin.access-control.groups.form.head.edit": "Edit group", - // TODO New key - Add a translation - "admin.access-control.groups.form.head.edit": "Edit group", + "admin.access-control.groups.form.head.edit": "Топты өңдеу", // "admin.access-control.groups.form.groupName": "Group name", - // TODO New key - Add a translation - "admin.access-control.groups.form.groupName": "Group name", + "admin.access-control.groups.form.groupName": "Топтың атауы", // "admin.access-control.groups.form.groupDescription": "Description", - // TODO New key - Add a translation - "admin.access-control.groups.form.groupDescription": "Description", + "admin.access-control.groups.form.groupDescription":"Сипаттама", // "admin.access-control.groups.form.notification.created.success": "Successfully created Group \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.created.success": "Successfully created Group \"{{name}}\"", + "admin.access-control.groups.form.notification.created.success": "Сәтті құрылған топ \"{{name}}\"", // "admin.access-control.groups.form.notification.created.failure": "Failed to create Group \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.created.failure": "Failed to create Group \"{{name}}\"", + "admin.access-control.groups.form.notification.created.failure": "Топ құру мүмкін емес \"{{name}}\"", // "admin.access-control.groups.form.notification.created.failure.groupNameInUse": "Failed to create Group with name: \"{{name}}\", make sure the name is not already in use.", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.created.failure.groupNameInUse": "Failed to create Group with name: \"{{name}}\", make sure the name is not already in use.", + "admin.access-control.groups.form.notification.created.failure.groupNameInUse": "Аты бар топ құру мүмкін емес: \"{{name}}\", бұл атау әлі қолданылмағанына көз жеткізіңіз.", // "admin.access-control.groups.form.notification.edited.failure": "Failed to edit Group \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.edited.failure": "Failed to edit Group \"{{name}}\"", + "admin.access-control.groups.form.notification.edited.failure": "Топты өңдеу мүмкін емес\"{{name}}\"", // "admin.access-control.groups.form.notification.edited.failure.groupNameInUse": "Name \"{{name}}\" already in use!", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.edited.failure.groupNameInUse": "Name \"{{name}}\" already in use!", + "admin.access-control.groups.form.notification.edited.failure.groupNameInUse": "Аты \"{{name}}\" қазірдің өзінде қолданылады", // "admin.access-control.groups.form.notification.edited.success": "Successfully edited Group \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.edited.success": "Successfully edited Group \"{{name}}\"", + "admin.access-control.groups.form.notification.edited.success": "Сәтті өңделген топ \"{{name}}\"", // "admin.access-control.groups.form.actions.delete": "Delete Group", - // TODO New key - Add a translation - "admin.access-control.groups.form.actions.delete": "Delete Group", + "admin.access-control.groups.form.actions.delete": "Топты өшіру", // "admin.access-control.groups.form.delete-group.modal.header": "Delete Group \"{{ dsoName }}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.delete-group.modal.header": "Delete Group \"{{ dsoName }}\"", + "admin.access-control.groups.form.delete-group.modal.header": "Топты жою \"{{ dsoName }}\"", // "admin.access-control.groups.form.delete-group.modal.info": "Are you sure you want to delete Group \"{{ dsoName }}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.delete-group.modal.info": "Are you sure you want to delete Group \"{{ dsoName }}\"", + "admin.access-control.groups.form.delete-group.modal.info": "Сіз топты жойғыңыз келетініне сенімдісіз \"{{ dsoName }}\"", // "admin.access-control.groups.form.delete-group.modal.cancel": "Cancel", - // TODO New key - Add a translation - "admin.access-control.groups.form.delete-group.modal.cancel": "Cancel", + "admin.access-control.groups.form.delete-group.modal.cancel": "Болдырмау", // "admin.access-control.groups.form.delete-group.modal.confirm": "Delete", - // TODO New key - Add a translation - "admin.access-control.groups.form.delete-group.modal.confirm": "Delete", + "admin.access-control.groups.form.delete-group.modal.confirm": "Жою", // "admin.access-control.groups.form.notification.deleted.success": "Successfully deleted group \"{{ name }}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.deleted.success": "Successfully deleted group \"{{ name }}\"", + "admin.access-control.groups.form.notification.deleted.success": "Сәтті қашықтағы топ \"{{ name }}\"", // "admin.access-control.groups.form.notification.deleted.failure.title": "Failed to delete group \"{{ name }}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.deleted.failure.title": "Failed to delete group \"{{ name }}\"", + "admin.access-control.groups.form.notification.deleted.failure.title": "Топты жою мүмкін емес\"{{ name }}\"", // "admin.access-control.groups.form.notification.deleted.failure.content": "Cause: \"{{ cause }}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.notification.deleted.failure.content": "Cause: \"{{ cause }}\"", + "admin.access-control.groups.form.notification.deleted.failure.content": "Өйткені: \"{{ cause }}\"", // "admin.access-control.groups.form.members-list.head": "EPeople", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.head": "EPeople", + "admin.access-control.groups.form.members-list.head": "Адамдар", // "admin.access-control.groups.form.members-list.search.head": "Add EPeople", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.search.head": "Add EPeople", + "admin.access-control.groups.form.members-list.search.head": "Адамдарды қосу", // "admin.access-control.groups.form.members-list.button.see-all": "Browse All", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.button.see-all": "Browse All", + "admin.access-control.groups.form.members-list.button.see-all": "Барлығын қарау", // "admin.access-control.groups.form.members-list.headMembers": "Current Members", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.headMembers": "Current Members", + "admin.access-control.groups.form.members-list.headMembers": "Қазіргі мүшелер", // "admin.access-control.groups.form.members-list.search.scope.metadata": "Metadata", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.search.scope.metadata": "Metadata", + "admin.access-control.groups.form.members-list.search.scope.metadata": "Метадеректер", // "admin.access-control.groups.form.members-list.search.scope.email": "E-mail (exact)", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.search.scope.email": "E-mail (exact)", + "admin.access-control.groups.form.members-list.search.scope.email": "Электрондық пошта (exact)", // "admin.access-control.groups.form.members-list.search.button": "Search", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.search.button": "Search", + "admin.access-control.groups.form.members-list.search.button": "Іздеу", // "admin.access-control.groups.form.members-list.table.id": "ID", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.table.id": "ID", + "admin.access-control.groups.form.members-list.table.id": "Жеке куәлік", // "admin.access-control.groups.form.members-list.table.name": "Name", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.table.name": "Name", + "admin.access-control.groups.form.members-list.table.name": "Аты", // "admin.access-control.groups.form.members-list.table.edit": "Remove / Add", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.table.edit": "Remove / Add", + "admin.access-control.groups.form.members-list.table.edit": "Жою/ Add", // "admin.access-control.groups.form.members-list.table.edit.buttons.remove": "Remove member with name \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.table.edit.buttons.remove": "Remove member with name \"{{name}}\"", + "admin.access-control.groups.form.members-list.table.edit.buttons.remove": "Қатысушыны аты-жөнімен жою \"{{name}}\"", // "admin.access-control.groups.form.members-list.notification.success.addMember": "Successfully added member: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.notification.success.addMember": "Successfully added member: \"{{name}}\"", + "admin.access-control.groups.form.members-list.notification.success.addMember":"Сәтті қосылған мүше: \"{{name}}\"", // "admin.access-control.groups.form.members-list.notification.failure.addMember": "Failed to add member: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.notification.failure.addMember": "Failed to add member: \"{{name}}\"", + "admin.access-control.groups.form.members-list.notification.failure.addMember":"Қатысушыны қосу мүмкін емес: \"{{name}}\"", // "admin.access-control.groups.form.members-list.notification.success.deleteMember": "Successfully deleted member: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.notification.success.deleteMember": "Successfully deleted member: \"{{name}}\"", + "admin.access-control.groups.form.members-list.notification.success.deleteMember": "Сәтті қашықтағы мүше: \"{{name}}\"", // "admin.access-control.groups.form.members-list.notification.failure.deleteMember": "Failed to delete member: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.notification.failure.deleteMember": "Failed to delete member: \"{{name}}\"", + "admin.access-control.groups.form.members-list.notification.failure.deleteMember": "Қатысушыны жою мүмкін емес: \"{{name}}\"", // "admin.access-control.groups.form.members-list.table.edit.buttons.add": "Add member with name \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.table.edit.buttons.add": "Add member with name \"{{name}}\"", + "admin.access-control.groups.form.members-list.table.edit.buttons.add": "Аты бар мүшені қосу\"{{name}}\"", // "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", + "admin.access-control.groups.form.members-list.notification.failure.noActiveGroup": "Ағымдағы белсенді топ жоқ, алдымен атын енгізіңіз.", // "admin.access-control.groups.form.members-list.no-members-yet": "No members in group yet, search and add.", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.no-members-yet": "No members in group yet, search and add.", + "admin.access-control.groups.form.members-list.no-members-yet": "Топта әлі мүшелер жоқ, табыңыз және қосыңыз", // "admin.access-control.groups.form.members-list.no-items": "No EPeople found in that search", - // TODO New key - Add a translation - "admin.access-control.groups.form.members-list.no-items": "No EPeople found in that search", + "admin.access-control.groups.form.members-list.no-items": "Бұл іздеу барысында бірде-бір адам табылған жоқ", // "admin.access-control.groups.form.subgroups-list.notification.failure": "Something went wrong: \"{{cause}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.notification.failure": "Something went wrong: \"{{cause}}\"", + "admin.access-control.groups.form.subgroups-list.notification.failure": "Бір нәрсе дұрыс болмады: \"{{cause}}\"", // "admin.access-control.groups.form.subgroups-list.head": "Groups", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.head": "Groups", + "admin.access-control.groups.form.subgroups-list.head": "Топтар", // "admin.access-control.groups.form.subgroups-list.search.head": "Add Subgroup", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.search.head": "Add Subgroup", + "admin.access-control.groups.form.subgroups-list.search.head":"Кіші топты қосу", // "admin.access-control.groups.form.subgroups-list.button.see-all": "Browse All", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.button.see-all": "Browse All", + "admin.access-control.groups.form.subgroups-list.button.see-all": "Барлығын Қарау", // "admin.access-control.groups.form.subgroups-list.headSubgroups": "Current Subgroups", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.headSubgroups": "Current Subgroups", + "admin.access-control.groups.form.subgroups-list.headSubgroups": "Ағымдағы кіші топтар", // "admin.access-control.groups.form.subgroups-list.search.button": "Search", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.search.button": "Search", + "admin.access-control.groups.form.subgroups-list.search.button": "Іздеу", // "admin.access-control.groups.form.subgroups-list.table.id": "ID", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.table.id": "ID", + "admin.access-control.groups.form.subgroups-list.table.id": "Жеке куәлік", // "admin.access-control.groups.form.subgroups-list.table.name": "Name", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.table.name": "Name", + "admin.access-control.groups.form.subgroups-list.table.name": "Аты", // "admin.access-control.groups.form.subgroups-list.table.edit": "Remove / Add", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.table.edit": "Remove / Add", + "admin.access-control.groups.form.subgroups-list.table.edit": "Жою / Қосу", // "admin.access-control.groups.form.subgroups-list.table.edit.buttons.remove": "Remove subgroup with name \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.table.edit.buttons.remove": "Remove subgroup with name \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.table.edit.buttons.remove": "Аты бар кіші топты жою \"{{name}}\"", - // "admin.access-control.groups.form.subgroups-list.table.edit.buttons.add": "Add subgroup with name \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.table.edit.buttons.add": "Add subgroup with name \"{{name}}\"", + // "admin.access-control.groups.form.subgroups-list.table.edit.buttons.add": "Add subgroup with name \"{{name}}\"" + "admin.access-control.groups.form.subgroups-list.table.edit.buttons.add": "Атауы бар кіші топты қосыңыз \"{{name}}\"", // "admin.access-control.groups.form.subgroups-list.table.edit.currentGroup": "Current group", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.table.edit.currentGroup": "Current group", + "admin.access-control.groups.form.subgroups-list.table.edit.currentGroup": "Ағымдағы топ", // "admin.access-control.groups.form.subgroups-list.notification.success.addSubgroup": "Successfully added subgroup: \"{{name}}\"", - // TODO New key - Add a translation "admin.access-control.groups.form.subgroups-list.notification.success.addSubgroup": "Successfully added subgroup: \"{{name}}\"", // "admin.access-control.groups.form.subgroups-list.notification.failure.addSubgroup": "Failed to add subgroup: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.notification.failure.addSubgroup": "Failed to add subgroup: \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.notification.failure.addSubgroup": "Кіші топ қосу мүмкін емес: \"{{name}}\"", // "admin.access-control.groups.form.subgroups-list.notification.success.deleteSubgroup": "Successfully deleted subgroup: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.notification.success.deleteSubgroup": "Successfully deleted subgroup: \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.notification.success.deleteSubgroup": "Сәтті жойылған кіші топ: \"{{name}}\"", // "admin.access-control.groups.form.subgroups-list.notification.failure.deleteSubgroup": "Failed to delete subgroup: \"{{name}}\"", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.notification.failure.deleteSubgroup": "Failed to delete subgroup: \"{{name}}\"", + "admin.access-control.groups.form.subgroups-list.notification.failure.deleteSubgroup": "Кіші топты жою мүмкін емес: \"{{name}}\"", // "admin.access-control.groups.form.subgroups-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.notification.failure.noActiveGroup": "No current active group, submit a name first.", + "admin.access-control.groups.form.subgroups-list.notification.failure.noActiveGroup": "Ағымдағы белсенді топ жоқ, алдымен атын енгізіңіз.", // "admin.access-control.groups.form.subgroups-list.notification.failure.subgroupToAddIsActiveGroup": "This is the current group, can't be added.", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.notification.failure.subgroupToAddIsActiveGroup": "This is the current group, can't be added.", + "admin.access-control.groups.form.subgroups-list.notification.failure.subgroupToAddIsActiveGroup": "Бұл қазіргі топ, оны қосу мүмкін емес.", // "admin.access-control.groups.form.subgroups-list.no-items": "No groups found with this in their name or this as UUID", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.no-items": "No groups found with this in their name or this as UUID", + "admin.access-control.groups.form.subgroups-list.no-items": "Бұл атаумен немесе UUID сияқты топтар табылған жоқ", // "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "No subgroups in group yet.", - // TODO New key - Add a translation - "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "No subgroups in group yet.", + "admin.access-control.groups.form.subgroups-list.no-subgroups-yet": "Топта әлі кіші топтар жоқ.", // "admin.access-control.groups.form.return": "Return to groups", - // TODO New key - Add a translation - "admin.access-control.groups.form.return": "Return to groups", - - + "admin.access-control.groups.form.return": "Топтарға оралу", // "admin.search.breadcrumbs": "Administrative Search", - // TODO New key - Add a translation - "admin.search.breadcrumbs": "Administrative Search", + "admin.search.breadcrumbs": "Әкімшілік іздеу", // "admin.search.collection.edit": "Edit", - // TODO New key - Add a translation - "admin.search.collection.edit": "Edit", + "admin.search.collection.edit": "Өңдеу", // "admin.search.community.edit": "Edit", - // TODO New key - Add a translation - "admin.search.community.edit": "Edit", + "admin.search.community.edit":"Өңдеу", // "admin.search.item.delete": "Delete", - // TODO New key - Add a translation - "admin.search.item.delete": "Delete", + "admin.search.item.delete": "Жою", // "admin.search.item.edit": "Edit", - // TODO New key - Add a translation - "admin.search.item.edit": "Edit", + "admin.search.item.edit": "Өңдеу", // "admin.search.item.make-private": "Make Private", - // TODO New key - Add a translation - "admin.search.item.make-private": "Make Private", + "admin.search.item.make-private": "Жеке ету", // "admin.search.item.make-public": "Make Public", - // TODO New key - Add a translation - "admin.search.item.make-public": "Make Public", + "admin.search.item.make-public": "Жариялау", // "admin.search.item.move": "Move", - // TODO New key - Add a translation - "admin.search.item.move": "Move", + "admin.search.item.move": "Жылжыту", // "admin.search.item.reinstate": "Reinstate", - // TODO New key - Add a translation - "admin.search.item.reinstate": "Reinstate", + "admin.search.item.reinstate":"Қалпына келтіру", // "admin.search.item.withdraw": "Withdraw", - // TODO New key - Add a translation - "admin.search.item.withdraw": "Withdraw", + "admin.search.item.withdraw": "Шақыру", // "admin.search.title": "Administrative Search", - // TODO New key - Add a translation - "admin.search.title": "Administrative Search", + "admin.search.title": "Әкімшілік іздеу", // "administrativeView.search.results.head": "Administrative Search", - // TODO New key - Add a translation - "administrativeView.search.results.head": "Administrative Search", - - - + "administrativeView.search.results.head": "Әкімшілік іздеу", // "admin.workflow.breadcrumbs": "Administer Workflow", - // TODO New key - Add a translation - "admin.workflow.breadcrumbs": "Administer Workflow", + "admin.workflow.breadcrumbs": "Жұмыс процесін басқару", // "admin.workflow.title": "Administer Workflow", - // TODO New key - Add a translation - "admin.workflow.title": "Administer Workflow", + "admin.workflow.title": "Жұмыс процесін басқару", // "admin.workflow.item.workflow": "Workflow", - // TODO New key - Add a translation - "admin.workflow.item.workflow": "Workflow", + "admin.workflow.item.workflow": "Жұмыс процесі", // "admin.workflow.item.delete": "Delete", - // TODO New key - Add a translation - "admin.workflow.item.delete": "Delete", + "admin.workflow.item.delete": "Жою", // "admin.workflow.item.send-back": "Send back", - // TODO New key - Add a translation - "admin.workflow.item.send-back": "Send back", - - + "admin.workflow.item.send-back": "Кері жіберу", // "admin.metadata-import.breadcrumbs": "Import Metadata", - // TODO New key - Add a translation - "admin.metadata-import.breadcrumbs": "Import Metadata", + "admin.metadata-import.breadcrumbs": "Метадеректерді импорттау", // "admin.metadata-import.title": "Import Metadata", - // TODO New key - Add a translation - "admin.metadata-import.title": "Import Metadata", + "admin.metadata-import.title": "Метадеректерді импорттау", // "admin.metadata-import.page.header": "Import Metadata", - // TODO New key - Add a translation - "admin.metadata-import.page.header": "Import Metadata", + "admin.metadata-import.page.header": "Метадеректерді импорттау", // "admin.metadata-import.page.help": "You can drop or browse CSV files that contain batch metadata operations on files here", - // TODO New key - Add a translation - "admin.metadata-import.page.help": "You can drop or browse CSV files that contain batch metadata operations on files here", + "admin.metadata-import.page.help": "Мұнда файлдарда метадеректермен пакеттік операциялары бар CSV файлдарын жоюға немесе көруге болады", // "admin.metadata-import.page.dropMsg": "Drop a metadata CSV to import", - // TODO New key - Add a translation - "admin.metadata-import.page.dropMsg": "Drop a metadata CSV to import", + "admin.metadata-import.page.dropMsg": "Импорттау үшін метадеректердің CSV файлын сүйреңіз", // "admin.metadata-import.page.dropMsgReplace": "Drop to replace the metadata CSV to import", - // TODO New key - Add a translation - "admin.metadata-import.page.dropMsgReplace": "Drop to replace the metadata CSV to import", + "admin.metadata-import.page.dropMsgReplace": "Импорттау үшін CSV метадеректерін ауыстыру үшін тастаңыз", // "admin.metadata-import.page.button.return": "Return", - // TODO New key - Add a translation - "admin.metadata-import.page.button.return": "Return", + "admin.metadata-import.page.button.return": "Қайтару", // "admin.metadata-import.page.button.proceed": "Proceed", - // TODO New key - Add a translation - "admin.metadata-import.page.button.proceed": "Proceed", + "admin.metadata-import.page.button.proceed": "Жалғастыра беріңіз", // "admin.metadata-import.page.error.addFile": "Select file first!", - // TODO New key - Add a translation - "admin.metadata-import.page.error.addFile": "Select file first!", + "admin.metadata-import.page.error.addFile": "Алдымен файлды таңдаңыз!", // "auth.errors.invalid-user": "Invalid email address or password.", // TODO New key - Add a translation - "auth.errors.invalid-user": "Invalid email address or password.", + "auth.errors.invalid-user": "Жарамсыз электрондық пошта мекенжайы немесе құпия сөз.", // "auth.messages.expired": "Your session has expired. Please log in again.", // TODO New key - Add a translation - "auth.messages.expired": "Your session has expired. Please log in again.", + "auth.messages.expired": "Сессияңыздың мерзімі аяқталды. Жүйеге қайта кіріңіз.", From 917e5fe5bc0fdee2f022892c6bfab795384578ba Mon Sep 17 00:00:00 2001 From: Marie Verdonck Date: Mon, 2 May 2022 14:55:23 +0200 Subject: [PATCH 0311/2129] Issue 1635: Fix for @input not working on search bar ds-search-form --- src/app/shared/search-form/search-form.component.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/app/shared/search-form/search-form.component.ts b/src/app/shared/search-form/search-form.component.ts index 2791aee378f..cabcab48596 100644 --- a/src/app/shared/search-form/search-form.component.ts +++ b/src/app/shared/search-form/search-form.component.ts @@ -77,6 +77,9 @@ export class SearchFormComponent { * @param data Values submitted using the form */ onSubmit(data: any) { + if (isNotEmpty(this.scope)) { + data = Object.assign(data, { scope: this.scope }); + } this.updateSearch(data); this.submitSearch.emit(data); } From f3a40a5ef900b180d7e6c27e320df4c20753e7a6 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 2 May 2022 16:08:58 +0200 Subject: [PATCH 0312/2129] [CST-5239] Fix button visualization --- .../metadata-import-page.component.html | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html index fb96c4becd5..2c710935d51 100644 --- a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html +++ b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html @@ -12,8 +12,10 @@ [dropMessageLabelReplacement]="'admin.metadata-import.page.dropMsgReplace'"> - - +
+ + +
From bb3cc1c619dfe0e2f9a8bfb55380f8f5eb0671e9 Mon Sep 17 00:00:00 2001 From: Davide Negretti Date: Mon, 2 May 2022 17:02:04 +0200 Subject: [PATCH 0313/2129] [CST-5674] Edit policy target; modal content; test --- .../resource-policy.service.spec.ts | 8 ++- .../resource-policy.service.ts | 55 +++++++++++++++++-- .../edit/resource-policy-edit.component.ts | 33 +++++++---- .../form/resource-policy-form.component.html | 15 ++++- .../resource-policy-form.component.spec.ts | 13 +++-- .../form/resource-policy-form.component.ts | 5 ++ src/assets/i18n/en.json5 | 10 ++++ 7 files changed, 117 insertions(+), 22 deletions(-) diff --git a/src/app/core/resource-policy/resource-policy.service.spec.ts b/src/app/core/resource-policy/resource-policy.service.spec.ts index 59316c00981..ca62159f59d 100644 --- a/src/app/core/resource-policy/resource-policy.service.spec.ts +++ b/src/app/core/resource-policy/resource-policy.service.spec.ts @@ -19,6 +19,8 @@ import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils import { RestResponse } from '../cache/response.models'; import { RequestEntry } from '../data/request-entry.model'; import { FindListOptions } from '../data/find-list-options.model'; +import { EPersonDataService } from '../eperson/eperson-data.service'; +import { GroupDataService } from '../eperson/group-data.service'; describe('ResourcePolicyService', () => { let scheduler: TestScheduler; @@ -28,6 +30,8 @@ describe('ResourcePolicyService', () => { let objectCache: ObjectCacheService; let halService: HALEndpointService; let responseCacheEntry: RequestEntry; + let ePersonService: EPersonDataService; + let groupService: GroupDataService; const resourcePolicy: any = { id: '1', @@ -129,7 +133,9 @@ describe('ResourcePolicyService', () => { halService, notificationsService, http, - comparator + comparator, + ePersonService, + groupService ); spyOn((service as any).dataService, 'create').and.callThrough(); diff --git a/src/app/core/resource-policy/resource-policy.service.ts b/src/app/core/resource-policy/resource-policy.service.ts index 065e58c53d3..f4f70a73e27 100644 --- a/src/app/core/resource-policy/resource-policy.service.ts +++ b/src/app/core/resource-policy/resource-policy.service.ts @@ -1,6 +1,6 @@ /* eslint-disable max-classes-per-file */ import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; @@ -23,11 +23,19 @@ import { PaginatedList } from '../data/paginated-list.model'; import { ActionType } from './models/action-type.model'; import { RequestParam } from '../cache/models/request-param.model'; import { isNotEmpty } from '../../shared/empty.util'; -import { map } from 'rxjs/operators'; +import { map, switchMap, take } from 'rxjs/operators'; import { NoContent } from '../shared/NoContent.model'; import { getFirstCompletedRemoteData } from '../shared/operators'; import { CoreState } from '../core-state.model'; import { FindListOptions } from '../data/find-list-options.model'; +import { HttpOptions } from '../dspace-rest/dspace-rest.service'; +import { PostRequest } from '../data/request.models'; +import { GenericConstructor } from '../shared/generic-constructor'; +import { ResponseParsingService } from '../data/parsing.service'; +import { StatusCodeOnlyResponseParsingService } from '../data/status-code-only-response-parsing.service'; +import { HALLink } from '../shared/hal-link.model'; +import { EPersonDataService } from '../eperson/eperson-data.service'; +import { GroupDataService } from '../eperson/group-data.service'; /** @@ -44,7 +52,8 @@ class DataServiceImpl extends DataService { protected halService: HALEndpointService, protected notificationsService: NotificationsService, protected http: HttpClient, - protected comparator: ChangeAnalyzer) { + protected comparator: ChangeAnalyzer, + ) { super(); } @@ -68,7 +77,10 @@ export class ResourcePolicyService { protected halService: HALEndpointService, protected notificationsService: NotificationsService, protected http: HttpClient, - protected comparator: DefaultChangeAnalyzer) { + protected comparator: DefaultChangeAnalyzer, + protected ePersonService: EPersonDataService, + protected groupService: GroupDataService, + ) { this.dataService = new DataServiceImpl(requestService, rdbService, null, objectCache, halService, notificationsService, http, comparator); } @@ -221,4 +233,39 @@ export class ResourcePolicyService { return this.dataService.searchBy(this.searchByResourceMethod, options, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow); } + /** + * Update the target of the resource policy + * @param resourcePolicyHref the link to the resource policy + * @param uuid the UUID of the target to which the permission is being granted + * @param type the type of the target (eperson or group) to which the permission is being granted + */ + updateTarget(resourcePolicyHref: string, uuid: string, type: string): Observable> { + + const targetService = type === 'eperson' ? this.ePersonService : this.groupService; + + const ep$ = targetService.getBrowseEndpoint().pipe( + take(1), + map((endpoint: string) =>`${endpoint}/${uuid}`), + ); + + const options: HttpOptions = Object.create({}); + let headers = new HttpHeaders(); + headers = headers.append('Content-Type', 'text/uri-list'); + options.headers = headers; + + const requestId = this.requestService.generateRequestId(); + + return ep$.pipe(switchMap((ep) => { + const request = new PostRequest(requestId, resourcePolicyHref, ep, options); + Object.assign(request, { + getResponseParser(): GenericConstructor { + return StatusCodeOnlyResponseParsingService; + } + }); + this.requestService.send(request); + return this.rdbService.buildFromRequestUUID(requestId); + })); + + } + } diff --git a/src/app/shared/resource-policies/edit/resource-policy-edit.component.ts b/src/app/shared/resource-policies/edit/resource-policy-edit.component.ts index a515eef675f..d2c1b6dd0de 100644 --- a/src/app/shared/resource-policies/edit/resource-policy-edit.component.ts +++ b/src/app/shared/resource-policies/edit/resource-policy-edit.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; -import { BehaviorSubject, Observable } from 'rxjs'; +import { BehaviorSubject, Observable, of, combineLatest as observableCombineLatest, } from 'rxjs'; import { map, take } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; @@ -88,16 +88,29 @@ export class ResourcePolicyEditComponent implements OnInit { type: RESOURCE_POLICY.value, _links: this.resourcePolicy._links }); - this.resourcePolicyService.update(updatedObject).pipe( + + const updateTargetSucceeded$ = event.updateTarget ? this.resourcePolicyService.updateTarget( + this.resourcePolicy._links.self.href, event.target.uuid, event.target.type + ).pipe( + getFirstCompletedRemoteData(), + map((responseRD) => responseRD && responseRD.hasSucceeded) + ) : of(true); + + const updateResourcePolicySucceeded$ = this.resourcePolicyService.update(updatedObject).pipe( getFirstCompletedRemoteData(), - ).subscribe((responseRD: RemoteData) => { - this.processing$.next(false); - if (responseRD && responseRD.hasSucceeded) { - this.notificationsService.success(null, this.translate.get('resource-policies.edit.page.success.content')); - this.redirectToAuthorizationsPage(); - } else { - this.notificationsService.error(null, this.translate.get('resource-policies.edit.page.failure.content')); + map((responseRD) => responseRD && responseRD.hasSucceeded) + ); + + observableCombineLatest([updateTargetSucceeded$, updateResourcePolicySucceeded$]).subscribe( + ([updateTargetSucceeded, updateResourcePolicySucceeded]) => { + this.processing$.next(false); + if (updateTargetSucceeded && updateResourcePolicySucceeded) { + this.notificationsService.success(null, this.translate.get('resource-policies.edit.page.success.content')); + this.redirectToAuthorizationsPage(); + } else { + this.notificationsService.error(null, this.translate.get('resource-policies.edit.page.failure.content')); + } } - }); + ); } } diff --git a/src/app/shared/resource-policies/form/resource-policy-form.component.html b/src/app/shared/resource-policies/form/resource-policy-form.component.html index 821d15f4146..f7aad55ce8c 100644 --- a/src/app/shared/resource-policies/form/resource-policy-form.component.html +++ b/src/app/shared/resource-policies/form/resource-policy-form.component.html @@ -55,15 +55,24 @@ diff --git a/src/app/shared/resource-policies/form/resource-policy-form.component.spec.ts b/src/app/shared/resource-policies/form/resource-policy-form.component.spec.ts index c31a65c1f62..456eb6db5e0 100644 --- a/src/app/shared/resource-policies/form/resource-policy-form.component.spec.ts +++ b/src/app/shared/resource-policies/form/resource-policy-form.component.spec.ts @@ -222,6 +222,8 @@ describe('ResourcePolicyFormComponent test suite', () => { testFixture = createTestComponent(html, TestComponent) as ComponentFixture; testComp = testFixture.componentInstance; + testComp.resourcePolicy = resourcePolicy; + fixture.detectChanges(); }); afterEach(() => { @@ -242,6 +244,7 @@ describe('ResourcePolicyFormComponent test suite', () => { fixture = TestBed.createComponent(ResourcePolicyFormComponent); comp = fixture.componentInstance; compAsAny = fixture.componentInstance; + compAsAny.resourcePolicy = resourcePolicy; comp.isProcessing = observableOf(false); }); @@ -261,7 +264,7 @@ describe('ResourcePolicyFormComponent test suite', () => { expect(compAsAny.buildResourcePolicyForm).toHaveBeenCalled(); expect(compAsAny.initModelsValue).toHaveBeenCalled(); expect(compAsAny.formModel.length).toBe(5); - expect(compAsAny.subs.length).toBe(0); + expect(compAsAny.subs.length).toBe(1); }); @@ -279,7 +282,7 @@ describe('ResourcePolicyFormComponent test suite', () => { expect(compAsAny.reset.emit).toHaveBeenCalled(); }); - it('should update resource policy grant object properly', () => { + it('should update resource policy grant object properly', () => { comp.updateObjectSelected(EPersonMock, true); expect(comp.resourcePolicyGrant).toEqual(EPersonMock); @@ -301,6 +304,7 @@ describe('ResourcePolicyFormComponent test suite', () => { comp = fixture.componentInstance; compAsAny = fixture.componentInstance; comp.resourcePolicy = resourcePolicy; + compAsAny.resourcePolicy = resourcePolicy; comp.isProcessing = observableOf(false); compAsAny.ePersonService.findByHref.and.returnValue( observableOf(createSuccessfulRemoteDataObject({})).pipe(delay(100)) @@ -343,8 +347,8 @@ describe('ResourcePolicyFormComponent test suite', () => { }); }); - it('should not can set grant', () => { - expect(comp.isBeingEdited()).toBeFalsy(); + it('should be being edited', () => { + expect(comp.isBeingEdited()).toBeTrue(); }); it('should have a target name', () => { @@ -398,6 +402,7 @@ describe('ResourcePolicyFormComponent test suite', () => { type: 'group', uuid: GroupMock.id }; + eventPayload.updateTarget = false; scheduler = getTestScheduler(); scheduler.schedule(() => comp.onSubmit()); diff --git a/src/app/shared/resource-policies/form/resource-policy-form.component.ts b/src/app/shared/resource-policies/form/resource-policy-form.component.ts index ea49433db0e..2783200d8f4 100644 --- a/src/app/shared/resource-policies/form/resource-policy-form.component.ts +++ b/src/app/shared/resource-policies/form/resource-policy-form.component.ts @@ -49,6 +49,7 @@ export interface ResourcePolicyEvent { type: string, uuid: string }; + updateTarget: boolean; } @Component({ @@ -130,6 +131,8 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy { navActiveId: string; + resourcePolicyTargetUpdated = false; + /** * Initialize instance variables * @@ -278,6 +281,7 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy { * Update reference to the eperson or group that will be granted the permission */ updateObjectSelected(object: DSpaceObject, isEPerson: boolean): void { + this.resourcePolicyTargetUpdated = true; this.resourcePolicyGrant = object; this.resourcePolicyGrantType = isEPerson ? 'eperson' : 'group'; this.resourcePolicyTargetName$.next(this.getResourcePolicyTargetName()); @@ -304,6 +308,7 @@ export class ResourcePolicyFormComponent implements OnInit, OnDestroy { type: this.resourcePolicyGrantType, uuid: this.resourcePolicyGrant.id }; + eventPayload.updateTarget = this.resourcePolicyTargetUpdated; this.submit.emit(eventPayload); }); } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index a7ce942e7d0..dfc715b72b1 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3136,6 +3136,16 @@ "resource-policies.form.eperson-group-list.table.headers.name": "Name", + "resource-policies.form.eperson-group-list.modal.header": "Cannot change type", + + "resource-policies.form.eperson-group-list.modal.text1.toGroup": "It is not possible to replace an ePerson with a group.", + + "resource-policies.form.eperson-group-list.modal.text1.toEPerson": "It is not possible to replace a group with an ePerson.", + + "resource-policies.form.eperson-group-list.modal.text2": "Delete the current resource policy and create a new one with the desired type.", + + "resource-policies.form.eperson-group-list.modal.close": "Ok", + "resource-policies.form.date.end.label": "End Date", "resource-policies.form.date.start.label": "Start Date", From 833637c215afa64389a6ee47738ee27d6907f4b6 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Tue, 3 May 2022 14:10:33 +1200 Subject: [PATCH 0314/2129] [TLC-254] Get Type Bind config from backend --- config/config.example.yml | 5 --- .../ds-dynamic-type-bind-relation.service.ts | 8 ++-- .../form/builder/form-builder.service.spec.ts | 26 ++++++++++- .../form/builder/form-builder.service.ts | 43 ++++++++++++++++--- .../builder/parsers/concat-field-parser.ts | 2 +- .../builder/parsers/date-field-parser.spec.ts | 3 +- .../parsers/disabled-field-parser.spec.ts | 3 +- .../parsers/dropdown-field-parser.spec.ts | 3 +- .../builder/parsers/dropdown-field-parser.ts | 4 +- .../form/builder/parsers/field-parser.ts | 18 ++++---- .../builder/parsers/list-field-parser.spec.ts | 3 +- .../parsers/lookup-field-parser.spec.ts | 3 +- .../parsers/lookup-name-field-parser.spec.ts | 3 +- .../builder/parsers/name-field-parser.spec.ts | 3 +- .../parsers/onebox-field-parser.spec.ts | 3 +- .../form/builder/parsers/parser-options.ts | 1 + .../relation-group-field-parser.spec.ts | 3 +- .../form/builder/parsers/row-parser.spec.ts | 23 +++++----- .../shared/form/builder/parsers/row-parser.ts | 6 ++- .../parsers/series-field-parser.spec.ts | 3 +- .../builder/parsers/tag-field-parser.spec.ts | 3 +- .../parsers/textarea-field-parser.spec.ts | 3 +- src/app/submission/submission.module.ts | 3 +- 23 files changed, 123 insertions(+), 52 deletions(-) diff --git a/config/config.example.yml b/config/config.example.yml index fb0b4fd589c..771c7b16530 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -77,11 +77,6 @@ submission: # NOTE: after how many time (milliseconds) submission is saved automatically # eg. timer: 5 * (1000 * 60); // 5 minutes timer: 0 - typeBind: - # NOTE: which field to use when matching to type-bind configuration, - # eg. dc.type, local.publicationType - # default: dc.type - field: dc.type icons: metadata: # NOTE: example of configuration diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts index c9473bd9d26..39f754af24b 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts @@ -2,7 +2,7 @@ import { Inject, Injectable, Injector, Optional } from '@angular/core'; import { FormControl } from '@angular/forms'; import { Subscription } from 'rxjs'; -import { startWith } from 'rxjs/operators'; +import {map, startWith} from 'rxjs/operators'; import { AND_OPERATOR, @@ -15,10 +15,12 @@ import { OR_OPERATOR } from '@ng-dynamic-forms/core'; -import { hasNoValue, hasValue } from '../../../empty.util'; +import {hasNoValue, hasValue, isEmpty} from '../../../empty.util'; import { FormBuilderService } from '../form-builder.service'; import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from './ds-dynamic-form-constants'; +import {getFirstCompletedRemoteData} from "../../../../core/shared/operators"; +import {ConfigurationDataService} from "../../../../core/data/configuration-data.service"; /** * Service to manage type binding for submission input fields @@ -31,7 +33,6 @@ export class DsDynamicTypeBindRelationService { protected dynamicFormRelationService: DynamicFormRelationService, protected formBuilderService: FormBuilderService, protected injector: Injector) { - } /** @@ -53,6 +54,7 @@ export class DsDynamicTypeBindRelationService { return value; } + /** * Get models for this bind type * @param model diff --git a/src/app/shared/form/builder/form-builder.service.spec.ts b/src/app/shared/form/builder/form-builder.service.spec.ts index 14c4e336cd1..d2cd887e820 100644 --- a/src/app/shared/form/builder/form-builder.service.spec.ts +++ b/src/app/shared/form/builder/form-builder.service.spec.ts @@ -48,12 +48,18 @@ import { DynamicConcatModel } from './ds-dynamic-form-ui/models/ds-dynamic-conca import { DynamicLookupNameModel } from './ds-dynamic-form-ui/models/lookup/dynamic-lookup-name.model'; import { DynamicRowArrayModel } from './ds-dynamic-form-ui/models/ds-dynamic-row-array-model'; import { FormRowModel } from '../../../core/config/models/config-submission-form.model'; +import {ConfigurationDataService} from "../../../core/data/configuration-data.service"; +import {createSuccessfulRemoteDataObject$} from "../../remote-data.utils"; +import {ConfigurationProperty} from "../../../core/shared/configuration-property.model"; describe('FormBuilderService test suite', () => { let testModel: DynamicFormControlModel[]; let testFormConfiguration: SubmissionFormsModel; let service: FormBuilderService; + let configSpy: ConfigurationDataService; + const typeFieldProp = 'submit.type-bind.field'; + const typeFieldTestValue = 'dc.type'; const submissionId = '1234'; @@ -65,15 +71,24 @@ describe('FormBuilderService test suite', () => { return new Promise((resolve) => setTimeout(() => resolve(true), 0)); } - beforeEach(() => { + const createConfigSuccessSpy = (...values: string[]) => jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$({ + ... new ConfigurationProperty(), + name: typeFieldProp, + values: values, + }), + }); + beforeEach(() => { + configSpy = createConfigSuccessSpy(typeFieldTestValue); TestBed.configureTestingModule({ imports: [ReactiveFormsModule], providers: [ { provide: FormBuilderService, useClass: FormBuilderService }, { provide: DynamicFormValidationService, useValue: {} }, { provide: NG_VALIDATORS, useValue: testValidator, multi: true }, - { provide: NG_ASYNC_VALIDATORS, useValue: testAsyncValidator, multi: true } + { provide: NG_ASYNC_VALIDATORS, useValue: testAsyncValidator, multi: true }, + { provide: ConfigurationDataService, useValue: configSpy } ] }); @@ -881,4 +896,11 @@ describe('FormBuilderService test suite', () => { expect(formArray.length === 0).toBe(true); }); + it(`should request the ${typeFieldProp} property and set value "dc_type"`, () => { + service.setTypeBindFieldFromConfig(); + expect(configSpy.findByPropertyName).toHaveBeenCalledTimes(1); + expect(configSpy.findByPropertyName).toHaveBeenCalledWith(typeFieldProp); + expect(service.getTypeField()).toEqual('dc_type'); + }); + }); diff --git a/src/app/shared/form/builder/form-builder.service.ts b/src/app/shared/form/builder/form-builder.service.ts index 532a4fe0856..9cca31e7555 100644 --- a/src/app/shared/form/builder/form-builder.service.ts +++ b/src/app/shared/form/builder/form-builder.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@angular/core'; +import {Injectable, Optional} from '@angular/core'; import { AbstractControl, FormControl, FormGroup } from '@angular/forms'; import { @@ -42,6 +42,8 @@ import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from './ds-dynamic-form-ui/d import { CONCAT_GROUP_SUFFIX, DynamicConcatModel } from './ds-dynamic-form-ui/models/ds-dynamic-concat.model'; import { VIRTUAL_METADATA_PREFIX } from '../../../core/shared/metadata.models'; import { environment } from '../../../../environments/environment'; +import {ConfigurationDataService} from "../../../core/data/configuration-data.service"; +import {getFirstCompletedRemoteData} from "../../../core/shared/operators"; @Injectable() export class FormBuilderService extends DynamicFormService { @@ -66,13 +68,17 @@ export class FormBuilderService extends DynamicFormService { constructor( componentService: DynamicFormComponentService, validationService: DynamicFormValidationService, - protected rowParser: RowParser + protected rowParser: RowParser, + @Optional() protected configService: ConfigurationDataService, ) { super(componentService, validationService); this.formModels = new Map(); this.formGroups = new Map(); - // Replace . with _ in configured type field here, to make configuration more simple and user-friendly - this.typeField = environment.submission.typeBind.field.replace(/\./g, '_'); + if (hasValue(configService)) { + this.setTypeBindFieldFromConfig(); + } else { + this.typeField = 'dc_type'; + } } createDynamicFormControlEvent(control: FormControl, group: FormGroup, model: DynamicFormControlModel, type: string): DynamicFormControlEvent { @@ -278,7 +284,8 @@ export class FormBuilderService extends DynamicFormService { const rawData = typeof json === 'string' ? JSON.parse(json, parseReviver) : json; if (rawData.rows && !isEmpty(rawData.rows)) { rawData.rows.forEach((currentRow) => { - const rowParsed = this.rowParser.parse(submissionId, currentRow, scopeUUID, sectionData, submissionScope, readOnly); + const rowParsed = this.rowParser.parse(submissionId, currentRow, scopeUUID, sectionData, submissionScope, + readOnly, this.typeField); if (isNotNull(rowParsed)) { if (Array.isArray(rowParsed)) { rows = rows.concat(rowParsed); @@ -489,4 +496,30 @@ export class FormBuilderService extends DynamicFormService { return Object.keys(result); } + /** + * Get the type bind field from config + */ + setTypeBindFieldFromConfig(): void { + this.configService.findByPropertyName('submit.type-bind.field').pipe( + getFirstCompletedRemoteData(), + ).subscribe((remoteData: any) => { + // make sure we got a success response from the backend + if (!remoteData.hasSucceeded) { + this.typeField = 'dc_type'; + return; + } + // Read type bind value from response and set if non-empty + const typeFieldConfig = remoteData.payload.values[0]; + if (isEmpty(typeFieldConfig)) { + this.typeField = 'dc_type'; + } else { + this.typeField = typeFieldConfig.replace(/\./g, '_'); + } + }); + } + + getTypeField(): string { + return this.typeField; + } + } diff --git a/src/app/shared/form/builder/parsers/concat-field-parser.ts b/src/app/shared/form/builder/parsers/concat-field-parser.ts index 80859244226..2de5f256dc7 100644 --- a/src/app/shared/form/builder/parsers/concat-field-parser.ts +++ b/src/app/shared/form/builder/parsers/concat-field-parser.ts @@ -1,4 +1,4 @@ -import { Inject } from '@angular/core'; +import {Inject} from '@angular/core'; import { FormFieldModel } from '../models/form-field.model'; import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; import { diff --git a/src/app/shared/form/builder/parsers/date-field-parser.spec.ts b/src/app/shared/form/builder/parsers/date-field-parser.spec.ts index b9adf3ed65c..9ab43709ad0 100644 --- a/src/app/shared/form/builder/parsers/date-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/date-field-parser.spec.ts @@ -12,7 +12,8 @@ describe('DateFieldParser test suite', () => { const parserOptions: ParserOptions = { readOnly: false, submissionScope: null, - collectionUUID: null + collectionUUID: null, + typeField: 'dc_type' }; beforeEach(() => { diff --git a/src/app/shared/form/builder/parsers/disabled-field-parser.spec.ts b/src/app/shared/form/builder/parsers/disabled-field-parser.spec.ts index e3e86d7051c..d69f0e48e90 100644 --- a/src/app/shared/form/builder/parsers/disabled-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/disabled-field-parser.spec.ts @@ -11,7 +11,8 @@ describe('DisabledFieldParser test suite', () => { const parserOptions: ParserOptions = { readOnly: false, submissionScope: null, - collectionUUID: null + collectionUUID: null, + typeField: 'dc_type' }; beforeEach(() => { diff --git a/src/app/shared/form/builder/parsers/dropdown-field-parser.spec.ts b/src/app/shared/form/builder/parsers/dropdown-field-parser.spec.ts index 82d2aeac63b..3dca7558b34 100644 --- a/src/app/shared/form/builder/parsers/dropdown-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/dropdown-field-parser.spec.ts @@ -11,7 +11,8 @@ describe('DropdownFieldParser test suite', () => { const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', - collectionUUID: null + collectionUUID: null, + typeField: 'dc_type' }; beforeEach(() => { diff --git a/src/app/shared/form/builder/parsers/dropdown-field-parser.ts b/src/app/shared/form/builder/parsers/dropdown-field-parser.ts index 760fc634827..3e5ec0b9daa 100644 --- a/src/app/shared/form/builder/parsers/dropdown-field-parser.ts +++ b/src/app/shared/form/builder/parsers/dropdown-field-parser.ts @@ -1,4 +1,4 @@ -import { Inject } from '@angular/core'; +import {Inject} from '@angular/core'; import { FormFieldModel } from '../models/form-field.model'; import { CONFIG_DATA, @@ -22,7 +22,7 @@ export class DropdownFieldParser extends FieldParser { @Inject(SUBMISSION_ID) submissionId: string, @Inject(CONFIG_DATA) configData: FormFieldModel, @Inject(INIT_FORM_VALUES) initFormValues, - @Inject(PARSER_OPTIONS) parserOptions: ParserOptions + @Inject(PARSER_OPTIONS) parserOptions: ParserOptions, ) { super(submissionId, configData, initFormValues, parserOptions); } diff --git a/src/app/shared/form/builder/parsers/field-parser.ts b/src/app/shared/form/builder/parsers/field-parser.ts index c8b8e07bad9..35743ec9b7e 100644 --- a/src/app/shared/form/builder/parsers/field-parser.ts +++ b/src/app/shared/form/builder/parsers/field-parser.ts @@ -1,9 +1,9 @@ -import { Inject, InjectionToken } from '@angular/core'; +import {Inject, InjectionToken} from '@angular/core'; import { uniqueId } from 'lodash'; import {DynamicFormControlLayout, DynamicFormControlRelation, MATCH_VISIBLE, OR_OPERATOR} from '@ng-dynamic-forms/core'; -import { hasValue, isNotEmpty, isNotNull, isNotUndefined } from '../../../empty.util'; +import {hasValue, isEmpty, isNotEmpty, isNotNull, isNotUndefined} from '../../../empty.util'; import { FormFieldModel } from '../models/form-field.model'; import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; import { @@ -18,6 +18,8 @@ import { VocabularyOptions } from '../../../../core/submission/vocabularies/mode import { ParserType } from './parser-type'; import { isNgbDateStruct } from '../../../date.util'; import { environment } from '../../../../../environments/environment'; +import {getFirstCompletedRemoteData} from "../../../../core/shared/operators"; +import {map} from "rxjs/operators"; export const SUBMISSION_ID: InjectionToken = new InjectionToken('submissionId'); export const CONFIG_DATA: InjectionToken = new InjectionToken('configData'); @@ -39,8 +41,6 @@ export abstract class FieldParser { @Inject(INIT_FORM_VALUES) protected initFormValues: any, @Inject(PARSER_OPTIONS) protected parserOptions: ParserOptions ) { - // Replace . with _ in configured type field here, to make configuration more simple and user-friendly - this.typeField = environment.submission.typeBind.field.replace(/\./g, '_'); } public abstract modelFactory(fieldValue?: FormFieldMetadataValueObject, label?: boolean): any; @@ -75,7 +75,8 @@ export abstract class FieldParser { metadataFields: this.getAllFieldIds(), hasSelectableMetadata: isNotEmpty(this.configData.selectableMetadata), isDraggable, - typeBindRelations: isNotEmpty(this.configData.typeBind) ? this.getTypeBindRelations(this.configData.typeBind) : null, + typeBindRelations: isNotEmpty(this.configData.typeBind) ? this.getTypeBindRelations(this.configData.typeBind, + this.parserOptions.typeField) : null, groupFactory: () => { let model; if ((arrayCounter === 0)) { @@ -303,7 +304,8 @@ export abstract class FieldParser { // If typeBind is configured if (isNotEmpty(this.configData.typeBind)) { - (controlModel as DsDynamicInputModel).typeBindRelations = this.getTypeBindRelations(this.configData.typeBind); + (controlModel as DsDynamicInputModel).typeBindRelations = this.getTypeBindRelations(this.configData.typeBind, + this.parserOptions.typeField); } return controlModel; @@ -319,11 +321,11 @@ export abstract class FieldParser { * @private * @return DynamicFormControlRelation[] array with one relation in it, for type bind matching to show a field */ - private getTypeBindRelations(configuredTypeBindValues: string[]): DynamicFormControlRelation[] { + private getTypeBindRelations(configuredTypeBindValues: string[], typeField: string): DynamicFormControlRelation[] { const bindValues = []; configuredTypeBindValues.forEach((value) => { bindValues.push({ - id: this.typeField, + id: typeField, value: value }); }); diff --git a/src/app/shared/form/builder/parsers/list-field-parser.spec.ts b/src/app/shared/form/builder/parsers/list-field-parser.spec.ts index 8a05b169fd3..30d1913a519 100644 --- a/src/app/shared/form/builder/parsers/list-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/list-field-parser.spec.ts @@ -13,7 +13,8 @@ describe('ListFieldParser test suite', () => { const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', - collectionUUID: null + collectionUUID: null, + typeField: 'dc_type' }; beforeEach(() => { diff --git a/src/app/shared/form/builder/parsers/lookup-field-parser.spec.ts b/src/app/shared/form/builder/parsers/lookup-field-parser.spec.ts index 87cee9d950d..24efcf34622 100644 --- a/src/app/shared/form/builder/parsers/lookup-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/lookup-field-parser.spec.ts @@ -12,7 +12,8 @@ describe('LookupFieldParser test suite', () => { const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', - collectionUUID: null + collectionUUID: null, + typeField: 'dc_type' }; beforeEach(() => { diff --git a/src/app/shared/form/builder/parsers/lookup-name-field-parser.spec.ts b/src/app/shared/form/builder/parsers/lookup-name-field-parser.spec.ts index 3d02b6952ef..d0281681ef6 100644 --- a/src/app/shared/form/builder/parsers/lookup-name-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/lookup-name-field-parser.spec.ts @@ -12,7 +12,8 @@ describe('LookupNameFieldParser test suite', () => { const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', - collectionUUID: null + collectionUUID: null, + typeField: 'dc_type' }; beforeEach(() => { diff --git a/src/app/shared/form/builder/parsers/name-field-parser.spec.ts b/src/app/shared/form/builder/parsers/name-field-parser.spec.ts index 514585f03f7..6b520142cc4 100644 --- a/src/app/shared/form/builder/parsers/name-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/name-field-parser.spec.ts @@ -14,7 +14,8 @@ describe('NameFieldParser test suite', () => { const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', - collectionUUID: null + collectionUUID: null, + typeField: 'dc_type' }; beforeEach(() => { diff --git a/src/app/shared/form/builder/parsers/onebox-field-parser.spec.ts b/src/app/shared/form/builder/parsers/onebox-field-parser.spec.ts index 8ecce241947..e7e68a6461b 100644 --- a/src/app/shared/form/builder/parsers/onebox-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/onebox-field-parser.spec.ts @@ -15,7 +15,8 @@ describe('OneboxFieldParser test suite', () => { const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', - collectionUUID: null + collectionUUID: null, + typeField: 'dc_type' }; beforeEach(() => { diff --git a/src/app/shared/form/builder/parsers/parser-options.ts b/src/app/shared/form/builder/parsers/parser-options.ts index 8b0b42008e7..f7aac3449d7 100644 --- a/src/app/shared/form/builder/parsers/parser-options.ts +++ b/src/app/shared/form/builder/parsers/parser-options.ts @@ -2,4 +2,5 @@ export interface ParserOptions { readOnly: boolean; submissionScope: string; collectionUUID: string; + typeField: string; } diff --git a/src/app/shared/form/builder/parsers/relation-group-field-parser.spec.ts b/src/app/shared/form/builder/parsers/relation-group-field-parser.spec.ts index 111193a6375..7d48ad2d002 100644 --- a/src/app/shared/form/builder/parsers/relation-group-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/relation-group-field-parser.spec.ts @@ -12,7 +12,8 @@ describe('RelationGroupFieldParser test suite', () => { const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', - collectionUUID: 'WORKSPACE' + collectionUUID: 'WORKSPACE', + typeField: 'dc_type' }; beforeEach(() => { diff --git a/src/app/shared/form/builder/parsers/row-parser.spec.ts b/src/app/shared/form/builder/parsers/row-parser.spec.ts index e612534d55a..1f9bde8a7fb 100644 --- a/src/app/shared/form/builder/parsers/row-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/row-parser.spec.ts @@ -22,6 +22,7 @@ describe('RowParser test suite', () => { const initFormValues = {}; const submissionScope = 'WORKSPACE'; const readOnly = false; + const typeField = 'dc_type'; beforeEach(() => { row1 = { @@ -338,7 +339,7 @@ describe('RowParser test suite', () => { it('should return a DynamicRowGroupModel object', () => { const parser = new RowParser(undefined); - const rowModel = parser.parse(submissionId, row1, scopeUUID, initFormValues, submissionScope, readOnly); + const rowModel = parser.parse(submissionId, row1, scopeUUID, initFormValues, submissionScope, readOnly, typeField); expect(rowModel instanceof DynamicRowGroupModel).toBe(true); }); @@ -346,7 +347,7 @@ describe('RowParser test suite', () => { it('should return a row with three fields', () => { const parser = new RowParser(undefined); - const rowModel = parser.parse(submissionId, row1, scopeUUID, initFormValues, submissionScope, readOnly); + const rowModel = parser.parse(submissionId, row1, scopeUUID, initFormValues, submissionScope, readOnly, typeField); expect((rowModel as DynamicRowGroupModel).group.length).toBe(3); }); @@ -354,7 +355,7 @@ describe('RowParser test suite', () => { it('should return a DynamicRowArrayModel object', () => { const parser = new RowParser(undefined); - const rowModel = parser.parse(submissionId, row2, scopeUUID, initFormValues, submissionScope, readOnly); + const rowModel = parser.parse(submissionId, row2, scopeUUID, initFormValues, submissionScope, readOnly, typeField); expect(rowModel instanceof DynamicRowArrayModel).toBe(true); }); @@ -362,7 +363,7 @@ describe('RowParser test suite', () => { it('should return a row that contains only scoped fields', () => { const parser = new RowParser(undefined); - const rowModel = parser.parse(submissionId, row3, scopeUUID, initFormValues, submissionScope, readOnly); + const rowModel = parser.parse(submissionId, row3, scopeUUID, initFormValues, submissionScope, readOnly, typeField); expect((rowModel as DynamicRowGroupModel).group.length).toBe(1); }); @@ -370,7 +371,7 @@ describe('RowParser test suite', () => { it('should be able to parse a dropdown combo field', () => { const parser = new RowParser(undefined); - const rowModel = parser.parse(submissionId, row4, scopeUUID, initFormValues, submissionScope, readOnly); + const rowModel = parser.parse(submissionId, row4, scopeUUID, initFormValues, submissionScope, readOnly, typeField); expect(rowModel).toBeDefined(); }); @@ -378,7 +379,7 @@ describe('RowParser test suite', () => { it('should be able to parse a lookup-name field', () => { const parser = new RowParser(undefined); - const rowModel = parser.parse(submissionId, row5, scopeUUID, initFormValues, submissionScope, readOnly); + const rowModel = parser.parse(submissionId, row5, scopeUUID, initFormValues, submissionScope, readOnly, typeField); expect(rowModel).toBeDefined(); }); @@ -386,7 +387,7 @@ describe('RowParser test suite', () => { it('should be able to parse a list field', () => { const parser = new RowParser(undefined); - const rowModel = parser.parse(submissionId, row6, scopeUUID, initFormValues, submissionScope, readOnly); + const rowModel = parser.parse(submissionId, row6, scopeUUID, initFormValues, submissionScope, readOnly, typeField); expect(rowModel).toBeDefined(); }); @@ -394,7 +395,7 @@ describe('RowParser test suite', () => { it('should be able to parse a date field', () => { const parser = new RowParser(undefined); - const rowModel = parser.parse(submissionId, row7, scopeUUID, initFormValues, submissionScope, readOnly); + const rowModel = parser.parse(submissionId, row7, scopeUUID, initFormValues, submissionScope, readOnly, typeField); expect(rowModel).toBeDefined(); }); @@ -402,7 +403,7 @@ describe('RowParser test suite', () => { it('should be able to parse a tag field', () => { const parser = new RowParser(undefined); - const rowModel = parser.parse(submissionId, row8, scopeUUID, initFormValues, submissionScope, readOnly); + const rowModel = parser.parse(submissionId, row8, scopeUUID, initFormValues, submissionScope, readOnly, typeField); expect(rowModel).toBeDefined(); }); @@ -410,7 +411,7 @@ describe('RowParser test suite', () => { it('should be able to parse a textarea field', () => { const parser = new RowParser(undefined); - const rowModel = parser.parse(submissionId, row9, scopeUUID, initFormValues, submissionScope, readOnly); + const rowModel = parser.parse(submissionId, row9, scopeUUID, initFormValues, submissionScope, readOnly, typeField); expect(rowModel).toBeDefined(); }); @@ -418,7 +419,7 @@ describe('RowParser test suite', () => { it('should be able to parse a group field', () => { const parser = new RowParser(undefined); - const rowModel = parser.parse(submissionId, row10, scopeUUID, initFormValues, submissionScope, readOnly); + const rowModel = parser.parse(submissionId, row10, scopeUUID, initFormValues, submissionScope, readOnly, typeField); expect(rowModel).toBeDefined(); }); diff --git a/src/app/shared/form/builder/parsers/row-parser.ts b/src/app/shared/form/builder/parsers/row-parser.ts index fe664305b01..764f52ffdf0 100644 --- a/src/app/shared/form/builder/parsers/row-parser.ts +++ b/src/app/shared/form/builder/parsers/row-parser.ts @@ -31,7 +31,8 @@ export class RowParser { scopeUUID, initFormValues: any, submissionScope, - readOnly: boolean): DynamicRowGroupModel { + readOnly: boolean, + typeField: string): DynamicRowGroupModel { let fieldModel: any = null; let parsedResult = null; const config: DynamicFormGroupModelConfig = { @@ -47,7 +48,8 @@ export class RowParser { const parserOptions: ParserOptions = { readOnly: readOnly, submissionScope: submissionScope, - collectionUUID: scopeUUID + collectionUUID: scopeUUID, + typeField: typeField }; // Iterate over row's fields diff --git a/src/app/shared/form/builder/parsers/series-field-parser.spec.ts b/src/app/shared/form/builder/parsers/series-field-parser.spec.ts index b044f43833a..0761cfe60e2 100644 --- a/src/app/shared/form/builder/parsers/series-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/series-field-parser.spec.ts @@ -12,7 +12,8 @@ describe('SeriesFieldParser test suite', () => { const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', - collectionUUID: null + collectionUUID: null, + typeField: 'dc_type' }; beforeEach(() => { diff --git a/src/app/shared/form/builder/parsers/tag-field-parser.spec.ts b/src/app/shared/form/builder/parsers/tag-field-parser.spec.ts index 7c63235f678..115829f8d38 100644 --- a/src/app/shared/form/builder/parsers/tag-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/tag-field-parser.spec.ts @@ -12,7 +12,8 @@ describe('TagFieldParser test suite', () => { const parserOptions: ParserOptions = { readOnly: false, submissionScope: 'testScopeUUID', - collectionUUID: null + collectionUUID: null, + typeField: 'dc_type' }; beforeEach(() => { diff --git a/src/app/shared/form/builder/parsers/textarea-field-parser.spec.ts b/src/app/shared/form/builder/parsers/textarea-field-parser.spec.ts index a81907aa131..855e464f21d 100644 --- a/src/app/shared/form/builder/parsers/textarea-field-parser.spec.ts +++ b/src/app/shared/form/builder/parsers/textarea-field-parser.spec.ts @@ -12,7 +12,8 @@ describe('TextareaFieldParser test suite', () => { const parserOptions: ParserOptions = { readOnly: false, submissionScope: null, - collectionUUID: null + collectionUUID: null, + typeField: 'dc_type' }; beforeEach(() => { diff --git a/src/app/submission/submission.module.ts b/src/app/submission/submission.module.ts index 939d1bff292..d9b83d98640 100644 --- a/src/app/submission/submission.module.ts +++ b/src/app/submission/submission.module.ts @@ -42,6 +42,7 @@ import { NgbAccordionModule, NgbModalModule } from '@ng-bootstrap/ng-bootstrap'; import { SubmissionSectionAccessesComponent } from './sections/accesses/section-accesses.component'; import { SubmissionAccessesConfigService } from '../core/config/submission-accesses-config.service'; import { SectionAccessesService } from './sections/accesses/section-accesses.service'; +import {ConfigurationDataService} from "../core/data/configuration-data.service"; const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator @@ -97,7 +98,7 @@ const DECLARATIONS = [ SectionsService, SubmissionUploadsConfigService, SubmissionAccessesConfigService, - SectionAccessesService + SectionAccessesService, ] }) From fd0c8f409e061487c6b57a1a50c18c0c9f3166f5 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Tue, 3 May 2022 14:11:02 +1200 Subject: [PATCH 0315/2129] [TLC-254] Tests for isObjectEmpty() --- src/app/shared/empty.util.spec.ts | 39 ++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/app/shared/empty.util.spec.ts b/src/app/shared/empty.util.spec.ts index 1112883c2aa..7516e08ca77 100644 --- a/src/app/shared/empty.util.spec.ts +++ b/src/app/shared/empty.util.spec.ts @@ -9,7 +9,7 @@ import { isNotEmptyOperator, isNotNull, isNotUndefined, - isNull, + isNull, isObjectEmpty, isUndefined } from './empty.util'; @@ -444,6 +444,43 @@ describe('Empty Utils', () => { }); }); + describe('isObjectEmpty', () => { + /* + isObjectEmpty(); // true + isObjectEmpty(null); // true + isObjectEmpty(undefined); // true + isObjectEmpty(''); // true + isObjectEmpty([]); // true + isObjectEmpty({}); // true + isObjectEmpty({name: null}); // true + isObjectEmpty({ name: 'Adam Hawkins', surname : null}); // false + */ + it('should be empty if no parameter passed', () => { + expect(isObjectEmpty()).toBeTrue(); + }) + it('should be empty if null parameter passed', () => { + expect(isObjectEmpty(null)).toBeTrue(); + }) + it('should be empty if undefined parameter passed', () => { + expect(isObjectEmpty(undefined)).toBeTrue(); + }) + it('should be empty if empty string passed', () => { + expect(isObjectEmpty('')).toBeTrue(); + }) + it('should be empty if empty array passed', () => { + expect(isObjectEmpty([])).toBeTrue(); + }) + it('should be empty if empty object passed', () => { + expect(isObjectEmpty({})).toBeTrue(); + }) + it('should be empty if single key with null value passed', () => { + expect(isObjectEmpty({ name: null })).toBeTrue(); + }) + it('should NOT be empty if object with at least one non-null value passed', () => { + expect(isObjectEmpty({ name: 'Adam Hawkins', surname : null })).toBeFalse(); + }) + }); + describe('ensureArrayHasValue', () => { it('should let all arrays pass unchanged, and turn everything else in to empty arrays', () => { const sourceData = { From b9b5b50999a3e3173a97709e403c4773839116a5 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Tue, 3 May 2022 08:56:37 +0200 Subject: [PATCH 0316/2129] 89741: Added ThemedExpandableNavbarSectionComponent --- ...med-expandable-navbar-section.component.ts | 29 +++++++++++++++++++ src/app/navbar/navbar.module.ts | 11 +++---- 2 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 src/app/navbar/expandable-navbar-section/themed-expandable-navbar-section.component.ts diff --git a/src/app/navbar/expandable-navbar-section/themed-expandable-navbar-section.component.ts b/src/app/navbar/expandable-navbar-section/themed-expandable-navbar-section.component.ts new file mode 100644 index 00000000000..744eeb5a027 --- /dev/null +++ b/src/app/navbar/expandable-navbar-section/themed-expandable-navbar-section.component.ts @@ -0,0 +1,29 @@ +import { Component } from '@angular/core'; +import { ThemedComponent } from '../../shared/theme-support/themed.component'; +import { ExpandableNavbarSectionComponent } from './expandable-navbar-section.component'; +import { rendersSectionForMenu } from '../../shared/menu/menu-section.decorator'; +import { MenuID } from '../../shared/menu/initial-menus-state'; + +/** + * Themed wrapper for ExpandableNavbarSectionComponent + */ +@Component({ + /* tslint:disable:component-selector */ + selector: 'li[ds-themed-expandable-navbar-section]', + styleUrls: [], + templateUrl: '../../shared/theme-support/themed.component.html', +}) +@rendersSectionForMenu(MenuID.PUBLIC, true) +export class ThemedExpandableNavbarSectionComponent extends ThemedComponent { + protected getComponentName(): string { + return 'ExpandableNavbarSectionComponent'; + } + + protected importThemedComponent(themeName: string): Promise { + return import(`../../../themes/${themeName}/app/navbar/expandable-navbar-section/expandable-navbar-section.component`); + } + + protected importUnthemedComponent(): Promise { + return import(`./expandable-navbar-section.component`); + } +} diff --git a/src/app/navbar/navbar.module.ts b/src/app/navbar/navbar.module.ts index c84e732fd52..95641de41bb 100644 --- a/src/app/navbar/navbar.module.ts +++ b/src/app/navbar/navbar.module.ts @@ -7,6 +7,7 @@ import { CoreModule } from '../core/core.module'; import { NavbarEffects } from './navbar.effects'; import { NavbarSectionComponent } from './navbar-section/navbar-section.component'; import { ExpandableNavbarSectionComponent } from './expandable-navbar-section/expandable-navbar-section.component'; +import { ThemedExpandableNavbarSectionComponent } from './expandable-navbar-section/themed-expandable-navbar-section.component'; import { NavbarComponent } from './navbar.component'; import { MenuModule } from '../shared/menu/menu.module'; import { SharedModule } from '../shared/shared.module'; @@ -20,7 +21,7 @@ const effects = [ const ENTRY_COMPONENTS = [ // put only entry components that use custom decorator NavbarSectionComponent, - ExpandableNavbarSectionComponent, + ThemedExpandableNavbarSectionComponent, ]; @NgModule({ @@ -36,19 +37,19 @@ const ENTRY_COMPONENTS = [ NavbarComponent, ThemedNavbarComponent, NavbarSectionComponent, - ExpandableNavbarSectionComponent + ExpandableNavbarSectionComponent, + ThemedExpandableNavbarSectionComponent, ], providers: [ ], entryComponents: [ - NavbarSectionComponent, - ExpandableNavbarSectionComponent + ...ENTRY_COMPONENTS, ], exports: [ ThemedNavbarComponent, NavbarSectionComponent, - ExpandableNavbarSectionComponent + ThemedExpandableNavbarSectionComponent, ] }) From 22d5643d8b0276922bc6477db29283a6b5360993 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Tue, 3 May 2022 09:32:31 +0200 Subject: [PATCH 0317/2129] 90978: Set klaro cookie before each test --- cypress/support/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cypress/support/index.ts b/cypress/support/index.ts index d9b6409a0d9..024b46cdde6 100644 --- a/cypress/support/index.ts +++ b/cypress/support/index.ts @@ -21,7 +21,7 @@ import './commands'; import 'cypress-axe'; // Runs once before the first test in each "block" -before(() => { +beforeEach(() => { // Pre-agree to all Klaro cookies by setting the klaro-anonymous cookie // This just ensures it doesn't get in the way of matching other objects in the page. cy.setCookie('klaro-anonymous', '{%22authentication%22:true%2C%22preferences%22:true%2C%22acknowledgement%22:true%2C%22google-analytics%22:true}'); From 32a91f64d9d8db83390589628c76882b212c968b Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Tue, 3 May 2022 12:06:48 +0200 Subject: [PATCH 0318/2129] [CST-5535] Refactoring health page --- package.json | 1 - src/app/app-routing-paths.ts | 2 + src/app/app-routing.module.ts | 19 ++- .../health-info-component.component.html | 28 +++ .../health-info-component.component.scss | 0 .../health-info-component.component.spec.ts | 72 ++++++++ .../health-info-component.component.ts | 35 ++++ .../health-info/health-info.component.html | 7 + .../health-info/health-info.component.scss | 0 .../health-info/health-info.component.spec.ts | 37 ++++ .../health-info/health-info.component.ts | 14 ++ .../health-page/health-page.component.html | 21 +++ .../health-page/health-page.component.scss | 0 .../health-page/health-page.component.spec.ts | 72 ++++++++ src/app/health-page/health-page.component.ts | 41 +++++ src/app/health-page/health-page.module.ts | 35 ++++ ...odule.ts => health-page.routing.module.ts} | 19 +-- .../health-component.component.html | 27 +++ .../health-component.component.scss | 0 .../health-component.component.spec.ts | 77 +++++++++ .../health-component.component.ts | 27 +++ .../health-panel/health-panel.component.html | 21 +++ .../health-panel/health-panel.component.scss | 0 .../health-panel.component.spec.ts | 58 +++++++ .../health-panel/health-panel.component.ts | 21 +++ .../health-status.component.html | 6 + .../health-status.component.scss | 0 .../health-status.component.spec.ts | 48 ++++++ .../health-status/health-status.component.ts | 20 +++ src/app/health-page/health.module.ts | 23 --- .../health-page/health/health.component.html | 39 ----- .../health-page/health/health.component.scss | 8 - .../health/health.component.spec.ts | 160 ------------------ .../health-page/health/health.component.ts | 100 ----------- .../models/health-component.model.ts | 48 ++++++ src/app/shared/mocks/health-endpoint.mocks.ts | 140 +++++++++++++++ 36 files changed, 878 insertions(+), 348 deletions(-) create mode 100644 src/app/health-page/health-info/health-info-component/health-info-component.component.html create mode 100644 src/app/health-page/health-info/health-info-component/health-info-component.component.scss create mode 100644 src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts create mode 100644 src/app/health-page/health-info/health-info-component/health-info-component.component.ts create mode 100644 src/app/health-page/health-info/health-info.component.html create mode 100644 src/app/health-page/health-info/health-info.component.scss create mode 100644 src/app/health-page/health-info/health-info.component.spec.ts create mode 100644 src/app/health-page/health-info/health-info.component.ts create mode 100644 src/app/health-page/health-page.component.html create mode 100644 src/app/health-page/health-page.component.scss create mode 100644 src/app/health-page/health-page.component.spec.ts create mode 100644 src/app/health-page/health-page.component.ts create mode 100644 src/app/health-page/health-page.module.ts rename src/app/health-page/{health.routing.module.ts => health-page.routing.module.ts} (57%) create mode 100644 src/app/health-page/health-panel/health-component/health-component.component.html create mode 100644 src/app/health-page/health-panel/health-component/health-component.component.scss create mode 100644 src/app/health-page/health-panel/health-component/health-component.component.spec.ts create mode 100644 src/app/health-page/health-panel/health-component/health-component.component.ts create mode 100644 src/app/health-page/health-panel/health-panel.component.html create mode 100644 src/app/health-page/health-panel/health-panel.component.scss create mode 100644 src/app/health-page/health-panel/health-panel.component.spec.ts create mode 100644 src/app/health-page/health-panel/health-panel.component.ts create mode 100644 src/app/health-page/health-panel/health-status/health-status.component.html create mode 100644 src/app/health-page/health-panel/health-status/health-status.component.scss create mode 100644 src/app/health-page/health-panel/health-status/health-status.component.spec.ts create mode 100644 src/app/health-page/health-panel/health-status/health-status.component.ts delete mode 100644 src/app/health-page/health.module.ts delete mode 100644 src/app/health-page/health/health.component.html delete mode 100644 src/app/health-page/health/health.component.scss delete mode 100644 src/app/health-page/health/health.component.spec.ts delete mode 100644 src/app/health-page/health/health.component.ts create mode 100644 src/app/health-page/models/health-component.model.ts create mode 100644 src/app/shared/mocks/health-endpoint.mocks.ts diff --git a/package.json b/package.json index d6c234ef9eb..75e22b40f35 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,6 @@ "@angular/core": "~13.2.6", "@angular/forms": "~13.2.6", "@angular/localize": "13.2.6", - "@angular/material": "13.3.5", "@angular/platform-browser": "~13.2.6", "@angular/platform-browser-dynamic": "~13.2.6", "@angular/platform-server": "~13.2.6", diff --git a/src/app/app-routing-paths.ts b/src/app/app-routing-paths.ts index 57767b6f3e6..929cdbeaa25 100644 --- a/src/app/app-routing-paths.ts +++ b/src/app/app-routing-paths.ts @@ -116,3 +116,5 @@ export const REQUEST_COPY_MODULE_PATH = 'request-a-copy'; export function getRequestCopyModulePath() { return `/${REQUEST_COPY_MODULE_PATH}`; } + +export const HEALTH_PAGE_PATH = 'health'; diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 80310774c8b..243fe05f59e 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -3,13 +3,16 @@ import { RouterModule } from '@angular/router'; import { AuthBlockingGuard } from './core/auth/auth-blocking.guard'; import { AuthenticatedGuard } from './core/auth/authenticated.guard'; -import { SiteAdministratorGuard } from './core/data/feature-authorization/feature-authorization-guard/site-administrator.guard'; +import { + SiteAdministratorGuard +} from './core/data/feature-authorization/feature-authorization-guard/site-administrator.guard'; import { ACCESS_CONTROL_MODULE_PATH, ADMIN_MODULE_PATH, BITSTREAM_MODULE_PATH, FORBIDDEN_PATH, FORGOT_PASSWORD_PATH, + HEALTH_PAGE_PATH, INFO_MODULE_PATH, INTERNAL_SERVER_ERROR, LEGACY_BITSTREAM_MODULE_PATH, @@ -27,8 +30,12 @@ import { EndUserAgreementCurrentUserGuard } from './core/end-user-agreement/end- import { SiteRegisterGuard } from './core/data/feature-authorization/feature-authorization-guard/site-register.guard'; import { ThemedPageNotFoundComponent } from './pagenotfound/themed-pagenotfound.component'; import { ThemedForbiddenComponent } from './forbidden/themed-forbidden.component'; -import { GroupAdministratorGuard } from './core/data/feature-authorization/feature-authorization-guard/group-administrator.guard'; -import { ThemedPageInternalServerErrorComponent } from './page-internal-server-error/themed-page-internal-server-error.component'; +import { + GroupAdministratorGuard +} from './core/data/feature-authorization/feature-authorization-guard/group-administrator.guard'; +import { + ThemedPageInternalServerErrorComponent +} from './page-internal-server-error/themed-page-internal-server-error.component'; import { ServerCheckGuard } from './core/server-check/server-check.guard'; @NgModule({ @@ -209,9 +216,9 @@ import { ServerCheckGuard } from './core/server-check/server-check.guard'; .then((m) => m.StatisticsPageRoutingModule) }, { - path: 'health', - loadChildren: () => import('./health-page/health.module') - .then((m) => m.HealthModule) + path: HEALTH_PAGE_PATH, + loadChildren: () => import('./health-page/health-page.module') + .then((m) => m.HealthPageModule) }, { path: ACCESS_CONTROL_MODULE_PATH, diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.html b/src/app/health-page/health-info/health-info-component/health-info-component.component.html new file mode 100644 index 00000000000..55c1b3372f9 --- /dev/null +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.html @@ -0,0 +1,28 @@ + +
+
+ +
+ + +
+
+
+
+
+ +
+
+
+
+
+ +

{{ healthInfoComponentName | titlecase }} : {{healthInfoComponent}}

+
diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.scss b/src/app/health-page/health-info/health-info-component/health-info-component.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts b/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts new file mode 100644 index 00000000000..2297007cd5e --- /dev/null +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts @@ -0,0 +1,72 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { By } from '@angular/platform-browser'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; + +import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap'; + +import { HealthInfoComponentComponent } from './health-info-component.component'; +import { HealthInfoComponentOne, HealthInfoComponentTwo } from '../../../shared/mocks/health-endpoint.mocks'; +import { ObjNgFor } from '../../../shared/utils/object-ngfor.pipe'; + +describe('HealthInfoComponentComponent', () => { + let component: HealthInfoComponentComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ + CommonModule, + NgbCollapseModule, + NoopAnimationsModule + ], + declarations: [ + HealthInfoComponentComponent, + ObjNgFor + ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HealthInfoComponentComponent); + component = fixture.componentInstance; + }); + + describe('when has nested components', () => { + beforeEach(() => { + component.healthInfoComponentName = 'App'; + component.healthInfoComponent = HealthInfoComponentOne; + component.isCollapsed = false; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should display property', () => { + const components = fixture.debugElement.queryAll(By.css('[data-test="component"]')); + expect(components.length).toBe(4); + }); + + }); + + describe('when has plain properties', () => { + beforeEach(() => { + component.healthInfoComponentName = 'Java'; + component.healthInfoComponent = HealthInfoComponentTwo; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should display property', () => { + const property = fixture.debugElement.queryAll(By.css('[data-test="property"]')); + expect(property.length).toBe(1); + }); + + }); +}); diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.ts b/src/app/health-page/health-info/health-info-component/health-info-component.component.ts new file mode 100644 index 00000000000..b6c31214c8f --- /dev/null +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.ts @@ -0,0 +1,35 @@ +import { Component, Input } from '@angular/core'; + +import { HealthInfoComponent } from '../../models/health-component.model'; + +@Component({ + selector: 'ds-health-info-component', + templateUrl: './health-info-component.component.html', + styleUrls: ['./health-info-component.component.scss'] +}) +export class HealthInfoComponentComponent { + + /** + * The HealthInfoComponent object to display + */ + @Input() healthInfoComponent: HealthInfoComponent|string; + + /** + * The HealthInfoComponent object name + */ + @Input() healthInfoComponentName: string; + + /** + * A boolean representing if div should start collapsed + */ + @Input() isNested = false; + + /** + * A boolean representing if div should start collapsed + */ + public isCollapsed = true; + + isPlainProperty(entry: HealthInfoComponent | string): boolean { + return typeof entry === 'string'; + } +} diff --git a/src/app/health-page/health-info/health-info.component.html b/src/app/health-page/health-info/health-info.component.html new file mode 100644 index 00000000000..e4d29adf548 --- /dev/null +++ b/src/app/health-page/health-info/health-info.component.html @@ -0,0 +1,7 @@ + +
+ +
+
diff --git a/src/app/health-page/health-info/health-info.component.scss b/src/app/health-page/health-info/health-info.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/health-page/health-info/health-info.component.spec.ts b/src/app/health-page/health-info/health-info.component.spec.ts new file mode 100644 index 00000000000..3af1d71db3b --- /dev/null +++ b/src/app/health-page/health-info/health-info.component.spec.ts @@ -0,0 +1,37 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HealthInfoComponent } from './health-info.component'; +import { HealthInfoResponseObj } from '../../shared/mocks/health-endpoint.mocks'; +import { ObjNgFor } from '../../shared/utils/object-ngfor.pipe'; +import { By } from '@angular/platform-browser'; + +describe('HealthInfoComponent', () => { + let component: HealthInfoComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ + HealthInfoComponent, + ObjNgFor + ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HealthInfoComponent); + component = fixture.componentInstance; + component.healthInfoResponse = HealthInfoResponseObj; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should create info component properly', () => { + const components = fixture.debugElement.queryAll(By.css('[data-test="info-component"]')); + expect(components.length).toBe(3); + }); +}); diff --git a/src/app/health-page/health-info/health-info.component.ts b/src/app/health-page/health-info/health-info.component.ts new file mode 100644 index 00000000000..a5fb0b282bc --- /dev/null +++ b/src/app/health-page/health-info/health-info.component.ts @@ -0,0 +1,14 @@ +import { Component, Input } from '@angular/core'; + +import { HealthInfoResponse } from '../models/health-component.model'; + +@Component({ + selector: 'ds-health-info', + templateUrl: './health-info.component.html', + styleUrls: ['./health-info.component.scss'] +}) +export class HealthInfoComponent { + + @Input() healthInfoResponse: HealthInfoResponse; + +} diff --git a/src/app/health-page/health-page.component.html b/src/app/health-page/health-page.component.html new file mode 100644 index 00000000000..6ec9abddcb4 --- /dev/null +++ b/src/app/health-page/health-page.component.html @@ -0,0 +1,21 @@ + diff --git a/src/app/health-page/health-page.component.scss b/src/app/health-page/health-page.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/health-page/health-page.component.spec.ts b/src/app/health-page/health-page.component.spec.ts new file mode 100644 index 00000000000..205af8036a1 --- /dev/null +++ b/src/app/health-page/health-page.component.spec.ts @@ -0,0 +1,72 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { By } from '@angular/platform-browser'; + +import { of } from 'rxjs'; +import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; + +import { HealthPageComponent } from './health-page.component'; +import { HealthDataService } from './health-data.service'; +import { HealthInfoResponseObj, HealthResponseObj } from '../shared/mocks/health-endpoint.mocks'; +import { RawRestResponse } from '../core/dspace-rest/raw-rest-response.model'; +import { TranslateLoaderMock } from '../shared/mocks/translate-loader.mock'; + +describe('HealthPageComponent', () => { + let component: HealthPageComponent; + let fixture: ComponentFixture; + + const healthService = jasmine.createSpyObj('healthDataService', { + getHealth: jasmine.createSpy('getHealth'), + getInfo: jasmine.createSpy('getInfo'), + }); + + const healthRestResponse$ = of({ + payload: HealthResponseObj, + statusCode: 200, + statusText: 'OK' + } as RawRestResponse); + + const healthInfoRestResponse$ = of({ + payload: HealthInfoResponseObj, + statusCode: 200, + statusText: 'OK' + } as RawRestResponse); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ + CommonModule, + NgbNavModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock + } + }) + ], + declarations: [ HealthPageComponent ], + providers: [ + { provide: HealthDataService, useValue: healthService } + ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HealthPageComponent); + component = fixture.componentInstance; + healthService.getHealth.and.returnValue(healthRestResponse$); + healthService.getInfo.and.returnValue(healthInfoRestResponse$); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should create nav items properly', () => { + const navItems = fixture.debugElement.queryAll(By.css('li.nav-item')); + expect(navItems.length).toBe(2); + }); +}); diff --git a/src/app/health-page/health-page.component.ts b/src/app/health-page/health-page.component.ts new file mode 100644 index 00000000000..e4f4be7a03e --- /dev/null +++ b/src/app/health-page/health-page.component.ts @@ -0,0 +1,41 @@ +import { Component, OnInit } from '@angular/core'; + +import { BehaviorSubject } from 'rxjs'; +import { take } from 'rxjs/operators'; + +import { HealthDataService } from './health-data.service'; +import { HealthInfoResponse, HealthResponse } from './models/health-component.model'; + +@Component({ + selector: 'ds-health-page', + templateUrl: './health-page.component.html', + styleUrls: ['./health-page.component.scss'] +}) +export class HealthPageComponent implements OnInit { + + /** + * Health info endpoint response + */ + healthInfoResponse: BehaviorSubject = new BehaviorSubject(null); + + /** + * Health endpoint response + */ + healthResponse: BehaviorSubject = new BehaviorSubject(null); + + constructor(private healthDataService: HealthDataService) { + } + + /** + * Retrieve responses from rest + */ + ngOnInit(): void { + this.healthDataService.getHealth().pipe(take(1)).subscribe((data: any) => { + this.healthResponse.next(data.payload); + }); + + this.healthDataService.getInfo().pipe(take(1)).subscribe((data) => { + this.healthInfoResponse.next(data.payload); + }); + } +} diff --git a/src/app/health-page/health-page.module.ts b/src/app/health-page/health-page.module.ts new file mode 100644 index 00000000000..02a6a91a5f0 --- /dev/null +++ b/src/app/health-page/health-page.module.ts @@ -0,0 +1,35 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; + +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateModule } from '@ngx-translate/core'; + +import { HealthPageRoutingModule } from './health-page.routing.module'; +import { HealthPanelComponent } from './health-panel/health-panel.component'; +import { HealthStatusComponent } from './health-panel/health-status/health-status.component'; +import { SharedModule } from '../shared/shared.module'; +import { HealthPageComponent } from './health-page.component'; +import { HealthComponentComponent } from './health-panel/health-component/health-component.component'; +import { HealthInfoComponent } from './health-info/health-info.component'; +import { HealthInfoComponentComponent } from './health-info/health-info-component/health-info-component.component'; + + +@NgModule({ + imports: [ + CommonModule, + HealthPageRoutingModule, + NgbModule, + SharedModule, + TranslateModule + ], + declarations: [ + HealthPageComponent, + HealthPanelComponent, + HealthStatusComponent, + HealthComponentComponent, + HealthInfoComponent, + HealthInfoComponentComponent, + ] +}) +export class HealthPageModule { +} diff --git a/src/app/health-page/health.routing.module.ts b/src/app/health-page/health-page.routing.module.ts similarity index 57% rename from src/app/health-page/health.routing.module.ts rename to src/app/health-page/health-page.routing.module.ts index a8d94d9d1f5..37c8b626eb9 100644 --- a/src/app/health-page/health.routing.module.ts +++ b/src/app/health-page/health-page.routing.module.ts @@ -1,8 +1,11 @@ import { RouterModule } from '@angular/router'; import { NgModule } from '@angular/core'; -import { AuthenticatedGuard } from '../core/auth/authenticated.guard'; -import { HealthComponent } from './health/health.component'; + import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver'; +import { HealthPageComponent } from './health-page.component'; +import { + SiteAdministratorGuard +} from '../core/data/feature-authorization/feature-authorization-guard/site-administrator.guard'; @NgModule({ imports: [ @@ -11,15 +14,9 @@ import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.reso path: '', resolve: { breadcrumb: I18nBreadcrumbResolver }, data: { breadcrumbKey: 'health' }, - canActivate: [AuthenticatedGuard], - children: [ - { - path: '', - component: HealthComponent, - }, - ] - }, - + canActivate: [SiteAdministratorGuard], + component: HealthPageComponent + } ]) ] }) diff --git a/src/app/health-page/health-panel/health-component/health-component.component.html b/src/app/health-page/health-panel/health-component/health-component.component.html new file mode 100644 index 00000000000..81719177674 --- /dev/null +++ b/src/app/health-page/health-panel/health-component/health-component.component.html @@ -0,0 +1,27 @@ + +
+
+ +
+ + +
+
+
+
+
+ +
+
+
+
+
+ +
+ {{ item.key | titlecase }} : {{item.value}} +
+
diff --git a/src/app/health-page/health-panel/health-component/health-component.component.scss b/src/app/health-page/health-panel/health-component/health-component.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/health-page/health-panel/health-component/health-component.component.spec.ts b/src/app/health-page/health-panel/health-component/health-component.component.spec.ts new file mode 100644 index 00000000000..149d504c23c --- /dev/null +++ b/src/app/health-page/health-panel/health-component/health-component.component.spec.ts @@ -0,0 +1,77 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { By } from '@angular/platform-browser'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; + +import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap'; + +import { HealthComponentComponent } from './health-component.component'; +import { HealthComponentOne, HealthComponentTwo } from '../../../shared/mocks/health-endpoint.mocks'; +import { ObjNgFor } from '../../../shared/utils/object-ngfor.pipe'; + +describe('HealthComponentComponent', () => { + let component: HealthComponentComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ + CommonModule, + NgbCollapseModule, + NoopAnimationsModule + ], + declarations: [ + HealthComponentComponent, + ObjNgFor + ], + schemas: [NO_ERRORS_SCHEMA] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HealthComponentComponent); + component = fixture.componentInstance; + }); + + describe('when has nested components', () => { + beforeEach(() => { + component.healthComponentName = 'db'; + component.healthComponent = HealthComponentOne; + component.isCollapsed = false; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should create collapsible divs properly', () => { + const collapseDivs = fixture.debugElement.queryAll(By.css('[data-test="collapse"]')); + expect(collapseDivs.length).toBe(2); + const detailsDivs = fixture.debugElement.queryAll(By.css('[data-test="details"]')); + expect(detailsDivs.length).toBe(6); + }); + }); + + describe('when has details', () => { + beforeEach(() => { + component.healthComponentName = 'geoIp'; + component.healthComponent = HealthComponentTwo; + + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should create detail divs properly', () => { + const detailsDivs = fixture.debugElement.queryAll(By.css('[data-test="details"]')); + expect(detailsDivs.length).toBe(1); + const collapseDivs = fixture.debugElement.queryAll(By.css('[data-test="collapse"]')); + expect(collapseDivs.length).toBe(0); + }); + }); +}); diff --git a/src/app/health-page/health-panel/health-component/health-component.component.ts b/src/app/health-page/health-panel/health-component/health-component.component.ts new file mode 100644 index 00000000000..5ad40c94696 --- /dev/null +++ b/src/app/health-page/health-panel/health-component/health-component.component.ts @@ -0,0 +1,27 @@ +import { Component, Input } from '@angular/core'; + +import { HealthComponent } from '../../models/health-component.model'; + +@Component({ + selector: 'ds-health-component', + templateUrl: './health-component.component.html', + styleUrls: ['./health-component.component.scss'] +}) +export class HealthComponentComponent { + + /** + * The HealthComponent object to display + */ + @Input() healthComponent: HealthComponent; + + /** + * The HealthComponent object name + */ + @Input() healthComponentName: string; + + /** + * A boolean representing if div should start collapsed + */ + public isCollapsed = true; + +} diff --git a/src/app/health-page/health-panel/health-panel.component.html b/src/app/health-page/health-panel/health-panel.component.html new file mode 100644 index 00000000000..d582fb77f32 --- /dev/null +++ b/src/app/health-page/health-panel/health-panel.component.html @@ -0,0 +1,21 @@ +

{{'health-page.status' | translate}} :

+
+
+ +
+ + + +
+
+
+
+
+ +
+
+
+
diff --git a/src/app/health-page/health-panel/health-panel.component.scss b/src/app/health-page/health-panel/health-panel.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/health-page/health-panel/health-panel.component.spec.ts b/src/app/health-page/health-panel/health-panel.component.spec.ts new file mode 100644 index 00000000000..da392f7ba85 --- /dev/null +++ b/src/app/health-page/health-panel/health-panel.component.spec.ts @@ -0,0 +1,58 @@ +import { CommonModule } from '@angular/common'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; + +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { NgbCollapseModule, NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; + +import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; +import { HealthPanelComponent } from './health-panel.component'; +import { HealthResponseObj } from '../../shared/mocks/health-endpoint.mocks'; +import { ObjNgFor } from '../../shared/utils/object-ngfor.pipe'; + +describe('HealthComponent', () => { + let component: HealthPanelComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [ + NgbNavModule, + NgbCollapseModule, + CommonModule, + BrowserAnimationsModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock + } + }), + ], + declarations: [ + HealthPanelComponent, + ObjNgFor + ], + schemas: [NO_ERRORS_SCHEMA] + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HealthPanelComponent); + component = fixture.componentInstance; + component.healthResponse = HealthResponseObj; + component.isCollapsed = false; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should render a card for each component', () => { + const components = fixture.debugElement.queryAll(By.css('[data-test="component"]')); + expect(components.length).toBe(5); + }); + +}); diff --git a/src/app/health-page/health-panel/health-panel.component.ts b/src/app/health-page/health-panel/health-panel.component.ts new file mode 100644 index 00000000000..549544c370a --- /dev/null +++ b/src/app/health-page/health-panel/health-panel.component.ts @@ -0,0 +1,21 @@ +import { Component, Input } from '@angular/core'; +import { HealthResponse } from '../models/health-component.model'; + +@Component({ + selector: 'ds-health-panel', + templateUrl: './health-panel.component.html', + styleUrls: ['./health-panel.component.scss'] +}) +export class HealthPanelComponent { + + /** + * Health endpoint response + */ + @Input() healthResponse: HealthResponse; + + /** + * A boolean representing if div should start collapsed + */ + public isCollapsed = true; + +} diff --git a/src/app/health-page/health-panel/health-status/health-status.component.html b/src/app/health-page/health-panel/health-status/health-status.component.html new file mode 100644 index 00000000000..fdd726cddfe --- /dev/null +++ b/src/app/health-page/health-panel/health-status/health-status.component.html @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/app/health-page/health-panel/health-status/health-status.component.scss b/src/app/health-page/health-panel/health-status/health-status.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/health-page/health-panel/health-status/health-status.component.spec.ts b/src/app/health-page/health-panel/health-status/health-status.component.spec.ts new file mode 100644 index 00000000000..13df9c23e36 --- /dev/null +++ b/src/app/health-page/health-panel/health-status/health-status.component.spec.ts @@ -0,0 +1,48 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; + +import { HealthStatusComponent } from './health-status.component'; +import { HealthStatus } from '../../models/health-component.model'; + +describe('HealthStatusComponent', () => { + let component: HealthStatusComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ HealthStatusComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HealthStatusComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should create success icon', () => { + component.status = HealthStatus.UP; + fixture.detectChanges(); + const icon = fixture.debugElement.query(By.css('i.text-success')); + expect(icon).toBeTruthy(); + }); + + it('should create warning icon', () => { + component.status = HealthStatus.UP_WITH_ISSUES; + fixture.detectChanges(); + const icon = fixture.debugElement.query(By.css('i.text-warning')); + expect(icon).toBeTruthy(); + }); + + it('should create success icon', () => { + component.status = HealthStatus.DOWN; + fixture.detectChanges(); + const icon = fixture.debugElement.query(By.css('i.text-danger')); + expect(icon).toBeTruthy(); + }); +}); diff --git a/src/app/health-page/health-panel/health-status/health-status.component.ts b/src/app/health-page/health-panel/health-status/health-status.component.ts new file mode 100644 index 00000000000..9285483a972 --- /dev/null +++ b/src/app/health-page/health-panel/health-status/health-status.component.ts @@ -0,0 +1,20 @@ +import { Component, Input } from '@angular/core'; +import { HealthStatus } from '../../models/health-component.model'; + +@Component({ + selector: 'ds-health-status', + templateUrl: './health-status.component.html', + styleUrls: ['./health-status.component.scss'] +}) +export class HealthStatusComponent { + /** + * The current status to show + */ + @Input() status: HealthStatus; + + /** + * He + */ + HealthStatus = HealthStatus; + +} diff --git a/src/app/health-page/health.module.ts b/src/app/health-page/health.module.ts deleted file mode 100644 index 8731b77f773..00000000000 --- a/src/app/health-page/health.module.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { HealthPageRoutingModule } from './health.routing.module'; -import { HealthComponent } from './health/health.component'; -import { MatExpansionModule } from '@angular/material/expansion'; -import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; -import { TranslateModule } from '@ngx-translate/core'; - - -@NgModule({ - imports: [ - CommonModule, - HealthPageRoutingModule, - MatExpansionModule, - NgbModule, - TranslateModule - ], - declarations: [ - HealthComponent - ] - }) - export class HealthModule { - } diff --git a/src/app/health-page/health/health.component.html b/src/app/health-page/health/health.component.html deleted file mode 100644 index 05f77225fbb..00000000000 --- a/src/app/health-page/health/health.component.html +++ /dev/null @@ -1,39 +0,0 @@ -
- -
-
- - - - diff --git a/src/app/health-page/health/health.component.scss b/src/app/health-page/health/health.component.scss deleted file mode 100644 index c0851110794..00000000000 --- a/src/app/health-page/health/health.component.scss +++ /dev/null @@ -1,8 +0,0 @@ -.mat-expansion-panel-header { - padding-left: 0px; -} - -.circle-red { - color:red; - align-items: center; -} \ No newline at end of file diff --git a/src/app/health-page/health/health.component.spec.ts b/src/app/health-page/health/health.component.spec.ts deleted file mode 100644 index 4515aef2cb9..00000000000 --- a/src/app/health-page/health/health.component.spec.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MatExpansionModule } from '@angular/material/expansion'; -import { By } from '@angular/platform-browser'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; -import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; -import { of } from 'rxjs'; -import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; -import { HealthDataService } from '../health-data.service'; -import { HealthPageRoutingModule } from '../health.routing.module'; -import { HealthComponent } from './health.component'; - - function getHealth() { - return of({ - 'payload':{ - 'status':'UP_WITH_ISSUES', - 'components':{ - 'db':{ - 'status':'UP', - 'components':{ - 'dataSource':{ - 'status':'UP', - 'details':{ - 'database':'PostgreSQL', - 'result':1, - 'validationQuery':'SELECT 1' - } - }, - 'dspaceDataSource':{ - 'status':'UP', - 'details':{ - 'database':'PostgreSQL', - 'result':1, - 'validationQuery':'SELECT 1' - } - } - } - }, - 'geoIp':{ - 'status':'UP_WITH_ISSUES', - 'details':{ - 'reason':'The GeoLite Database file is missing (/var/lib/GeoIP/GeoLite2-City.mmdb)! Solr Statistics cannot generate location based reports! Please see the DSpace installation instructions for instructions to install this file.' - } - }, - 'solrOaiCore':{ - 'status':'UP', - 'details':{ - 'status':0, - 'detectedPathType':'particular core' - } - }, - 'solrSearchCore':{ - 'status':'UP', - 'details':{ - 'status':0, - 'detectedPathType':'particular core' - } - }, - 'solrStatisticsCore':{ - 'status':'UP', - 'details':{ - 'status':0, - 'detectedPathType':'particular core' - } - } - } - }, - 'statusCode':200, - 'statusText':'OK' - }); - } - - function getInfo() { - return of({ - 'payload':{ - 'app':{ - 'name':'DSpace at My University', - 'version':'7.3', - 'dir':'/Users/pratikrajkotiya/Documents/Project/FrontEnd/dspace-cris-install', - 'url':'http://localhost:8080/server', - 'db':'jdbc:postgresql://localhost:5432/4science', - 'solr':{ - 'server':'http://localhost:8983/solr', - 'prefix':'' - }, - 'mail':{ - 'server':'smtp.example.com', - 'from-address':'dspace-noreply@myu.edu', - 'feedback-recipient':'dspace-help@myu.edu', - 'mail-admin':'dspace-help@myu.edu', - 'mail-helpdesk':'dspace-help@myu.edu', - 'alert-recipient':'dspace-help@myu.edu' - }, - 'cors':{ - 'allowed-origins':'http://localhost:4000' - }, - 'ui':{ - 'url':'http://localhost:4000' - } - } - }, - 'statusCode':200, - 'statusText':'OK' - }); - } - -function getMockHealthDataService() { - return jasmine.createSpyObj('healthDataService', { - getHealth: getHealth(), - getInfo: getInfo() - }); -} - -describe('HealthComponent', () => { - let component: HealthComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ - NgbNavModule, - CommonModule, - HealthPageRoutingModule, - MatExpansionModule, - BrowserAnimationsModule, - TranslateModule.forRoot({ - loader: { - provide: TranslateLoader, - useClass: TranslateLoaderMock - } - }), - ], - declarations: [ HealthComponent ], - providers:[{ provide: HealthDataService, useValue: getMockHealthDataService() }] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(HealthComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - it('should render health tab.', () => { - const healthTab = fixture.debugElement.query(By.css('#health')); - expect(healthTab).toBeTruthy(); - }); - - it('should render info tab.', () => { - const infoTab = fixture.debugElement.query(By.css('#info')); - expect(infoTab).toBeFalsy(); - }); - -}); diff --git a/src/app/health-page/health/health.component.ts b/src/app/health-page/health/health.component.ts deleted file mode 100644 index 89aa6611f65..00000000000 --- a/src/app/health-page/health/health.component.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { HealthDataService } from '../health-data.service'; - - -enum HealthStatus { - UP = 'UP', - UP_WITH_ISSUES = 'UP_WITH_ISSUES', - DOWN = 'DOWN' -} -@Component({ - selector: 'ds-health', - templateUrl: './health.component.html', - styleUrls: ['./health.component.scss'] -}) -export class HealthComponent implements OnInit { - healthArr: string[]; - serverInfoArr: string[]; - healthGlobalStatus: string; - activeId ='Health'; - constructor(private healthDataService: HealthDataService) { } - - ngOnInit(): void { - this.healthDataService.getHealth().subscribe((data) => { - this.healthArr = this.getHealth(data.payload.components); - this.healthGlobalStatus = data.payload.status; - }); - - this.healthDataService.getInfo().subscribe((data) => { - this.serverInfoArr = this.getInfo(data.payload, null, []); - }); - } - - /** - * @param obj represents a info - * @param key represents a nested key of info - * @param arr represents a key value pair or only key - * @returns {{arr}} of key value pair or only key - */ - getInfo(obj, key, arr) { - if (typeof obj === 'object' && key !== null) { - arr.push({style: {'font-weight': 'bold' ,'font-size.px': key === 'app' ? '30' : '20' }, value: key}); - } - if (typeof obj !== 'object') { - arr.push({style: {'font-size.px': '15'}, value: `${key} = ${obj}`}); - return obj; - } - // tslint:disable-next-line: forin - for (const objKey in obj) { - this.getInfo(obj[objKey], objKey, arr); - } - return arr; - } - - /** - * @param subCompObj represent nested sub component - * @param superCompkey represents a key of super component - * @returns linear components array - */ - getHealthSubComponents(subCompObj, superCompkey) { - const subCompArr = []; - // tslint:disable-next-line: forin - for (const key in subCompObj) { - subCompArr.push({ ...subCompObj[key], components: superCompkey + '.' + key }); - } - return subCompArr; - } - - /** - * @param componentsObj represent health data - * @returns linear components array - */ - getHealth(componentsObj) { - let componentsArr = []; - for (const key in componentsObj) { - if (componentsObj[key].hasOwnProperty('components')) { - componentsArr.push({ ...componentsObj[key], components: key }); - // tslint:disable-next-line: no-string-literal - componentsArr = [...componentsArr, ...this.getHealthSubComponents(componentsObj[key]['components'], key)]; - } else { - componentsArr.push({ ...componentsObj[key], components: key }); - } - } - return componentsArr; - } - - /** - * @param status of perticular block - * @returns {{ string }} class respective status - */ - getHealthIconClass(status: string): string { - if (status === HealthStatus.UP) { - return 'fa fa-check-circle text-success ml-2 mt-1'; - } else if (status === HealthStatus.UP_WITH_ISSUES) { - return 'fa fa-exclamation-triangle text-warning ml-2 mt-1'; - } else { - return 'fa fa-times-circle circle-red ml-2 mt-1'; - } - } - -} diff --git a/src/app/health-page/models/health-component.model.ts b/src/app/health-page/models/health-component.model.ts new file mode 100644 index 00000000000..8461d4d9672 --- /dev/null +++ b/src/app/health-page/models/health-component.model.ts @@ -0,0 +1,48 @@ +/** + * Interface for Health Status + */ +export enum HealthStatus { + UP = 'UP', + UP_WITH_ISSUES = 'UP_WITH_ISSUES', + DOWN = 'DOWN' +} + +/** + * Interface describing the Health endpoint response + */ +export interface HealthResponse { + status: HealthStatus; + components: { + [name: string]: HealthComponent; + }; +} + +/** + * Interface describing a single component retrieved from the Health endpoint response + */ +export interface HealthComponent { + status: HealthStatus; + details?: { + [name: string]: number|string; + }; + components?: { + [name: string]: HealthComponent; + }; +} + +/** + * Interface describing the Health info endpoint response + */ +export interface HealthInfoResponse { + [name: string]: HealthInfoComponent|string; +} + +/** + * Interface describing a single component retrieved from the Health info endpoint response + */ +export interface HealthInfoComponent { + [property: string]: HealthInfoComponent|string; +} + + + diff --git a/src/app/shared/mocks/health-endpoint.mocks.ts b/src/app/shared/mocks/health-endpoint.mocks.ts new file mode 100644 index 00000000000..9bd39561391 --- /dev/null +++ b/src/app/shared/mocks/health-endpoint.mocks.ts @@ -0,0 +1,140 @@ +import { + HealthComponent, + HealthInfoComponent, + HealthInfoResponse, + HealthResponse, + HealthStatus +} from '../../health-page/models/health-component.model'; + +export const HealthResponseObj: HealthResponse = { + 'status': HealthStatus.UP_WITH_ISSUES, + 'components': { + 'db': { + 'status': HealthStatus.UP, + 'components': { + 'dataSource': { + 'status': HealthStatus.UP, + 'details': { + 'database': 'PostgreSQL', + 'result': 1, + 'validationQuery': 'SELECT 1' + } + }, + 'dspaceDataSource': { + 'status': HealthStatus.UP, + 'details': { + 'database': 'PostgreSQL', + 'result': 1, + 'validationQuery': 'SELECT 1' + } + } + } + }, + 'geoIp': { + 'status': HealthStatus.UP_WITH_ISSUES, + 'details': { + 'reason': 'The GeoLite Database file is missing (/var/lib/GeoIP/GeoLite2-City.mmdb)! Solr Statistics cannot generate location based reports! Please see the DSpace installation instructions for instructions to install this file.' + } + }, + 'solrOaiCore': { + 'status': HealthStatus.UP, + 'details': { + 'status': 0, + 'detectedPathType': 'particular core' + } + }, + 'solrSearchCore': { + 'status': HealthStatus.UP, + 'details': { + 'status': 0, + 'detectedPathType': 'particular core' + } + }, + 'solrStatisticsCore': { + 'status': HealthStatus.UP, + 'details': { + 'status': 0, + 'detectedPathType': 'particular core' + } + } + } +}; + +export const HealthComponentOne: HealthComponent = { + 'status': HealthStatus.UP, + 'components': { + 'dataSource': { + 'status': HealthStatus.UP, + 'details': { + 'database': 'PostgreSQL', + 'result': 1, + 'validationQuery': 'SELECT 1' + } + }, + 'dspaceDataSource': { + 'status': HealthStatus.UP, + 'details': { + 'database': 'PostgreSQL', + 'result': 1, + 'validationQuery': 'SELECT 1' + } + } + } +}; + +export const HealthComponentTwo: HealthComponent = { + 'status': HealthStatus.UP_WITH_ISSUES, + 'details': { + 'reason': 'The GeoLite Database file is missing (/var/lib/GeoIP/GeoLite2-City.mmdb)! Solr Statistics cannot generate location based reports! Please see the DSpace installation instructions for instructions to install this file.' + } +}; + +export const HealthInfoResponseObj: HealthInfoResponse = { + 'app': { + 'name': 'DSpace at My University', + 'dir': '/home/giuseppe/development/java/install/dspace7-review', + 'url': 'http://localhost:8080/server', + 'db': 'jdbc:postgresql://localhost:5432/dspace7', + 'solr': { + 'server': 'http://localhost:8983/solr', + 'prefix': '' + }, + 'mail': { + 'server': 'smtp.example.com', + 'from-address': 'dspace-noreply@myu.edu', + 'feedback-recipient': 'dspace-help@myu.edu', + 'mail-admin': 'dspace-help@myu.edu', + 'mail-helpdesk': 'dspace-help@myu.edu', + 'alert-recipient': 'dspace-help@myu.edu' + }, + 'cors': { + 'allowed-origins': 'http://localhost:4000' + }, + 'ui': { + 'url': 'http://localhost:4000' + } + }, + 'java': { + 'vendor': 'Private Build', + 'version': '11.0.15', + 'runtime': { + 'name': 'OpenJDK Runtime Environment', + 'version': '11.0.15+10-Ubuntu-0ubuntu0.20.04.1' + }, + 'jvm': { + 'name': 'OpenJDK 64-Bit Server VM', + 'vendor': 'Private Build', + 'version': '11.0.15+10-Ubuntu-0ubuntu0.20.04.1' + } + }, + 'version': '7.3-SNAPSHOT' +}; + +export const HealthInfoComponentOne: HealthInfoComponent = { + 'name': 'DSpace at My University', + 'dir': '/home/giuseppe/development/java/install/dspace7-review', + 'url': 'http://localhost:8080/server', + 'db': 'jdbc:postgresql://localhost:5432/dspace7' +}; + +export const HealthInfoComponentTwo = '7.3-SNAPSHOT'; From 3c2f26f6c18bbf379e9b0be64f713a91cada110f Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Tue, 3 May 2022 15:30:20 +0200 Subject: [PATCH 0319/2129] [CST-5535] Add environment configuration for Actuators --- src/config/actuators.config.ts | 11 +++++++++++ src/config/app-config.interface.ts | 2 ++ src/config/default-app-config.ts | 5 +++++ src/environments/environment.test.ts | 4 ++++ 4 files changed, 22 insertions(+) create mode 100644 src/config/actuators.config.ts diff --git a/src/config/actuators.config.ts b/src/config/actuators.config.ts new file mode 100644 index 00000000000..8f59a13c980 --- /dev/null +++ b/src/config/actuators.config.ts @@ -0,0 +1,11 @@ +import { Config } from './config.interface'; + +/** + * Config that determines the spring Actuators options + */ +export class ActuatorsConfig implements Config { + /** + * The endpoint path + */ + public endpointPath: string; +} diff --git a/src/config/app-config.interface.ts b/src/config/app-config.interface.ts index a41ec05b820..e8bda533739 100644 --- a/src/config/app-config.interface.ts +++ b/src/config/app-config.interface.ts @@ -15,6 +15,7 @@ import { UIServerConfig } from './ui-server-config.interface'; import { MediaViewerConfig } from './media-viewer-config.interface'; import { BrowseByConfig } from './browse-by-config.interface'; import { BundleConfig } from './bundle-config.interface'; +import { ActuatorsConfig } from './actuators.config'; interface AppConfig extends Config { ui: UIServerConfig; @@ -34,6 +35,7 @@ interface AppConfig extends Config { themes: ThemeConfig[]; mediaViewer: MediaViewerConfig; bundle: BundleConfig; + actuators: ActuatorsConfig } const APP_CONFIG = new InjectionToken('APP_CONFIG'); diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index a7360bd1d1b..27950f52692 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -15,6 +15,7 @@ import { SubmissionConfig } from './submission-config.interface'; import { ThemeConfig } from './theme.model'; import { UIServerConfig } from './ui-server-config.interface'; import { BundleConfig } from './bundle-config.interface'; +import { ActuatorsConfig } from './actuators.config'; export class DefaultAppConfig implements AppConfig { production = false; @@ -48,6 +49,10 @@ export class DefaultAppConfig implements AppConfig { nameSpace: '/', }; + actuators: ActuatorsConfig = { + endpointPath: '/actuator/health' + }; + // Caching settings cache: CacheConfig = { // NOTE: how long should objects be cached for by default diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index bc1622f5f29..d2f2ad7426a 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -38,6 +38,10 @@ export const environment: BuildConfig = { baseUrl: 'https://rest.com/api' }, + actuators: { + endpointPath: '/actuator/health' + }, + // Caching settings cache: { // NOTE: how long should objects be cached for by default From 675f3910ccb23a2eb2376d61af067a018db59e72 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Tue, 3 May 2022 15:32:02 +0200 Subject: [PATCH 0320/2129] [CST-5535] Refactoring health check server side request --- package.json | 1 + server.ts | 31 +++++++++++++++++++------------ yarn.lock | 10 +++++++++- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 75e22b40f35..14e2436ccd3 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "@nicky-lenaers/ngx-scroll-to": "^9.0.0", "angular-idle-preload": "3.0.0", "angulartics2": "^10.0.0", + "axios": "^0.27.2", "bootstrap": "4.3.1", "caniuse-lite": "^1.0.30001165", "cerialize": "0.1.18", diff --git a/server.ts b/server.ts index 7f8bb9bbdb4..14ce33ed362 100644 --- a/server.ts +++ b/server.ts @@ -19,6 +19,7 @@ import 'zone.js/node'; import 'reflect-metadata'; import 'rxjs'; +import axios from 'axios'; import * as pem from 'pem'; import * as https from 'https'; import * as morgan from 'morgan'; @@ -37,14 +38,14 @@ import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens'; import { environment } from './src/environments/environment'; import { createProxyMiddleware } from 'http-proxy-middleware'; -import { hasValue, hasNoValue } from './src/app/shared/empty.util'; +import { hasNoValue, hasValue } from './src/app/shared/empty.util'; import { UIServerConfig } from './src/config/ui-server-config.interface'; import { ServerAppModule } from './src/main.server'; import { buildAppConfig } from './src/config/config.server'; -import { AppConfig, APP_CONFIG } from './src/config/app-config.interface'; +import { APP_CONFIG, AppConfig } from './src/config/app-config.interface'; import { extendEnvironmentWithAppConfig } from './src/config/config.util'; /* @@ -160,16 +161,7 @@ export function app() { /** * Checking server status */ - server.get('/app/health', async (req,res) => { - try { - const serverStatus = await https.get(`${environment.rest.baseUrl}/actuator/health`); - res.send(serverStatus); - } catch (error) { - res.send({ - error: error.message - }); - } - }); + server.get('/app/health', healthCheck); // Register the ngApp callback function to handle incoming requests server.get('*', ngApp); @@ -301,6 +293,21 @@ function start() { } } +/* + * The callback function to serve health check requests + */ +function healthCheck(req, res) { + const baseUrl = `${environment.rest.baseUrl}${environment.actuators.endpointPath}`; + axios.get(baseUrl) + .then((response) => { + res.status(response.status).send(response.data); + }) + .catch((error) => { + res.status(error.response.status).send({ + error: error.message + }); + }); +} // Webpack will replace 'require' with '__webpack_require__' // '__non_webpack_require__' is a proxy to Node 'require' // The below code is to ensure that the server is run only when not requiring the bundle. diff --git a/yarn.lock b/yarn.lock index 00c93618d90..a612a985d82 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3226,6 +3226,14 @@ axios@0.21.4: dependencies: follow-redirects "^1.14.0" +axios@^0.27.2: + version "0.27.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" + integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== + dependencies: + follow-redirects "^1.14.9" + form-data "^4.0.0" + axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" @@ -6108,7 +6116,7 @@ flatted@^3.1.0, flatted@^3.2.5: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== -follow-redirects@^1.0.0, follow-redirects@^1.14.0: +follow-redirects@^1.0.0, follow-redirects@^1.14.0, follow-redirects@^1.14.9: version "1.14.9" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== From 804930fbe2b5cca46343d24bf7486034cf5cc4f8 Mon Sep 17 00:00:00 2001 From: Luca Giamminonni Date: Tue, 3 May 2022 15:35:51 +0200 Subject: [PATCH 0321/2129] [CST-5307] Improved researcher profile component --- ...on-search-result-list-element.component.ts | 15 ++- .../item-pages/person/person.component.html | 3 +- .../person/person.component.spec.ts | 7 +- .../item-pages/person/person.component.ts | 93 ++++++++++++++++++- .../full/full-item-page.component.html | 3 +- .../full/full-item-page.component.ts | 9 +- .../item-page/simple/item-page.component.ts | 63 +------------ .../item-types/shared/item.component.spec.ts | 13 ++- ...rofile-page-researcher-form.component.html | 4 +- .../profile-page/profile-page.component.html | 17 ++-- .../profile-page.component.spec.ts | 10 ++ .../profile-page/profile-page.component.ts | 19 +++- 12 files changed, 162 insertions(+), 94 deletions(-) diff --git a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.ts b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.ts index a6f64bff1b8..32785d7b8ab 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.ts +++ b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.ts @@ -2,6 +2,9 @@ import { Component } from '@angular/core'; import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; import { ViewMode } from '../../../../../core/shared/view-mode.model'; import { ItemSearchResultListElementComponent } from '../../../../../shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component'; +import {TruncatableService} from '../../../../../shared/truncatable/truncatable.service'; +import {DSONameService} from '../../../../../core/breadcrumbs/dso-name.service'; +import {isNotEmpty} from '../../../../../shared/empty.util'; @listableObjectComponent('PersonSearchResult', ViewMode.ListElement) @Component({ @@ -14,9 +17,15 @@ import { ItemSearchResultListElementComponent } from '../../../../../shared/obje */ export class PersonSearchResultListElementComponent extends ItemSearchResultListElementComponent { + public constructor(protected truncatableService: TruncatableService, protected dsoNameService: DSONameService) { + super(truncatableService, dsoNameService); + } + get name() { - return this.value ? - this.value : - this.firstMetadataValue('person.familyName') + ', ' + this.firstMetadataValue('person.givenName'); + let personName = this.dsoNameService.getName(this.dso); + if (isNotEmpty(this.firstMetadataValue('person.familyName')) && isNotEmpty(this.firstMetadataValue('person.givenName'))) { + personName = this.firstMetadataValue('person.familyName') + ', ' + this.firstMetadataValue('person.givenName'); + } + return personName; } } diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.html b/src/app/entity-groups/research-entities/item-pages/person/person.component.html index 8cf6117121b..7505a31327a 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.html +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.html @@ -1,9 +1,10 @@

- {{'person.page.titleprefix' | translate}} + {{'person.page.titleprefix' | translate}}

+
diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.spec.ts b/src/app/entity-groups/research-entities/item-pages/person/person.component.spec.ts index 546621700a9..93b3cf208d7 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.spec.ts +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.spec.ts @@ -54,7 +54,12 @@ const mockItem: Item = Object.assign(new Item(), { } ] }, - relationships: createRelationshipsObservable() + relationships: createRelationshipsObservable(), + _links: { + self : { + href: 'item-href' + } + } }); describe('PersonComponent', getItemPageFieldsTest(mockItem, PersonComponent)); diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.ts b/src/app/entity-groups/research-entities/item-pages/person/person.component.ts index 8b104cc9b13..42eb4ec7e6b 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.ts +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.ts @@ -1,7 +1,20 @@ -import { Component } from '@angular/core'; +import {Component, OnInit} from '@angular/core'; import { ItemComponent } from '../../../../item-page/simple/item-types/shared/item.component'; import { ViewMode } from '../../../../core/shared/view-mode.model'; import { listableObjectComponent } from '../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; +import {MetadataValue} from '../../../../core/shared/metadata.models'; +import {FeatureID} from '../../../../core/data/feature-authorization/feature-id'; +import {mergeMap, take} from 'rxjs/operators'; +import {getFirstSucceededRemoteData} from '../../../../core/shared/operators'; +import {RemoteData} from '../../../../core/data/remote-data'; +import {ResearcherProfile} from '../../../../core/profile/model/researcher-profile.model'; +import {isNotUndefined} from '../../../../shared/empty.util'; +import {BehaviorSubject, Observable} from 'rxjs'; +import {RouteService} from '../../../../core/services/route.service'; +import {AuthorizationDataService} from '../../../../core/data/feature-authorization/authorization-data.service'; +import {ResearcherProfileService} from '../../../../core/profile/researcher-profile.service'; +import {NotificationsService} from '../../../../shared/notifications/notifications.service'; +import {TranslateService} from '@ngx-translate/core'; @listableObjectComponent('Person', ViewMode.StandalonePage) @Component({ @@ -12,5 +25,81 @@ import { listableObjectComponent } from '../../../../shared/object-collection/sh /** * The component for displaying metadata and relations of an item of the type Person */ -export class PersonComponent extends ItemComponent { +export class PersonComponent extends ItemComponent implements OnInit { + + claimable$: BehaviorSubject = new BehaviorSubject(false); + + constructor(protected routeService: RouteService, + protected authorizationService: AuthorizationDataService, + protected notificationsService: NotificationsService, + protected translate: TranslateService, + protected researcherProfileService: ResearcherProfileService) { + super(routeService); + } + + ngOnInit(): void { + super.ngOnInit(); + + this.authorizationService.isAuthorized(FeatureID.ShowClaimItem, this.object._links.self.href).pipe( + take(1) + ).subscribe((isAuthorized: boolean) => { + this.claimable$.next(isAuthorized); + }); + + } + + claim() { + + this.authorizationService.isAuthorized(FeatureID.CanClaimItem, this.object._links.self.href).pipe( + take(1) + ).subscribe((isAuthorized: boolean) => { + if (!isAuthorized) { + this.notificationsService.warning(this.translate.get('researcherprofile.claim.not-authorized')); + } else { + this.createFromExternalSource(); + } + }); + + } + + createFromExternalSource() { + this.researcherProfileService.createFromExternalSource(this.object._links.self.href).pipe( + getFirstSucceededRemoteData(), + mergeMap((rd: RemoteData) => { + return this.researcherProfileService.findRelatedItemId(rd.payload); + })) + .subscribe((id: string) => { + if (isNotUndefined(id)) { + this.notificationsService.success(this.translate.get('researcherprofile.success.claim.title'), + this.translate.get('researcherprofile.success.claim.body')); + this.claimable$.next(false); + } else { + this.notificationsService.error( + this.translate.get('researcherprofile.error.claim.title'), + this.translate.get('researcherprofile.error.claim.body')); + } + }); + } + + isClaimable(): Observable { + return this.claimable$; + } + + getTitleMetadataValues(): MetadataValue[]{ + const metadataValues = []; + const familyName = this.object?.firstMetadata('person.familyName'); + const givenName = this.object?.firstMetadata('person.givenName'); + const title = this.object?.firstMetadata('dc.title'); + if (familyName){ + metadataValues.push(familyName); + } + if (givenName){ + metadataValues.push(givenName); + } + if (metadataValues.length === 0 && title){ + metadataValues.push(title); + } + return metadataValues; + } + } diff --git a/src/app/item-page/full/full-item-page.component.html b/src/app/item-page/full/full-item-page.component.html index bfa25ec0097..7cc8ff92c42 100644 --- a/src/app/item-page/full/full-item-page.component.html +++ b/src/app/item-page/full/full-item-page.component.html @@ -10,7 +10,6 @@
-
-
\ No newline at end of file + 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 99cf083bc5d..369769c77d1 100644 --- a/src/app/item-page/full/full-item-page.component.ts +++ b/src/app/item-page/full/full-item-page.component.ts @@ -16,10 +16,6 @@ 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 { TranslateService } from '@ngx-translate/core'; -import { NotificationsService } from '../../shared/notifications/notifications.service'; -import { ResearcherProfileService } from '../../core/profile/researcher-profile.service'; -import { CollectionDataService } from '../../core/data/collection-data.service'; /** @@ -52,11 +48,8 @@ export class FullItemPageComponent extends ItemPageComponent implements OnInit, items: ItemDataService, authService: AuthService, authorizationService: AuthorizationDataService, - translate: TranslateService, - notificationsService: NotificationsService, - researcherProfileService: ResearcherProfileService, private _location: Location) { - super(route, router, items, authService, authorizationService, translate, notificationsService, researcherProfileService); + super(route, router, items, authService, authorizationService); } /*** AoT inheritance fix, will hopefully be resolved in the near future **/ diff --git a/src/app/item-page/simple/item-page.component.ts b/src/app/item-page/simple/item-page.component.ts index 34a059246d6..b3660eb9d76 100644 --- a/src/app/item-page/simple/item-page.component.ts +++ b/src/app/item-page/simple/item-page.component.ts @@ -64,24 +64,13 @@ export class ItemPageComponent implements OnInit { itemUrl: string; - public claimable$: BehaviorSubject = new BehaviorSubject(false); - public isProcessing$: BehaviorSubject = new BehaviorSubject(false); - constructor( protected route: ActivatedRoute, private router: Router, private items: ItemDataService, private authService: AuthService, - private authorizationService: AuthorizationDataService, - private translate: TranslateService, - private notificationsService: NotificationsService, - private researcherProfileService: ResearcherProfileService + private authorizationService: AuthorizationDataService ) { - this.route.data.pipe( - map((data) => data.dso as RemoteData) - ).subscribe((data: RemoteData) => { - this.itemUrl = data?.payload?.self; - }); } /** @@ -99,55 +88,5 @@ export class ItemPageComponent implements OnInit { this.isAdmin$ = this.authorizationService.isAuthorized(FeatureID.AdministratorOf); - this.authorizationService.isAuthorized(FeatureID.ShowClaimItem, this.itemUrl).pipe( - take(1) - ).subscribe((isAuthorized: boolean) => { - this.claimable$.next(isAuthorized); - }); - } - - claim() { - this.isProcessing$.next(true); - - this.authorizationService.isAuthorized(FeatureID.CanClaimItem, this.itemUrl).pipe( - take(1) - ).subscribe((isAuthorized: boolean) => { - if (!isAuthorized) { - this.notificationsService.warning(this.translate.get('researcherprofile.claim.not-authorized')); - this.isProcessing$.next(false); - } else { - this.createFromExternalSource(); - } - }); - - } - - createFromExternalSource() { - this.researcherProfileService.createFromExternalSource(this.itemUrl).pipe( - tap((rd: any) => { - if (!rd.hasSucceeded) { - this.isProcessing$.next(false); - } - }), - getFirstSucceededRemoteData(), - mergeMap((rd: RemoteData) => { - return this.researcherProfileService.findRelatedItemId(rd.payload); - })) - .subscribe((id: string) => { - if (isNotUndefined(id)) { - this.notificationsService.success(this.translate.get('researcherprofile.success.claim.title'), - this.translate.get('researcherprofile.success.claim.body')); - this.claimable$.next(false); - this.isProcessing$.next(false); - } else { - this.notificationsService.error( - this.translate.get('researcherprofile.error.claim.title'), - this.translate.get('researcherprofile.error.claim.body')); - } - }); - } - - isClaimable(): Observable { - return this.claimable$; } } diff --git a/src/app/item-page/simple/item-types/shared/item.component.spec.ts b/src/app/item-page/simple/item-types/shared/item.component.spec.ts index fc07f60b28d..6f7684b8965 100644 --- a/src/app/item-page/simple/item-types/shared/item.component.spec.ts +++ b/src/app/item-page/simple/item-types/shared/item.component.spec.ts @@ -4,7 +4,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { Store } from '@ngrx/store'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; -import { Observable } from 'rxjs'; +import {Observable, of as observableOf} from 'rxjs'; import { RemoteDataBuildService } from '../../../../core/cache/builders/remote-data-build.service'; import { ObjectCacheService } from '../../../../core/cache/object-cache.service'; import { BitstreamDataService } from '../../../../core/data/bitstream-data.service'; @@ -32,6 +32,8 @@ import { ItemComponent } from './item.component'; import { createPaginatedList } from '../../../../shared/testing/utils.test'; import { RouteService } from '../../../../core/services/route.service'; import { MetadataValue } from '../../../../core/shared/metadata.models'; +import {AuthorizationDataService} from '../../../../core/data/feature-authorization/authorization-data.service'; +import {ResearcherProfileService} from '../../../../core/profile/researcher-profile.service'; export const iiifEnabled = Object.assign(new MetadataValue(),{ 'value': 'true', @@ -69,6 +71,11 @@ export function getItemPageFieldsTest(mockItem: Item, component) { return createSuccessfulRemoteDataObject$(new Bitstream()); } }; + + const authorizationService = jasmine.createSpyObj('authorizationService', { + isAuthorized: observableOf(true) + }); + TestBed.configureTestingModule({ imports: [TranslateModule.forRoot({ loader: { @@ -92,7 +99,9 @@ export function getItemPageFieldsTest(mockItem: Item, component) { { provide: NotificationsService, useValue: {} }, { provide: DefaultChangeAnalyzer, useValue: {} }, { provide: BitstreamDataService, useValue: mockBitstreamDataService }, - { provide: RouteService, useValue: {} } + { provide: RouteService, useValue: {} }, + { provide: AuthorizationDataService, useValue: authorizationService }, + { provide: ResearcherProfileService, useValue: {} } ], schemas: [NO_ERRORS_SCHEMA] diff --git a/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.html b/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.html index b2d53ea0e3c..bb554187446 100644 --- a/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.html +++ b/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.html @@ -9,7 +9,7 @@

{{'researcher.profile.not.associated' | translate}}

- - diff --git a/src/app/shared/log-in/methods/password/log-in-password.component.spec.ts b/src/app/shared/log-in/methods/password/log-in-password.component.spec.ts index 355d328f3f8..5238482770d 100644 --- a/src/app/shared/log-in/methods/password/log-in-password.component.spec.ts +++ b/src/app/shared/log-in/methods/password/log-in-password.component.spec.ts @@ -17,6 +17,7 @@ import { storeModuleConfig } from '../../../../app.reducer'; import { AuthMethod } from '../../../../core/auth/models/auth.method'; import { AuthMethodType } from '../../../../core/auth/models/auth.method-type'; import { HardRedirectService } from '../../../../core/services/hard-redirect.service'; +import { BrowserOnlyMockPipe } from '../../../testing/browser-only-mock.pipe'; describe('LogInPasswordComponent', () => { @@ -57,7 +58,8 @@ describe('LogInPasswordComponent', () => { TranslateModule.forRoot() ], declarations: [ - LogInPasswordComponent + LogInPasswordComponent, + BrowserOnlyMockPipe, ], providers: [ { provide: AuthService, useClass: AuthServiceStub }, diff --git a/src/app/shared/log-out/log-out.component.html b/src/app/shared/log-out/log-out.component.html index 9151cb0c2d1..83e58b3841b 100644 --- a/src/app/shared/log-out/log-out.component.html +++ b/src/app/shared/log-out/log-out.component.html @@ -2,5 +2,5 @@ - + diff --git a/src/app/shared/log-out/log-out.component.spec.ts b/src/app/shared/log-out/log-out.component.spec.ts index f15203ed8b7..028738a019c 100644 --- a/src/app/shared/log-out/log-out.component.spec.ts +++ b/src/app/shared/log-out/log-out.component.spec.ts @@ -12,6 +12,7 @@ import { Router } from '@angular/router'; import { AppState } from '../../app.reducer'; import { LogOutComponent } from './log-out.component'; import { RouterStub } from '../testing/router.stub'; +import { BrowserOnlyMockPipe } from '../testing/browser-only-mock.pipe'; describe('LogOutComponent', () => { @@ -46,7 +47,8 @@ describe('LogOutComponent', () => { TranslateModule.forRoot() ], declarations: [ - LogOutComponent + LogOutComponent, + BrowserOnlyMockPipe, ], providers: [ { provide: Router, useValue: routerStub }, diff --git a/src/app/shared/object-grid/object-grid.component.html b/src/app/shared/object-grid/object-grid.component.html index 07dbcec8059..c988e768032 100644 --- a/src/app/shared/object-grid/object-grid.component.html +++ b/src/app/shared/object-grid/object-grid.component.html @@ -18,7 +18,7 @@ >
-
+
diff --git a/src/app/shared/object-list/object-list.component.html b/src/app/shared/object-list/object-list.component.html index 492cb4cf077..927f2b9d2ae 100644 --- a/src/app/shared/object-list/object-list.component.html +++ b/src/app/shared/object-list/object-list.component.html @@ -17,7 +17,7 @@ (next)="goNext()" >
    -
  • +
- - +
diff --git a/src/app/shared/search-form/search-form.component.spec.ts b/src/app/shared/search-form/search-form.component.spec.ts index 934f00b10ce..84c61f569b8 100644 --- a/src/app/shared/search-form/search-form.component.spec.ts +++ b/src/app/shared/search-form/search-form.component.spec.ts @@ -14,6 +14,7 @@ import { PaginationServiceStub } from '../testing/pagination-service.stub'; import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service'; import { createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; import { FindListOptions } from '../../core/data/find-list-options.model'; +import { BrowserOnlyMockPipe } from '../testing/browser-only-mock.pipe'; describe('SearchFormComponent', () => { let comp: SearchFormComponent; @@ -37,7 +38,10 @@ describe('SearchFormComponent', () => { { provide: SearchConfigurationService, useValue: searchConfigService }, { provide: DSpaceObjectDataService, useValue: { findById: () => createSuccessfulRemoteDataObject$(undefined)} } ], - declarations: [SearchFormComponent] + declarations: [ + SearchFormComponent, + BrowserOnlyMockPipe, + ] }).compileComponents(); })); diff --git a/src/app/shared/search/search-filters/search-filter/search-filter.component.html b/src/app/shared/search/search-filters/search-filter/search-filter.component.html index 230f0727724..452433e165f 100644 --- a/src/app/shared/search/search-filters/search-filter/search-filter.component.html +++ b/src/app/shared/search/search-filters/search-filter/search-filter.component.html @@ -4,6 +4,7 @@ class="filter-name d-flex" [attr.aria-controls]="regionId" [id]="toggleId" [attr.aria-expanded]="false" [attr.aria-label]="((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate" + [attr.data-test]="'filter-toggle' | dsBrowserOnly" >
{{'search.filters.filter.' + filter.name + '.head'| translate}} diff --git a/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts b/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts index 662b380ce88..7abe45ca8c7 100644 --- a/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts +++ b/src/app/shared/search/search-filters/search-filter/search-filter.component.spec.ts @@ -13,6 +13,7 @@ import { FilterType } from '../../models/filter-type.model'; import { SearchConfigurationServiceStub } from '../../../testing/search-configuration-service.stub'; import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component'; import { SequenceService } from '../../../../core/shared/sequence.service'; +import { BrowserOnlyMockPipe } from '../../../testing/browser-only-mock.pipe'; describe('SearchFilterComponent', () => { let comp: SearchFilterComponent; @@ -62,7 +63,10 @@ describe('SearchFilterComponent', () => { TestBed.configureTestingModule({ imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), NoopAnimationsModule], - declarations: [SearchFilterComponent], + declarations: [ + SearchFilterComponent, + BrowserOnlyMockPipe, + ], providers: [ { provide: SearchService, useValue: searchServiceStub }, { diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 37f4fafb1ee..2388c2f13e2 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -173,7 +173,7 @@ import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component'; import { ExternalLinkMenuItemComponent } from './menu/menu-item/external-link-menu-item.component'; - +import { BrowserOnlyPipe } from './utils/browser-only.pipe'; const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here CommonModule, @@ -215,7 +215,8 @@ const PIPES = [ ObjectKeysPipe, ObjectValuesPipe, ConsolePipe, - ObjNgFor + ObjNgFor, + BrowserOnlyPipe, ]; const COMPONENTS = [ diff --git a/src/app/shared/sidebar/filter/sidebar-filter.component.html b/src/app/shared/sidebar/filter/sidebar-filter.component.html index bd392aa715d..79afaa7583c 100644 --- a/src/app/shared/sidebar/filter/sidebar-filter.component.html +++ b/src/app/shared/sidebar/filter/sidebar-filter.component.html @@ -1,5 +1,5 @@
-
+
{{ label | translate }}
diff --git a/src/app/shared/testing/browser-only-mock.pipe.ts b/src/app/shared/testing/browser-only-mock.pipe.ts new file mode 100644 index 00000000000..12e5a7b2d74 --- /dev/null +++ b/src/app/shared/testing/browser-only-mock.pipe.ts @@ -0,0 +1,13 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +/** + * Support dsBrowserOnly in unit tests. + */ +@Pipe({ + name: 'dsBrowserOnly' +}) +export class BrowserOnlyMockPipe implements PipeTransform { + transform(value: string): string | undefined { + return value; + } +} diff --git a/src/app/shared/testing/test-module.ts b/src/app/shared/testing/test-module.ts index b43adde8ae7..7d45dd41f33 100644 --- a/src/app/shared/testing/test-module.ts +++ b/src/app/shared/testing/test-module.ts @@ -5,6 +5,7 @@ import { SharedModule } from '../shared.module'; import { NgComponentOutletDirectiveStub } from './ng-component-outlet-directive.stub'; import { QueryParamsDirectiveStub } from './query-params-directive.stub'; import { RouterLinkDirectiveStub } from './router-link-directive.stub'; +import { BrowserOnlyMockPipe } from './browser-only-mock.pipe'; /** * This module isn't used. It serves to prevent the AoT compiler @@ -21,7 +22,8 @@ import { RouterLinkDirectiveStub } from './router-link-directive.stub'; QueryParamsDirectiveStub, MySimpleItemActionComponent, RouterLinkDirectiveStub, - NgComponentOutletDirectiveStub + NgComponentOutletDirectiveStub, + BrowserOnlyMockPipe, ], exports: [ QueryParamsDirectiveStub diff --git a/src/app/shared/utils/browser-only.pipe.ts b/src/app/shared/utils/browser-only.pipe.ts new file mode 100644 index 00000000000..fc95bfda22e --- /dev/null +++ b/src/app/shared/utils/browser-only.pipe.ts @@ -0,0 +1,24 @@ +import { Inject, Pipe, PipeTransform, PLATFORM_ID } from '@angular/core'; +import { isPlatformBrowser } from '@angular/common'; + +/** + * A pipe that only returns its intput when run in the browser. + * Used to distinguish client-side rendered content from server-side rendered content. + */ +@Pipe({ + name: 'dsBrowserOnly' +}) +export class BrowserOnlyPipe implements PipeTransform { + constructor( + @Inject(PLATFORM_ID) private platformID: any, + ) { + } + + transform(value: string): string | undefined { + if (isPlatformBrowser((this.platformID))) { + return value; + } else { + return undefined; + } + } +} diff --git a/src/app/shared/view-mode-switch/view-mode-switch.component.html b/src/app/shared/view-mode-switch/view-mode-switch.component.html index 2863a4832b2..5f70bc699ce 100644 --- a/src/app/shared/view-mode-switch/view-mode-switch.component.html +++ b/src/app/shared/view-mode-switch/view-mode-switch.component.html @@ -7,7 +7,7 @@ routerLinkActive="active" [class.active]="currentMode === viewModeEnum.ListElement" class="btn btn-secondary" - data-test="list-view"> + [attr.data-test]="'list-view' | dsBrowserOnly"> + [attr.data-test]="'grid-view' | dsBrowserOnly"> + [attr.data-test]="'detail-view' | dsBrowserOnly">
diff --git a/src/app/shared/view-mode-switch/view-mode-switch.component.spec.ts b/src/app/shared/view-mode-switch/view-mode-switch.component.spec.ts index d3618574137..5780ea5cf36 100644 --- a/src/app/shared/view-mode-switch/view-mode-switch.component.spec.ts +++ b/src/app/shared/view-mode-switch/view-mode-switch.component.spec.ts @@ -9,6 +9,7 @@ import { SearchService } from '../../core/shared/search/search.service'; import { ViewModeSwitchComponent } from './view-mode-switch.component'; import { SearchServiceStub } from '../testing/search-service.stub'; import { ViewMode } from '../../core/shared/view-mode.model'; +import { BrowserOnlyMockPipe } from '../testing/browser-only-mock.pipe'; @Component({ template: '' }) class DummyComponent { @@ -36,7 +37,8 @@ describe('ViewModeSwitchComponent', () => { ], declarations: [ ViewModeSwitchComponent, - DummyComponent + DummyComponent, + BrowserOnlyMockPipe, ], providers: [ { provide: SearchService, useValue: searchService }, diff --git a/src/app/submission/form/footer/submission-form-footer.component.html b/src/app/submission/form/footer/submission-form-footer.component.html index 7013c556676..e898e1c2207 100644 --- a/src/app/submission/form/footer/submission-form-footer.component.html +++ b/src/app/submission/form/footer/submission-form-footer.component.html @@ -3,6 +3,7 @@ +
+
+ + + +
+ +
+
+
+
+ +
- diff --git a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.scss b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.scss new file mode 100644 index 00000000000..c3694e67847 --- /dev/null +++ b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.scss @@ -0,0 +1,4 @@ +.auth-bitstream-container { + margin-top: -1em; + margin-bottom: 1.5em; +} diff --git a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts index 76597a135bb..f3313d4cef3 100644 --- a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts +++ b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts @@ -1,3 +1,5 @@ +import { isEqual } from 'lodash'; +import { DSONameService } from './../../../core/breadcrumbs/dso-name.service'; import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @@ -25,7 +27,8 @@ interface BundleBitstreamsMapEntry { @Component({ selector: 'ds-item-authorizations', - templateUrl: './item-authorizations.component.html' + templateUrl: './item-authorizations.component.html', + styleUrls:['./item-authorizations.component.scss'] }) /** * Component that handles the item Authorizations @@ -36,14 +39,20 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { * A map that contains all bitstream of the item's bundles * @type {Observable>>>} */ - public bundleBitstreamsMap: Map>> = new Map>>(); + public bundleBitstreamsMap: Map = new Map(); /** - * The list of bundle for the item + * The list of all bundles for the item * @type {Observable>} */ private bundles$: BehaviorSubject = new BehaviorSubject([]); + /** + * The list of bundles to be displayed in the template + * @type {BehaviorSubject} + */ + bundlesToShow$: BehaviorSubject = new BehaviorSubject([]); + /** * The target editing item * @type {Observable} @@ -56,6 +65,37 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { */ private subs: Subscription[] = []; + /** + * The size of the bundles to be loaded on demand + * @type {number} + */ + bunblesPerPage = 6; + + /** + * The number of current page + * @type {number} + */ + bunblesPageSize = 1; + + /** + * The flag to show or not the 'Load more' button + * based on the condition if all the bundles are loaded or not + * @type {boolean} + */ + allBundlesLoaded = false; + + /** + * Initial size of loaded bitstreams + * The size of incrementation used in bitstream pagination + */ + bitstreamSize = 4; + + /** + * The size of the loaded bitstremas at a certain moment + * @private + */ + private bitstreamPageSize = 4; + /** * Initialize instance variables * @@ -64,7 +104,8 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { */ constructor( private linkService: LinkService, - private route: ActivatedRoute + private route: ActivatedRoute, + private nameService: DSONameService ) { } @@ -72,16 +113,53 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { * Initialize the component, setting up the bundle and bitstream within the item */ ngOnInit(): void { + this.getBundlesPerItem(); + } + + /** + * Return the item's UUID + */ + getItemUUID(): Observable { + return this.item$.pipe( + map((item: Item) => item.id), + first((UUID: string) => isNotEmpty(UUID)) + ); + } + + /** + * Return the item's name + */ + getItemName(): Observable { + return this.item$.pipe( + map((item: Item) => this.nameService.getName(item)) + ); + } + + /** + * Return all item's bundles + * + * @return an observable that emits all item's bundles + */ + getItemBundles(): Observable { + return this.bundles$.asObservable(); + } + + /** + * Get all bundles per item + * and all the bitstreams per bundle + * @param page number of current page + */ + getBundlesPerItem(page: number = 1) { this.item$ = this.route.data.pipe( map((data) => data.dso), getFirstSucceededRemoteDataWithNotEmptyPayload(), map((item: Item) => this.linkService.resolveLink( item, - followLink('bundles', {}, followLink('bitstreams')) + followLink('bundles', {findListOptions: {currentPage : page, elementsPerPage: this.bunblesPerPage}}, followLink('bitstreams')) )) ) as Observable; - const bundles$: Observable> = this.item$.pipe( + const bundles$: Observable> = this.item$.pipe( filter((item: Item) => isNotEmpty(item.bundles)), mergeMap((item: Item) => item.bundles), getFirstSucceededRemoteDataWithNotEmptyPayload(), @@ -96,37 +174,40 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { take(1), map((list: PaginatedList) => list.page) ).subscribe((bundles: Bundle[]) => { - this.bundles$.next(bundles); + if (isEqual(bundles.length,0) || bundles.length < this.bunblesPerPage) { + this.allBundlesLoaded = true; + } + if (isEqual(page, 1)) { + this.bundles$.next(bundles); + this.bundlesToShow$.next(bundles); + } else { + this.bundlesToShow$.next(this.bundles$.getValue().concat(bundles)); + this.bundles$.next(this.bundles$.getValue().concat(bundles)); + } }), bundles$.pipe( take(1), mergeMap((list: PaginatedList) => list.page), map((bundle: Bundle) => ({ id: bundle.id, bitstreams: this.getBundleBitstreams(bundle) })) ).subscribe((entry: BundleBitstreamsMapEntry) => { - this.bundleBitstreamsMap.set(entry.id, entry.bitstreams); + let bitstreamMapValues: BitstreamMapValue = { + isCollapsed: true, + allBitstreamsLoaded: false, + bitstreams: null + }; + let bits = entry.bitstreams.pipe( + map((b: PaginatedList) => { + bitstreamMapValues.allBitstreamsLoaded = b?.page.length < this.bitstreamSize ; + let firstLoaded = [...b.page.slice(0, this.bitstreamSize)]; + return firstLoaded; + }) + ); + bitstreamMapValues.bitstreams = bits; + this.bundleBitstreamsMap.set(entry.id, bitstreamMapValues); }) ); } - /** - * Return the item's UUID - */ - getItemUUID(): Observable { - return this.item$.pipe( - map((item: Item) => item.id), - first((UUID: string) => isNotEmpty(UUID)) - ); - } - - /** - * Return all item's bundles - * - * @return an observable that emits all item's bundles - */ - getItemBundles(): Observable { - return this.bundles$.asObservable(); - } - /** * Return all bundle's bitstreams * @@ -142,6 +223,48 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { ); } + /** + * Changes the collapsible state of the area that contains the bitstream list + * @param bundleId Id of bundle responsible for the requested bitstreams + */ + collapseArea(bundleId: string) { + this.bundleBitstreamsMap.get(bundleId).isCollapsed = !this.bundleBitstreamsMap.get(bundleId).isCollapsed; + } + + /** + * Loads as much bundles as initial value of bundleSize to be displayed + */ + onBunbleLoad(){ + this.bunblesPageSize ++; + this.getBundlesPerItem(this.bunblesPageSize); + } + + /** + * Calculates the bitstreams that are going to be loaded on demand, + * based on the number configured on this.bitstreamSize. + * @param bundle parent of bitstreams that are requested to be shown + * @returns Subscription + */ + onBitstreamsLoad(bundle: Bundle) { + return this.getBundleBitstreams(bundle).pipe( + map((res: PaginatedList) => { + let nextBitstreams = res?.page.slice(this.bitstreamPageSize, this.bitstreamPageSize + this.bitstreamSize); + let bitstreamsToShow = this.bundleBitstreamsMap.get(bundle.id).bitstreams.pipe( + map((existingBits: Bitstream[])=> { + return [... existingBits, ...nextBitstreams]; + }) + ); + this.bitstreamPageSize = this.bitstreamPageSize + this.bitstreamSize; + let bitstreamMapValues: BitstreamMapValue = { + bitstreams: bitstreamsToShow , + isCollapsed: this.bundleBitstreamsMap.get(bundle.id).isCollapsed, + allBitstreamsLoaded: res?.page.length <= this.bitstreamPageSize + }; + this.bundleBitstreamsMap.set(bundle.id, bitstreamMapValues); + }) + ).subscribe(); + } + /** * Unsubscribe from all subscriptions */ @@ -151,3 +274,9 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { .forEach((subscription) => subscription.unsubscribe()); } } + +export interface BitstreamMapValue { + bitstreams: Observable; + isCollapsed: boolean; + allBitstreamsLoaded: boolean; +} diff --git a/src/app/shared/resource-policies/resource-policies.component.html b/src/app/shared/resource-policies/resource-policies.component.html index 0a1ccf79524..5d11ac81f2f 100644 --- a/src/app/shared/resource-policies/resource-policies.component.html +++ b/src/app/shared/resource-policies/resource-policies.component.html @@ -4,9 +4,16 @@
- {{ 'resource-policies.table.headers.title.for.' + resourceType | translate }} {{resourceUUID}} + + {{ 'resource-policies.table.headers.title.for.' + resourceType | translate }} + + {{resourceName}} + + ({{resourceUUID}}) + +
- -
@@ -21,13 +21,13 @@ [resourceName]="bitstream.name">
- +
- +
diff --git a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts index f3313d4cef3..a833b90b208 100644 --- a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts +++ b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts @@ -45,13 +45,7 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { * The list of all bundles for the item * @type {Observable>} */ - private bundles$: BehaviorSubject = new BehaviorSubject([]); - - /** - * The list of bundles to be displayed in the template - * @type {BehaviorSubject} - */ - bundlesToShow$: BehaviorSubject = new BehaviorSubject([]); + bundles$: BehaviorSubject = new BehaviorSubject([]); /** * The target editing item @@ -69,13 +63,13 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { * The size of the bundles to be loaded on demand * @type {number} */ - bunblesPerPage = 6; + bunblesPerPage = 1; /** * The number of current page * @type {number} */ - bunblesPageSize = 1; + bunblesPageSize = 6; /** * The flag to show or not the 'Load more' button @@ -179,9 +173,7 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { } if (isEqual(page, 1)) { this.bundles$.next(bundles); - this.bundlesToShow$.next(bundles); } else { - this.bundlesToShow$.next(this.bundles$.getValue().concat(bundles)); this.bundles$.next(this.bundles$.getValue().concat(bundles)); } }), diff --git a/src/app/shared/resource-policies/resource-policies.component.html b/src/app/shared/resource-policies/resource-policies.component.html index 5d11ac81f2f..d1fd9266b13 100644 --- a/src/app/shared/resource-policies/resource-policies.component.html +++ b/src/app/shared/resource-policies/resource-policies.component.html @@ -6,7 +6,6 @@
{{ 'resource-policies.table.headers.title.for.' + resourceType | translate }} - {{resourceName}} ({{resourceUUID}}) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 76f4f538ea5..cef52fde9ca 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -848,6 +848,12 @@ "collection.edit.tabs.authorizations.title": "Collection Edit - Authorizations", + "collection.edit.item.authorizations.load-bundle-button": "Load more bundles", + + "collection.edit.item.authorizations.load-more-button": "Load more", + + "collection.edit.item.authorizations.show-bitstreams-button": "Show all Bitstreams' Policies for Bundle", + "collection.edit.tabs.metadata.head": "Edit Metadata", "collection.edit.tabs.metadata.title": "Collection Edit - Metadata", From 6cd41be3b80278fd086ffbf6ad7ad023a5aa3e67 Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Mon, 9 May 2022 12:01:46 +0200 Subject: [PATCH 0344/2129] [CST-5677] Changed bunblesPerPage value --- .../item-authorizations/item-authorizations.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts index a833b90b208..f018d1c6425 100644 --- a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts +++ b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts @@ -63,7 +63,7 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { * The size of the bundles to be loaded on demand * @type {number} */ - bunblesPerPage = 1; + bunblesPerPage = 6; /** * The number of current page From 32d7fca27af3d92eda08c998414a2927fb4ad2c3 Mon Sep 17 00:00:00 2001 From: Alisa Ismailati Date: Mon, 9 May 2022 12:02:50 +0200 Subject: [PATCH 0345/2129] [CST-5677] Changed bunblesPageSize value --- .../item-authorizations/item-authorizations.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts index f018d1c6425..3a7a7d95f27 100644 --- a/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts +++ b/src/app/item-page/edit-item-page/item-authorizations/item-authorizations.component.ts @@ -69,7 +69,7 @@ export class ItemAuthorizationsComponent implements OnInit, OnDestroy { * The number of current page * @type {number} */ - bunblesPageSize = 6; + bunblesPageSize = 1; /** * The flag to show or not the 'Load more' button From 51058daf27f0d63aecdc3f28a981ddc23b108ef7 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Tue, 10 May 2022 09:25:59 +1200 Subject: [PATCH 0346/2129] [TLC-254] tidy imports in type bind service --- .../ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts index f8a7376c3e8..5dd4a6627d0 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts @@ -15,7 +15,7 @@ import { OR_OPERATOR } from '@ng-dynamic-forms/core'; -import {hasNoValue, hasValue, isEmpty} from '../../../empty.util'; +import {hasNoValue, hasValue} from '../../../empty.util'; import { FormBuilderService } from '../form-builder.service'; import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; import { DYNAMIC_FORM_CONTROL_TYPE_RELATION_GROUP } from './ds-dynamic-form-constants'; From 870a36180c4836108c23f790e5e49c04460a99b4 Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Mon, 25 Apr 2022 17:26:12 +0200 Subject: [PATCH 0347/2129] 89984: Add ThemedLoadingComponent --- .../epeople-registry.component.html | 2 +- .../eperson-form/eperson-form.component.html | 4 +-- .../groups-registry.component.html | 2 +- .../edit-bitstream-page.component.html | 4 +-- .../browse-by-metadata-page.component.html | 2 +- .../collection-page.component.html | 8 ++--- .../collection-source.component.html | 2 +- .../edit-item-template-page.component.html | 2 +- .../community-list.component.html | 6 ++-- .../community-page.component.html | 2 +- ...ty-page-sub-collection-list.component.html | 2 +- ...ity-page-sub-community-list.component.html | 2 +- .../top-level-community-list.component.html | 2 +- .../item-bitstreams.component.html | 2 +- ...rag-and-drop-bitstream-list.component.html | 2 +- .../edit-relationship-list.component.html | 2 +- .../item-relationships.component.html | 2 +- .../full/full-item-page.component.html | 2 +- .../media-viewer/media-viewer.component.html | 4 +-- .../media-viewer.component.spec.ts | 2 +- .../file-section/file-section.component.html | 2 +- .../file-section.component.spec.ts | 2 +- .../item-page/simple/item-page.component.html | 2 +- .../simple/item-page.component.spec.ts | 2 +- ...etadata-representation-list.component.html | 2 +- .../related-items.component.html | 2 +- .../detail/process-detail.component.html | 2 +- .../deny-request-copy.component.html | 2 +- .../grant-deny-request-copy.component.html | 2 +- .../grant-request-copy.component.html | 2 +- src/app/root/root.component.html | 4 +-- .../user-menu/user-menu.component.html | 2 +- .../shared/browse-by/browse-by.component.html | 2 +- .../browse-by/browse-by.component.spec.ts | 2 +- .../collection-dropdown.component.html | 4 +-- .../comcol-role/comcol-role.component.html | 2 +- .../dso-selector/dso-selector.component.html | 2 +- .../entity-dropdown.component.html | 4 +-- ...sting-metadata-list-element.component.html | 2 +- ...sting-relation-list-element.component.html | 2 +- .../dynamic-relation-group.component.html | 2 +- ...namic-lookup-relation-modal.component.html | 2 +- ...elation-external-source-tab.component.html | 4 +-- ...tion-external-source-tab.component.spec.ts | 4 +-- .../loading/themed-loading.component.ts | 31 +++++++++++++++++++ src/app/shared/log-in/log-in.component.html | 2 +- .../object-detail.component.html | 2 +- .../object-grid/object-grid.component.html | 2 +- ...-search-result-list-element.component.html | 4 +-- ...-search-result-list-element.component.html | 4 +-- .../collection-select.component.html | 2 +- .../item-select/item-select.component.html | 2 +- .../search-results.component.html | 2 +- src/app/shared/shared.module.ts | 2 ++ .../vocabulary-treeview.component.html | 2 +- .../statistics-page.component.html | 2 +- .../form/submission-form.component.html | 2 +- ...-import-external-collection.component.html | 2 +- .../submission-import-external.component.html | 4 +-- ...mission-section-cc-licenses.component.html | 4 +-- .../sections/form/section-form.component.html | 2 +- src/app/thumbnail/thumbnail.component.html | 4 +-- src/app/thumbnail/thumbnail.component.spec.ts | 2 +- 63 files changed, 112 insertions(+), 79 deletions(-) create mode 100644 src/app/shared/loading/themed-loading.component.ts diff --git a/src/app/access-control/epeople-registry/epeople-registry.component.html b/src/app/access-control/epeople-registry/epeople-registry.component.html index 7ef02a76cfb..2d87f21d260 100644 --- a/src/app/access-control/epeople-registry/epeople-registry.component.html +++ b/src/app/access-control/epeople-registry/epeople-registry.component.html @@ -45,7 +45,7 @@
- + {{messagePrefix + '.edit' | translate}}
- +
{{messagePrefix + '.groupsEPersonIsMemberOf' | translate}}
- + {{messagePrefix + 'search.head' | tra
- + {{bitstreamRD?.payload?.name}} ({{bitstreamRD?.payl - +
diff --git a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html index 2321da02041..c0741891eba 100644 --- a/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html +++ b/src/app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component.html @@ -35,7 +35,7 @@ (prev)="goPrev()" (next)="goNext()"> - + diff --git a/src/app/collection-page/collection-page.component.html b/src/app/collection-page/collection-page.component.html index 9d598a3b697..4f5422e300f 100644 --- a/src/app/collection-page/collection-page.component.html +++ b/src/app/collection-page/collection-page.component.html @@ -57,8 +57,8 @@

{{'collection.page.browse.recent.head' | translate}}

- + @@ -75,7 +75,7 @@

{{'collection.page.browse.recent.head' | translate}}

- + diff --git a/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.html b/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.html index b67ee9a1bdd..847ccefdda3 100644 --- a/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.html +++ b/src/app/collection-page/edit-collection-page/collection-source/collection-source.component.html @@ -25,7 +25,7 @@

{{ 'collection.edit.tabs.source.head' | translate }}

- +

{{ 'collection.edit.tabs.source.form.head' | translate }}

diff --git a/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.html b/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.html index f8c5c92e961..37258cd0578 100644 --- a/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.html +++ b/src/app/collection-page/edit-item-template-page/edit-item-template-page.component.html @@ -6,7 +6,7 @@

{{ 'collection.edit.template.head' | translate:{ colle - +

diff --git a/src/app/community-list-page/community-list/community-list.component.html b/src/app/community-list-page/community-list/community-list.component.html index f441dfa36e0..5d53633c4ec 100644 --- a/src/app/community-list-page/community-list/community-list.component.html +++ b/src/app/community-list-page/community-list/community-list.component.html @@ -1,4 +1,4 @@ - + {{ 'communityList.showMore' | translate }} - +
@@ -57,7 +57,7 @@
- +
diff --git a/src/app/community-page/community-page.component.html b/src/app/community-page/community-page.component.html index cf7282eb4bd..95755fdaf1c 100644 --- a/src/app/community-page/community-page.component.html +++ b/src/app/community-page/community-page.component.html @@ -41,5 +41,5 @@ - + diff --git a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.html b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.html index 9928ebd18ae..69f16ee3ac0 100644 --- a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.html +++ b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.html @@ -9,5 +9,5 @@

{{'community.sub-collection-list.head' | translate}}

- +
diff --git a/src/app/community-page/sub-community-list/community-page-sub-community-list.component.html b/src/app/community-page/sub-community-list/community-page-sub-community-list.component.html index 2d14dce60a5..be2788a9f40 100644 --- a/src/app/community-page/sub-community-list/community-page-sub-community-list.component.html +++ b/src/app/community-page/sub-community-list/community-page-sub-community-list.component.html @@ -9,5 +9,5 @@

{{'community.sub-community-list.head' | translate}}

- + diff --git a/src/app/home-page/top-level-community-list/top-level-community-list.component.html b/src/app/home-page/top-level-community-list/top-level-community-list.component.html index dbea87a1752..788db6ea4f9 100644 --- a/src/app/home-page/top-level-community-list/top-level-community-list.component.html +++ b/src/app/home-page/top-level-community-list/top-level-community-list.component.html @@ -10,4 +10,4 @@

{{'home.top-level-communities.head' | translate}}

- + diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html index 315498378a0..0d6a609e745 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html @@ -44,7 +44,7 @@ class="alert alert-info w-100 d-inline-block mt-4" role="alert"> {{'item.edit.bitstreams.empty' | translate}} - +
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html index f7904f6cc8f..f54aa73597d 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component.html @@ -29,5 +29,5 @@
- + diff --git a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html index 86ab93662e4..7cdc903f240 100644 --- a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html +++ b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html @@ -31,5 +31,5 @@
{{"item.edit.relationships.no-relationships" | translate}}
- + diff --git a/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.html b/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.html index 4a53445a6d4..f19ab218719 100644 --- a/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.html +++ b/src/app/item-page/edit-item-page/item-relationships/item-relationships.component.html @@ -32,7 +32,7 @@ >
- +
diff --git a/src/app/item-page/full/full-item-page.component.html b/src/app/item-page/full/full-item-page.component.html index d2655c4ad03..ea97a3957c3 100644 --- a/src/app/item-page/full/full-item-page.component.html +++ b/src/app/item-page/full/full-item-page.component.html @@ -37,5 +37,5 @@
- + diff --git a/src/app/item-page/media-viewer/media-viewer.component.html b/src/app/item-page/media-viewer/media-viewer.component.html index b79b91629f6..4259af52508 100644 --- a/src/app/item-page/media-viewer/media-viewer.component.html +++ b/src/app/item-page/media-viewer/media-viewer.component.html @@ -1,9 +1,9 @@ - + >
diff --git a/src/app/item-page/media-viewer/media-viewer.component.spec.ts b/src/app/item-page/media-viewer/media-viewer.component.spec.ts index cfd72bf4164..39a35ebe61c 100644 --- a/src/app/item-page/media-viewer/media-viewer.component.spec.ts +++ b/src/app/item-page/media-viewer/media-viewer.component.spec.ts @@ -110,7 +110,7 @@ describe('MediaViewerComponent', () => { }); it('should display a loading component', () => { - const loading = fixture.debugElement.query(By.css('ds-loading')); + const loading = fixture.debugElement.query(By.css('ds-themed-loading')); expect(loading.nativeElement).toBeDefined(); }); }); diff --git a/src/app/item-page/simple/field-components/file-section/file-section.component.html b/src/app/item-page/simple/field-components/file-section/file-section.component.html index 3d093f83c91..5fa5e5096f6 100644 --- a/src/app/item-page/simple/field-components/file-section/file-section.component.html +++ b/src/app/item-page/simple/field-components/file-section/file-section.component.html @@ -6,7 +6,7 @@ ({{(file?.sizeBytes) | dsFileSize }}) - + diff --git a/src/app/item-page/simple/field-components/file-section/file-section.component.spec.ts b/src/app/item-page/simple/field-components/file-section/file-section.component.spec.ts index fdd6d14e7dc..2d185aef9ca 100644 --- a/src/app/item-page/simple/field-components/file-section/file-section.component.spec.ts +++ b/src/app/item-page/simple/field-components/file-section/file-section.component.spec.ts @@ -86,7 +86,7 @@ describe('FileSectionComponent', () => { }); it('should display a loading component', () => { - const loading = fixture.debugElement.query(By.css('ds-loading')); + const loading = fixture.debugElement.query(By.css('ds-themed-loading')); expect(loading.nativeElement).toBeDefined(); }); }); diff --git a/src/app/item-page/simple/item-page.component.html b/src/app/item-page/simple/item-page.component.html index 74b61fd976c..d91f4b501df 100644 --- a/src/app/item-page/simple/item-page.component.html +++ b/src/app/item-page/simple/item-page.component.html @@ -9,5 +9,5 @@
- + 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 ff5a1e38d51..0b0f1e1724f 100644 --- a/src/app/item-page/simple/item-page.component.spec.ts +++ b/src/app/item-page/simple/item-page.component.spec.ts @@ -85,7 +85,7 @@ describe('ItemPageComponent', () => { }); it('should display a loading component', () => { - const loading = fixture.debugElement.query(By.css('ds-loading')); + const loading = fixture.debugElement.query(By.css('ds-themed-loading')); expect(loading.nativeElement).toBeDefined(); }); }); diff --git a/src/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.html b/src/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.html index d1281f450a3..e1559cb1297 100644 --- a/src/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.html +++ b/src/app/item-page/simple/metadata-representation-list/metadata-representation-list.component.html @@ -4,7 +4,7 @@ - + - + diff --git a/src/app/request-copy/grant-request-copy/grant-request-copy.component.html b/src/app/request-copy/grant-request-copy/grant-request-copy.component.html index d2c2cfc3c8e..5cb4dbac36e 100644 --- a/src/app/request-copy/grant-request-copy/grant-request-copy.component.html +++ b/src/app/request-copy/grant-request-copy/grant-request-copy.component.html @@ -13,5 +13,5 @@

{{'grant-request-copy.header' | translate}}

- + diff --git a/src/app/root/root.component.html b/src/app/root/root.component.html index 898074352cd..d0465af69ff 100644 --- a/src/app/root/root.component.html +++ b/src/app/root/root.component.html @@ -13,7 +13,7 @@
- +
@@ -25,6 +25,6 @@
- +
diff --git a/src/app/shared/auth-nav-menu/user-menu/user-menu.component.html b/src/app/shared/auth-nav-menu/user-menu/user-menu.component.html index ac55a211e92..736d39d318a 100644 --- a/src/app/shared/auth-nav-menu/user-menu/user-menu.component.html +++ b/src/app/shared/auth-nav-menu/user-menu/user-menu.component.html @@ -1,4 +1,4 @@ - +
{{(user$ | async)?.name}} ({{(user$ | async)?.email}}) {{'nav.profile' | translate}} diff --git a/src/app/shared/browse-by/browse-by.component.html b/src/app/shared/browse-by/browse-by.component.html index 6d1422293db..645a987abe0 100644 --- a/src/app/shared/browse-by/browse-by.component.html +++ b/src/app/shared/browse-by/browse-by.component.html @@ -34,7 +34,7 @@
- + diff --git a/src/app/shared/comcol/comcol-forms/edit-comcol-page/comcol-role/comcol-role.component.html b/src/app/shared/comcol/comcol-forms/edit-comcol-page/comcol-role/comcol-role.component.html index b0a319b4ff3..440785b89bc 100644 --- a/src/app/shared/comcol/comcol-forms/edit-comcol-page/comcol-role/comcol-role.component.html +++ b/src/app/shared/comcol/comcol-forms/edit-comcol-page/comcol-role/comcol-role.component.html @@ -13,7 +13,7 @@
- +
{{'comcol-role.edit.no-group' | translate}}
diff --git a/src/app/shared/dso-selector/dso-selector/dso-selector.component.html b/src/app/shared/dso-selector/dso-selector/dso-selector.component.html index 4b46d3bc3ff..d4283246d8f 100644 --- a/src/app/shared/dso-selector/dso-selector/dso-selector.component.html +++ b/src/app/shared/dso-selector/dso-selector/dso-selector.component.html @@ -31,7 +31,7 @@
diff --git a/src/app/shared/entity-dropdown/entity-dropdown.component.html b/src/app/shared/entity-dropdown/entity-dropdown.component.html index 59c242ef973..a4d539625f5 100644 --- a/src/app/shared/entity-dropdown/entity-dropdown.component.html +++ b/src/app/shared/entity-dropdown/entity-dropdown.component.html @@ -21,8 +21,8 @@ diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.html index 07ea131a008..62d34a86254 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component.html @@ -1,7 +1,7 @@
- + diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component.html index 15087d25531..ff91b18e1c9 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component.html @@ -1,7 +1,7 @@
- + diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.html index 84bc0f4ffed..05f443aad57 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/dynamic-relation-group.component.html @@ -57,7 +57,7 @@
- +
{{ ('submission.sections.describe.relat
- + diff --git a/src/app/shared/object-list/my-dspace-result-list-element/workflow-item-search-result/workflow-item-search-result-list-element.component.html b/src/app/shared/object-list/my-dspace-result-list-element/workflow-item-search-result/workflow-item-search-result-list-element.component.html index 74fc5fd06d6..f26de733b28 100644 --- a/src/app/shared/object-list/my-dspace-result-list-element/workflow-item-search-result/workflow-item-search-result-list-element.component.html +++ b/src/app/shared/object-list/my-dspace-result-list-element/workflow-item-search-result/workflow-item-search-result-list-element.component.html @@ -6,6 +6,6 @@ - + [showMessage]="false"> diff --git a/src/app/shared/object-list/my-dspace-result-list-element/workspace-item-search-result/workspace-item-search-result-list-element.component.html b/src/app/shared/object-list/my-dspace-result-list-element/workspace-item-search-result/workspace-item-search-result-list-element.component.html index 41d95b87afe..2f0b04ef12b 100644 --- a/src/app/shared/object-list/my-dspace-result-list-element/workspace-item-search-result/workspace-item-search-result-list-element.component.html +++ b/src/app/shared/object-list/my-dspace-result-list-element/workspace-item-search-result/workspace-item-search-result-list-element.component.html @@ -6,6 +6,6 @@ - + [showMessage]="false"> diff --git a/src/app/shared/object-select/collection-select/collection-select.component.html b/src/app/shared/object-select/collection-select/collection-select.component.html index 27ebcd96433..8ed41c5226d 100644 --- a/src/app/shared/object-select/collection-select/collection-select.component.html +++ b/src/app/shared/object-select/collection-select/collection-select.component.html @@ -28,7 +28,7 @@ {{'collection.select.empty' | translate}}
- +
- + diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 715ee66a99b..f9391afdb49 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -177,6 +177,7 @@ import { ScopeSelectorModalComponent } from './search-form/scope-selector-modal/ import { BitstreamRequestACopyPageComponent } from './bitstream-request-a-copy-page/bitstream-request-a-copy-page.component'; import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; +import { ThemedLoadingComponent } from './loading/themed-loading.component'; const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here @@ -234,6 +235,7 @@ const COMPONENTS = [ FileSectionComponent, LangSwitchComponent, LoadingComponent, + ThemedLoadingComponent, LogInComponent, LogOutComponent, NumberPickerComponent, diff --git a/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.html b/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.html index 3f57e6a4c34..39c62d6e534 100644 --- a/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.html +++ b/src/app/shared/vocabulary-treeview/vocabulary-treeview.component.html @@ -23,7 +23,7 @@
- +

{{'vocabulary-treeview.search.no-result' | translate}}

diff --git a/src/app/statistics-page/statistics-page/statistics-page.component.html b/src/app/statistics-page/statistics-page/statistics-page.component.html index 5cf1e9c8b5f..c6938c7582b 100644 --- a/src/app/statistics-page/statistics-page/statistics-page.component.html +++ b/src/app/statistics-page/statistics-page/statistics-page.component.html @@ -11,7 +11,7 @@ - + diff --git a/src/app/submission/form/submission-form.component.html b/src/app/submission/form/submission-form.component.html index c86d4e01959..a80fe35f4e3 100644 --- a/src/app/submission/form/submission-form.component.html +++ b/src/app/submission/form/submission-form.component.html @@ -22,7 +22,7 @@
- +
@@ -26,7 +26,7 @@ diff --git a/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html b/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html index 7c8ce67b88f..6703634b6b2 100644 --- a/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html +++ b/src/app/entity-groups/research-entities/item-pages/org-unit/org-unit.component.html @@ -57,12 +57,12 @@

[relationTypes]="[{ label: 'isOrgUnitOfPerson', filter: 'isOrgUnitOfPerson', - configuration: 'person' + configuration: 'person-relationships' }, { label: 'isOrgUnitOfProject', filter: 'isOrgUnitOfProject', - configuration: 'project' + configuration: 'project-relationships' }]"> diff --git a/src/app/entity-groups/research-entities/item-pages/person/person.component.html b/src/app/entity-groups/research-entities/item-pages/person/person.component.html index 6e71f775d6b..4b7b3bed326 100644 --- a/src/app/entity-groups/research-entities/item-pages/person/person.component.html +++ b/src/app/entity-groups/research-entities/item-pages/person/person.component.html @@ -68,7 +68,8 @@

From 36208d13033f1b33d1bfaf15a84c18a7a3ccb593 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Wed, 11 May 2022 12:01:35 +0200 Subject: [PATCH 0360/2129] [CST-5307] Fix visibility toggle and address review feedback --- .../profile/researcher-profile.service.ts | 14 ++-- .../profile-claim.service.spec.ts | 16 ++--- .../profile-claim/profile-claim.service.ts | 8 ++- ...rofile-page-researcher-form.component.html | 9 ++- ...ile-page-researcher-form.component.spec.ts | 68 ++++++++++++++----- .../profile-page-researcher-form.component.ts | 19 +++--- src/assets/i18n/en.json5 | 2 + 7 files changed, 89 insertions(+), 47 deletions(-) diff --git a/src/app/core/profile/researcher-profile.service.ts b/src/app/core/profile/researcher-profile.service.ts index eab6ea3d483..0c39396950a 100644 --- a/src/app/core/profile/researcher-profile.service.ts +++ b/src/app/core/profile/researcher-profile.service.ts @@ -6,7 +6,7 @@ import { Router } from '@angular/router'; import { Store } from '@ngrx/store'; import { Operation, ReplaceOperation } from 'fast-json-patch'; import { Observable, of as observableOf } from 'rxjs'; -import { catchError, find, map, switchMap, tap } from 'rxjs/operators'; +import { catchError, find, map, tap } from 'rxjs/operators'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { dataService } from '../cache/builders/build-decorators'; @@ -142,18 +142,14 @@ export class ResearcherProfileService { * @param researcherProfile the profile to update * @param visible the visibility value to set */ - public setVisibility(researcherProfile: ResearcherProfile, visible: boolean): Observable { - + public setVisibility(researcherProfile: ResearcherProfile, visible: boolean): Observable> { const replaceOperation: ReplaceOperation = { path: '/visible', op: 'replace', value: visible }; - return this.patch(researcherProfile, [replaceOperation]).pipe( - switchMap(() => this.findById(researcherProfile.id)), - getFirstSucceededRemoteDataPayload() - ); + return this.patch(researcherProfile, [replaceOperation]); } /** @@ -181,6 +177,8 @@ export class ResearcherProfileService { } private patch(researcherProfile: ResearcherProfile, operations: Operation[]): Observable> { - return this.dataService.patch(researcherProfile, operations); + return this.dataService.patch(researcherProfile, operations).pipe( + getFirstCompletedRemoteData() + ); } } diff --git a/src/app/profile-page/profile-claim/profile-claim.service.spec.ts b/src/app/profile-page/profile-claim/profile-claim.service.spec.ts index 4030c7900c9..a06934231ba 100644 --- a/src/app/profile-page/profile-claim/profile-claim.service.spec.ts +++ b/src/app/profile-page/profile-claim/profile-claim.service.spec.ts @@ -110,7 +110,7 @@ describe('ProfileClaimService', () => { page: [] }); const searchResultRD = createSuccessfulRemoteDataObject(searchResult); - const emptyRearchResultRD = createSuccessfulRemoteDataObject(emptySearchResult); + const emptySearchResultRD = createSuccessfulRemoteDataObject(emptySearchResult); beforeEach(() => { scheduler = getTestScheduler(); @@ -127,7 +127,7 @@ describe('ProfileClaimService', () => { describe('when has suggestions', () => { beforeEach(() => { - spyOn(service, 'search').and.returnValue(observableOf(searchResultRD)); + spyOn(service, 'searchForSuggestions').and.returnValue(observableOf(searchResultRD)); }); it('should return true', () => { @@ -142,7 +142,7 @@ describe('ProfileClaimService', () => { describe('when has not suggestions', () => { beforeEach(() => { - spyOn(service, 'search').and.returnValue(observableOf(emptyRearchResultRD)); + spyOn(service, 'searchForSuggestions').and.returnValue(observableOf(emptySearchResultRD)); }); it('should return false', () => { @@ -176,7 +176,7 @@ describe('ProfileClaimService', () => { }); it('should return the proper search object', () => { - const result = service.search(eperson); + const result = service.searchForSuggestions(eperson); const expected = cold('(a|)', { a: searchResultRD }); @@ -187,13 +187,13 @@ describe('ProfileClaimService', () => { describe('when has not suggestions', () => { beforeEach(() => { - searchService.search.and.returnValue(observableOf(emptyRearchResultRD)); + searchService.search.and.returnValue(observableOf(emptySearchResultRD)); }); it('should return null', () => { - const result = service.search(eperson); + const result = service.searchForSuggestions(eperson); const expected = cold('(a|)', { - a: emptyRearchResultRD + a: emptySearchResultRD }); expect(result).toBeObservable(expected); }); @@ -202,7 +202,7 @@ describe('ProfileClaimService', () => { describe('when has not valid eperson', () => { it('should return null', () => { - const result = service.search(null); + const result = service.searchForSuggestions(null); const expected = cold('(a|)', { a: null }); diff --git a/src/app/profile-page/profile-claim/profile-claim.service.ts b/src/app/profile-page/profile-claim/profile-claim.service.ts index a61404540b1..62517c4b219 100644 --- a/src/app/profile-page/profile-claim/profile-claim.service.ts +++ b/src/app/profile-page/profile-claim/profile-claim.service.ts @@ -27,7 +27,7 @@ export class ProfileClaimService { * @param eperson the eperson */ hasProfilesToSuggest(eperson: EPerson): Observable { - return this.search(eperson).pipe( + return this.searchForSuggestions(eperson).pipe( map((rd: RemoteData>) => { return isNotEmpty(rd) && rd.hasSucceeded && rd.payload?.page?.length > 0; }) @@ -36,9 +36,10 @@ export class ProfileClaimService { /** * Returns profiles that could be associated with the given user. + * * @param eperson the user */ - search(eperson: EPerson): Observable>> { + searchForSuggestions(eperson: EPerson): Observable>> { const query = this.personQueryData(eperson); if (isEmpty(query)) { return of(null); @@ -48,6 +49,7 @@ export class ProfileClaimService { /** * Search object by the given query. + * * @param query the query for the search */ private lookup(query: string): Observable>> { @@ -71,7 +73,7 @@ export class ProfileClaimService { if (eperson) { const firstname = eperson.firstMetadataValue('eperson.firstname'); const lastname = eperson.firstMetadataValue('eperson.lastname'); - return 'dc.title:' + eperson.name + ' OR (person.familyName:' + lastname + ' AND person.givenName:' + firstname + ')'; + return '(dc.title:' + eperson.name + ') OR (person.familyName:' + lastname + ' AND person.givenName:' + firstname + ')'; } else { return null; } diff --git a/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.html b/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.html index bb554187446..2d959c1dfea 100644 --- a/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.html +++ b/src/app/profile-page/profile-page-researcher-form/profile-page-researcher-form.component.html @@ -3,14 +3,17 @@

{{'researcher.profile.associated' | translate}}

{{'researcher.profile.status' | translate}} - +

{{'researcher.profile.not.associated' | translate}}

- + diff --git a/src/app/shared/rss-feed/rss.component.html b/src/app/shared/rss-feed/rss.component.html new file mode 100644 index 00000000000..8868539b5c0 --- /dev/null +++ b/src/app/shared/rss-feed/rss.component.html @@ -0,0 +1,5 @@ + +
+ +
+ diff --git a/src/app/shared/rss-feed/rss.component.scss b/src/app/shared/rss-feed/rss.component.scss new file mode 100644 index 00000000000..929bb453ac5 --- /dev/null +++ b/src/app/shared/rss-feed/rss.component.scss @@ -0,0 +1,12 @@ +:host { + .dropdown-toggle::after { + display: none; + } + .dropdown-item { + padding-left: 20px; + } +} + +.margin-right { + margin-right: .5em; +} \ No newline at end of file diff --git a/src/app/shared/rss-feed/rss.component.spec.ts b/src/app/shared/rss-feed/rss.component.spec.ts new file mode 100644 index 00000000000..bbfd5442b3f --- /dev/null +++ b/src/app/shared/rss-feed/rss.component.spec.ts @@ -0,0 +1,109 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { RemoteData } from '../../core/data/remote-data'; +import { GroupDataService } from '../../core/eperson/group-data.service'; +import { PaginationService } from '../../core/pagination/pagination.service'; +import { LinkHeadService } from '../../core/services/link-head.service'; +import { Collection } from '../../core/shared/collection.model'; +import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; +import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; +import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; +import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; +import { PaginatedSearchOptions } from '../search/paginated-search-options.model'; +import { PaginationServiceStub } from '../testing/pagination-service.stub'; +import { createPaginatedList } from '../testing/utils.test'; +import { RSSComponent } from './rss.component'; +import { of as observableOf } from 'rxjs'; + + + +describe('RssComponent', () => { + let comp: RSSComponent; + let options: SortOptions; + let fixture: ComponentFixture; + let uuid: string; + let query: string; + let groupDataService: GroupDataService; + let linkHeadService: LinkHeadService; + let configurationDataService: ConfigurationDataService; + let paginationService; + + beforeEach(waitForAsync(() => { + const mockCollection: Collection = Object.assign(new Collection(), { + id: 'ce41d451-97ed-4a9c-94a1-7de34f16a9f4', + name: 'test-collection', + _links: { + mappedItems: { + href: 'https://rest.api/collections/ce41d451-97ed-4a9c-94a1-7de34f16a9f4/mappedItems' + }, + self: { + href: 'https://rest.api/collections/ce41d451-97ed-4a9c-94a1-7de34f16a9f4' + } + } + }); + configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + const mockCollectionRD: RemoteData = createSuccessfulRemoteDataObject(mockCollection); + const mockSearchOptions = observableOf(new PaginatedSearchOptions({ + pagination: Object.assign(new PaginationComponentOptions(), { + id: 'search-page-configuration', + pageSize: 10, + currentPage: 1 + }), + sort: new SortOptions('dc.title', SortDirection.ASC), + scope: mockCollection.id + })); + groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '' + }); + paginationService = new PaginationServiceStub(); + const searchConfigService = { + paginatedSearchOptions: mockSearchOptions + }; + TestBed.configureTestingModule({ + providers: [ + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: SearchConfigurationService, useValue: searchConfigService}, + { provide: PaginationService, useValue: paginationService } + ], + declarations: [RSSComponent] + }).compileComponents(); + })); + + beforeEach(() => { + options = new SortOptions('dc.title', SortDirection.DESC); + uuid = '2cfcf65e-0a51-4bcb-8592-b8db7b064790'; + query = 'test'; + fixture = TestBed.createComponent(RSSComponent); + comp = fixture.componentInstance; + }); + + it('should formulate the correct url given params in url', () => { + const route = comp.formulateRoute(uuid, options, query); + expect(route).toBe('/opensearch/search?format=atom&scope=2cfcf65e-0a51-4bcb-8592-b8db7b064790&sort=dc.title&sort_direction=DESC&query=test'); + }); + + it('should skip uuid if its null', () => { + const route = comp.formulateRoute(null, options, query); + expect(route).toBe('/opensearch/search?format=atom&sort=dc.title&sort_direction=DESC&query=test'); + }); + + it('should default to query * if none provided', () => { + const route = comp.formulateRoute(null, options, null); + expect(route).toBe('/opensearch/search?format=atom&sort=dc.title&sort_direction=DESC&query=*'); + }); +}); + diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts new file mode 100644 index 00000000000..036148b368e --- /dev/null +++ b/src/app/shared/rss-feed/rss.component.ts @@ -0,0 +1,94 @@ +import { + ChangeDetectionStrategy, + Component, + OnDestroy, + OnInit, + ViewEncapsulation +} from '@angular/core'; +import { BehaviorSubject, Observable } from 'rxjs'; +import { GroupDataService } from '../../core/eperson/group-data.service'; +import { LinkHeadService } from '../../core/services/link-head.service'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { getFirstCompletedRemoteData } from '../../core/shared/operators'; +import { environment } from '../../../../src/environments/environment'; +import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; +import { SortOptions } from '../../core/cache/models/sort-options.model'; +import { PaginationService } from '../../core/pagination/pagination.service'; + + +/** + * The default pagination controls component. + */ +@Component({ + exportAs: 'rssComponent', + selector: 'ds-rss', + styleUrls: ['rss.component.scss'], + templateUrl: 'rss.component.html', + changeDetection: ChangeDetectionStrategy.Default, + encapsulation: ViewEncapsulation.Emulated +}) +export class RSSComponent implements OnInit, OnDestroy { + + route$: BehaviorSubject; + + isEnabled$: BehaviorSubject = new BehaviorSubject(false); + + uuid: string; + configuration$: Observable; + sortOption$: Observable; + + constructor(private groupDataService: GroupDataService, + private linkHeadService: LinkHeadService, + private configurationService: ConfigurationDataService, + private searchConfigurationService: SearchConfigurationService, + protected paginationService: PaginationService) { + } + ngOnDestroy(): void { + this.linkHeadService.removeTag("rel='alternate'"); + } + + ngOnInit(): void { + this.configuration$ = this.searchConfigurationService.getCurrentConfiguration('default'); + + this.configurationService.findByPropertyName('websvc.opensearch.enable').pipe( + getFirstCompletedRemoteData(), + ).subscribe((result) => { + const enabled = Boolean(result.payload.values[0]); + this.isEnabled$.next(enabled); + }); + + this.searchConfigurationService.getCurrentQuery('').subscribe((query) => { + this.sortOption$ = this.paginationService.getCurrentSort(this.searchConfigurationService.paginationID, null, true); + this.sortOption$.subscribe((sort) => { + this.uuid = this.groupDataService.getUUIDFromString(window.location.href); + + const route = environment.rest.baseUrl + this.formulateRoute(this.uuid, sort, query); + + this.linkHeadService.addTag({ + href: route, + type: 'application/atom+xml', + rel: 'alternate', + title: 'Sitewide Atom feed' + }); + this.route$ = new BehaviorSubject(route); + }); + }); + } + + formulateRoute(uuid: string, sort: SortOptions, query: string): string { + let route = 'search?format=atom'; + if (uuid) { + route += `&scope=${uuid}`; + } + if (sort.direction && sort.field) { + route += `&sort=${sort.field}&sort_direction=${sort.direction}`; + } + if (query) { + route += `&query=${query}`; + } else { + route += `&query=*`; + } + route = '/opensearch/' + route; + return route; + } +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 12b6a482dcd..c70aff61920 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -173,10 +173,9 @@ import { BitstreamRequestACopyPageComponent } from './bitstream-request-a-copy-p import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component'; -import { ExternalLinkMenuItemComponent } from './menu/menu-item/external-link-menu-item.component'; +import { RSSComponent } from './rss-feed/rss.component'; const MODULES = [ - // Do NOT include UniversalModule, HttpModule, or JsonpModule here CommonModule, SortablejsModule, FileUploadModule, @@ -239,6 +238,7 @@ const COMPONENTS = [ AbstractListableElementComponent, ObjectCollectionComponent, PaginationComponent, + RSSComponent, SearchFormComponent, PageWithSidebarComponent, SidebarDropdownComponent, diff --git a/src/environments/environment.dev.ts b/src/environments/environment.dev.ts new file mode 100644 index 00000000000..999abd32eeb --- /dev/null +++ b/src/environments/environment.dev.ts @@ -0,0 +1,17 @@ +export const environment = { + ui: { + ssl: false, + host: 'localhost', + port: 18080, + nameSpace: '/' + }, + rest: { + ssl: false, + host: 'localhost', + port: 8080, + nameSpace: '/server' + }, + universal: { + preboot: false + } +}; diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts new file mode 100644 index 00000000000..c31da7b791f --- /dev/null +++ b/src/environments/environment.prod.ts @@ -0,0 +1,17 @@ +export const environment = { + ui: { + ssl: false, + host: 'localhost', + port: 18080, + nameSpace: '/' + }, + rest: { + ssl: false, + host: 'localhost', + port: 8080, + nameSpace: '/server' + }, + universal: { + preboot: true + } +}; From b8a96e48a7b885cc4424b720bfb9dbf012e82f23 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 10 Dec 2021 12:25:51 -0500 Subject: [PATCH 0370/2129] Fix test files to pass down necessary providers --- .../collection-item-mapper.component.spec.ts | 28 ++++++++++++++++- ...page-sub-collection-list.component.spec.ts | 31 +++++++++++++++++++ ...-page-sub-community-list.component.spec.ts | 30 ++++++++++++++++++ src/app/core/services/link-head.service.ts | 8 +---- ...top-level-community-list.component.spec.ts | 30 ++++++++++++++++++ .../edit-relationship-list.component.spec.ts | 29 +++++++++++++++++ .../collection-select.component.spec.ts | 31 ++++++++++++++++++- .../item-select/item-select.component.spec.ts | 30 +++++++++++++++++- src/app/shared/rss-feed/rss.component.scss | 2 +- src/app/shared/rss-feed/rss.component.spec.ts | 7 +++-- .../search-configuration-service.stub.ts | 4 +++ 11 files changed, 216 insertions(+), 14 deletions(-) diff --git a/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts b/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts index 7f0e6815ed1..142604c9b24 100644 --- a/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts +++ b/src/app/collection-page/collection-item-mapper/collection-item-mapper.component.spec.ts @@ -43,6 +43,10 @@ import { createPaginatedList } from '../../shared/testing/utils.test'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { MyDSpacePageComponent, SEARCH_CONFIG_SERVICE } from '../../my-dspace-page/my-dspace-page.component'; import { SearchConfigurationServiceStub } from '../../shared/testing/search-configuration-service.stub'; +import { GroupDataService } from '../../core/eperson/group-data.service'; +import { LinkHeadService } from '../../core/services/link-head.service'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; describe('CollectionItemMapperComponent', () => { let comp: CollectionItemMapperComponent; @@ -143,6 +147,25 @@ describe('CollectionItemMapperComponent', () => { isAuthorized: observableOf(true) }); + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [CommonModule, FormsModule, RouterTestingModule.withRoutes([]), TranslateModule.forRoot(), NgbModule], @@ -159,7 +182,10 @@ describe('CollectionItemMapperComponent', () => { { provide: HostWindowService, useValue: new HostWindowServiceStub(0) }, { provide: ObjectSelectService, useValue: new ObjectSelectServiceStub() }, { provide: RouteService, useValue: routeServiceStub }, - { provide: AuthorizationDataService, useValue: authorizationDataService } + { provide: AuthorizationDataService, useValue: authorizationDataService }, + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, ] }).overrideComponent(CollectionItemMapperComponent, { set: { diff --git a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts index ec61fac6130..c0ce5369ff6 100644 --- a/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts +++ b/src/app/community-page/sub-collection-list/community-page-sub-collection-list.component.spec.ts @@ -25,6 +25,14 @@ import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { ThemeService } from '../../shared/theme-support/theme.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { FindListOptions } from '../../core/data/find-list-options.model'; +import { GroupDataService } from '../../core/eperson/group-data.service'; +import { LinkHeadService } from '../../core/services/link-head.service'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; +import { SearchServiceStub } from '../../shared/testing/search-service.stub'; +import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; +import { createPaginatedList } from '../../shared/testing/utils.test'; +import { SearchConfigurationServiceStub } from '../../shared/testing/search-configuration-service.stub'; describe('CommunityPageSubCollectionList Component', () => { let comp: CommunityPageSubCollectionListComponent; @@ -122,6 +130,25 @@ describe('CommunityPageSubCollectionList Component', () => { themeService = getMockThemeService(); + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [ @@ -138,6 +165,10 @@ describe('CommunityPageSubCollectionList Component', () => { { provide: PaginationService, useValue: paginationService }, { provide: SelectableListService, useValue: {} }, { provide: ThemeService, useValue: themeService }, + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts b/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts index 2bc829a3b05..3392ada9943 100644 --- a/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts +++ b/src/app/community-page/sub-community-list/community-page-sub-community-list.component.spec.ts @@ -25,6 +25,13 @@ import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { ThemeService } from '../../shared/theme-support/theme.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { FindListOptions } from '../../core/data/find-list-options.model'; +import { GroupDataService } from '../../core/eperson/group-data.service'; +import { LinkHeadService } from '../../core/services/link-head.service'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; +import { SearchConfigurationServiceStub } from '../../shared/testing/search-configuration-service.stub'; +import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; +import { createPaginatedList } from '../../shared/testing/utils.test'; describe('CommunityPageSubCommunityListComponent Component', () => { let comp: CommunityPageSubCommunityListComponent; @@ -119,6 +126,25 @@ describe('CommunityPageSubCommunityListComponent Component', () => { } }; + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + const paginationService = new PaginationServiceStub(); themeService = getMockThemeService(); @@ -139,6 +165,10 @@ describe('CommunityPageSubCommunityListComponent Component', () => { { provide: PaginationService, useValue: paginationService }, { provide: SelectableListService, useValue: {} }, { provide: ThemeService, useValue: themeService }, + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/src/app/core/services/link-head.service.ts b/src/app/core/services/link-head.service.ts index 29ab62ff137..12c3ff197d8 100644 --- a/src/app/core/services/link-head.service.ts +++ b/src/app/core/services/link-head.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Optional, RendererFactory2, ViewEncapsulation, Inject } from '@angular/core'; +import { Injectable, RendererFactory2, ViewEncapsulation, Inject } from '@angular/core'; import { DOCUMENT } from '@angular/common'; @Injectable() @@ -22,7 +22,6 @@ export class LinkHeadService { const link = renderer.createElement('link'); const head = this.document.head; - const selector = this._parseSelector(tag); if (head === null) { throw new Error(' not found within DOCUMENT.'); @@ -61,11 +60,6 @@ export class LinkHeadService { } } } - - private _parseSelector(tag: LinkDefinition): string { - const attr: string = tag.rel ? 'rel' : 'hreflang'; - return `${attr}="${tag[attr]}"`; - } } export declare type LinkDefinition = { diff --git a/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts b/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts index eb52ca9243e..2561770942d 100644 --- a/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts +++ b/src/app/home-page/top-level-community-list/top-level-community-list.component.spec.ts @@ -25,6 +25,13 @@ import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { ThemeService } from '../../shared/theme-support/theme.service'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { FindListOptions } from '../../core/data/find-list-options.model'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { GroupDataService } from '../../core/eperson/group-data.service'; +import { LinkHeadService } from '../../core/services/link-head.service'; +import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; +import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; +import { createPaginatedList } from '../../shared/testing/utils.test'; +import { SearchConfigurationServiceStub } from '../../shared/testing/search-configuration-service.stub'; describe('TopLevelCommunityList Component', () => { let comp: TopLevelCommunityListComponent; @@ -114,6 +121,25 @@ describe('TopLevelCommunityList Component', () => { themeService = getMockThemeService(); + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ imports: [ @@ -130,6 +156,10 @@ describe('TopLevelCommunityList Component', () => { { provide: PaginationService, useValue: paginationService }, { provide: SelectableListService, useValue: {} }, { provide: ThemeService, useValue: themeService }, + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts index b0d8046cf4f..f9e889bba59 100644 --- a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts @@ -23,6 +23,12 @@ import { PaginationComponent } from '../../../../shared/pagination/pagination.co import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model'; import { RelationshipTypeService } from '../../../../core/data/relationship-type.service'; import { FieldChangeType } from '../../../../core/data/object-updates/field-change-type.model'; +import { GroupDataService } from '../../../../core/eperson/group-data.service'; +import { ConfigurationDataService } from '../../../../core/data/configuration-data.service'; +import { LinkHeadService } from '../../../../core/services/link-head.service'; +import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; +import { SearchConfigurationServiceStub } from '../../../../shared/testing/search-configuration-service.stub'; +import { ConfigurationProperty } from '../../../../core/shared/configuration-property.model'; let comp: EditRelationshipListComponent; let fixture: ComponentFixture; @@ -174,6 +180,25 @@ describe('EditRelationshipListComponent', () => { hostWindowService = new HostWindowServiceStub(1200); + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + TestBed.configureTestingModule({ imports: [SharedModule, TranslateModule.forRoot()], declarations: [EditRelationshipListComponent], @@ -185,6 +210,10 @@ describe('EditRelationshipListComponent', () => { { provide: PaginationService, useValue: paginationService }, { provide: HostWindowService, useValue: hostWindowService }, { provide: RelationshipTypeService, useValue: relationshipTypeService }, + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, ], schemas: [ NO_ERRORS_SCHEMA ] diff --git a/src/app/shared/object-select/collection-select/collection-select.component.spec.ts b/src/app/shared/object-select/collection-select/collection-select.component.spec.ts index 5714db23858..1b89fd32c19 100644 --- a/src/app/shared/object-select/collection-select/collection-select.component.spec.ts +++ b/src/app/shared/object-select/collection-select/collection-select.component.spec.ts @@ -17,6 +17,12 @@ import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../testing/pagination-service.stub'; import { of as observableOf } from 'rxjs'; import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { LinkHeadService } from '../../../core/services/link-head.service'; +import { GroupDataService } from '../../../core/eperson/group-data.service'; +import { ConfigurationDataService } from '../../../core/data/configuration-data.service'; +import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service'; +import { SearchConfigurationServiceStub } from '../../testing/search-configuration-service.stub'; +import { ConfigurationProperty } from '../../../core/shared/configuration-property.model'; describe('CollectionSelectComponent', () => { let comp: CollectionSelectComponent; @@ -44,6 +50,25 @@ describe('CollectionSelectComponent', () => { isAuthorized: observableOf(true) }); + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + const paginationService = new PaginationServiceStub(); beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ @@ -53,7 +78,11 @@ describe('CollectionSelectComponent', () => { { provide: ObjectSelectService, useValue: new ObjectSelectServiceStub([mockCollectionList[1].id]) }, { provide: HostWindowService, useValue: new HostWindowServiceStub(0) }, { provide: PaginationService, useValue: paginationService }, - { provide: AuthorizationDataService, useValue: authorizationDataService } + { provide: AuthorizationDataService, useValue: authorizationDataService }, + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/src/app/shared/object-select/item-select/item-select.component.spec.ts b/src/app/shared/object-select/item-select/item-select.component.spec.ts index de52f1c3c25..25340ee8628 100644 --- a/src/app/shared/object-select/item-select/item-select.component.spec.ts +++ b/src/app/shared/object-select/item-select/item-select.component.spec.ts @@ -18,6 +18,12 @@ import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationServiceStub } from '../../testing/pagination-service.stub'; import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; +import { ConfigurationDataService } from '../../../core/data/configuration-data.service'; +import { SearchConfigurationService } from '../../../core/shared/search/search-configuration.service'; +import { LinkHeadService } from '../../../core/services/link-head.service'; +import { GroupDataService } from '../../../core/eperson/group-data.service'; +import { SearchConfigurationServiceStub } from '../../testing/search-configuration-service.stub'; +import { ConfigurationProperty } from '../../../core/shared/configuration-property.model'; describe('ItemSelectComponent', () => { let comp: ItemSelectComponent; @@ -70,6 +76,24 @@ describe('ItemSelectComponent', () => { const authorizationDataService = new AuthorizationDataService(null, null, null, null, null, null, null, null, null, null); + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ @@ -79,7 +103,11 @@ describe('ItemSelectComponent', () => { { provide: ObjectSelectService, useValue: new ObjectSelectServiceStub([mockItemList[1].id]) }, { provide: HostWindowService, useValue: new HostWindowServiceStub(0) }, { provide: PaginationService, useValue: paginationService }, - { provide: AuthorizationDataService, useValue: authorizationDataService } + { provide: AuthorizationDataService, useValue: authorizationDataService }, + { provide: GroupDataService, useValue: groupDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, ], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/src/app/shared/rss-feed/rss.component.scss b/src/app/shared/rss-feed/rss.component.scss index 929bb453ac5..91310eddcba 100644 --- a/src/app/shared/rss-feed/rss.component.scss +++ b/src/app/shared/rss-feed/rss.component.scss @@ -9,4 +9,4 @@ .margin-right { margin-right: .5em; -} \ No newline at end of file +} diff --git a/src/app/shared/rss-feed/rss.component.spec.ts b/src/app/shared/rss-feed/rss.component.spec.ts index bbfd5442b3f..cbdc2a2d0ee 100644 --- a/src/app/shared/rss-feed/rss.component.spec.ts +++ b/src/app/shared/rss-feed/rss.component.spec.ts @@ -15,6 +15,7 @@ import { PaginationServiceStub } from '../testing/pagination-service.stub'; import { createPaginatedList } from '../testing/utils.test'; import { RSSComponent } from './rss.component'; import { of as observableOf } from 'rxjs'; +import { SearchConfigurationServiceStub } from '../testing/search-configuration-service.stub'; @@ -61,11 +62,11 @@ describe('RssComponent', () => { currentPage: 1 }), sort: new SortOptions('dc.title', SortDirection.ASC), - scope: mockCollection.id })); groupDataService = jasmine.createSpyObj('groupsDataService', { findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), - getGroupRegistryRouterLink: '' + getGroupRegistryRouterLink: '', + getUUIDFromString: '', }); paginationService = new PaginationServiceStub(); const searchConfigService = { @@ -76,7 +77,7 @@ describe('RssComponent', () => { { provide: GroupDataService, useValue: groupDataService }, { provide: LinkHeadService, useValue: linkHeadService }, { provide: ConfigurationDataService, useValue: configurationDataService }, - { provide: SearchConfigurationService, useValue: searchConfigService}, + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, { provide: PaginationService, useValue: paginationService } ], declarations: [RSSComponent] diff --git a/src/app/shared/testing/search-configuration-service.stub.ts b/src/app/shared/testing/search-configuration-service.stub.ts index 80744ba59a6..78b358f0d47 100644 --- a/src/app/shared/testing/search-configuration-service.stub.ts +++ b/src/app/shared/testing/search-configuration-service.stub.ts @@ -17,6 +17,10 @@ export class SearchConfigurationServiceStub { return observableOf('test-id'); } + getCurrentQuery(a) { + return observableOf(a); + } + getCurrentConfiguration(a) { return observableOf(a); } From b5943b48b47009a7f771db99530d57d5be2fd1fc Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 25 Feb 2022 12:14:16 -0500 Subject: [PATCH 0371/2129] w2p-86403 fix opensearch is disabled, router issues and links --- src/app/core/services/link-head.service.ts | 3 ++ src/app/shared/rss-feed/rss.component.ts | 32 +++++++++++++++++----- src/app/shared/shared.module.ts | 4 +++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/app/core/services/link-head.service.ts b/src/app/core/services/link-head.service.ts index 12c3ff197d8..af5dddec8d6 100644 --- a/src/app/core/services/link-head.service.ts +++ b/src/app/core/services/link-head.service.ts @@ -1,6 +1,9 @@ import { Injectable, RendererFactory2, ViewEncapsulation, Inject } from '@angular/core'; import { DOCUMENT } from '@angular/common'; +/** + * LinkHead Service injects tag into the head element during runtime. + */ @Injectable() export class LinkHeadService { constructor( diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 036148b368e..11286e19e39 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -14,10 +14,11 @@ import { environment } from '../../../../src/environments/environment'; import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; import { SortOptions } from '../../core/cache/models/sort-options.model'; import { PaginationService } from '../../core/pagination/pagination.service'; +import { Router } from '@angular/router'; /** - * The default pagination controls component. + * The Rss feed button componenet. */ @Component({ exportAs: 'rssComponent', @@ -41,6 +42,7 @@ export class RSSComponent implements OnInit, OnDestroy { private linkHeadService: LinkHeadService, private configurationService: ConfigurationDataService, private searchConfigurationService: SearchConfigurationService, + private router: Router, protected paginationService: PaginationService) { } ngOnDestroy(): void { @@ -53,22 +55,22 @@ export class RSSComponent implements OnInit, OnDestroy { this.configurationService.findByPropertyName('websvc.opensearch.enable').pipe( getFirstCompletedRemoteData(), ).subscribe((result) => { - const enabled = Boolean(result.payload.values[0]); + const enabled = (result.payload.values[0] === 'true'); this.isEnabled$.next(enabled); }); this.searchConfigurationService.getCurrentQuery('').subscribe((query) => { this.sortOption$ = this.paginationService.getCurrentSort(this.searchConfigurationService.paginationID, null, true); this.sortOption$.subscribe((sort) => { - this.uuid = this.groupDataService.getUUIDFromString(window.location.href); + this.uuid = this.groupDataService.getUUIDFromString(this.router.url); const route = environment.rest.baseUrl + this.formulateRoute(this.uuid, sort, query); - + this.addLinks(route); this.linkHeadService.addTag({ - href: route, + href: environment.rest.baseUrl + '/opensearch/service', type: 'application/atom+xml', - rel: 'alternate', - title: 'Sitewide Atom feed' + rel: 'search', + title: 'Dspace' }); this.route$ = new BehaviorSubject(route); }); @@ -91,4 +93,20 @@ export class RSSComponent implements OnInit, OnDestroy { route = '/opensearch/' + route; return route; } + + addLinks(route: string): void { + this.linkHeadService.addTag({ + href: route, + type: 'application/atom+xml', + rel: 'alternate', + title: 'Sitewide Atom feed' + }); + route = route.replace('format=atom', 'format=rss'); + this.linkHeadService.addTag({ + href: route, + type: 'application/rss+xml', + rel: 'alternate', + title: 'Sitewide RSS feed' + }); + } } diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index c70aff61920..c6cc3d2bd98 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -174,6 +174,10 @@ import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component'; import { RSSComponent } from './rss-feed/rss.component'; +import { SearchObjects } from './search/models/search-objects.model'; +import { FacetConfigResponse } from './search/models/facet-config-response.model'; +import { SearchResult } from './search/models/search-result.model'; +import { FacetValues } from './search/models/facet-values.model'; const MODULES = [ CommonModule, From efb76ea88328df3d03706ad3c5f0411dcf7077a9 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 25 Feb 2022 12:35:17 -0500 Subject: [PATCH 0372/2129] Fix tests now that router is apart of the rss component --- .../edit-relationship-list.component.spec.ts | 3 +++ src/app/shared/rss-feed/rss.component.spec.ts | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts index f9e889bba59..2403d8f4430 100644 --- a/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts +++ b/src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts @@ -29,6 +29,8 @@ import { LinkHeadService } from '../../../../core/services/link-head.service'; import { SearchConfigurationService } from '../../../../core/shared/search/search-configuration.service'; import { SearchConfigurationServiceStub } from '../../../../shared/testing/search-configuration-service.stub'; import { ConfigurationProperty } from '../../../../core/shared/configuration-property.model'; +import { Router } from '@angular/router'; +import { RouterMock } from '../../../../shared/mocks/router.mock'; let comp: EditRelationshipListComponent; let fixture: ComponentFixture; @@ -211,6 +213,7 @@ describe('EditRelationshipListComponent', () => { { provide: HostWindowService, useValue: hostWindowService }, { provide: RelationshipTypeService, useValue: relationshipTypeService }, { provide: GroupDataService, useValue: groupDataService }, + { provide: Router, useValue: new RouterMock() }, { provide: LinkHeadService, useValue: linkHeadService }, { provide: ConfigurationDataService, useValue: configurationDataService }, { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, diff --git a/src/app/shared/rss-feed/rss.component.spec.ts b/src/app/shared/rss-feed/rss.component.spec.ts index cbdc2a2d0ee..b304abda833 100644 --- a/src/app/shared/rss-feed/rss.component.spec.ts +++ b/src/app/shared/rss-feed/rss.component.spec.ts @@ -10,12 +10,14 @@ import { ConfigurationProperty } from '../../core/shared/configuration-property. import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; -import { PaginatedSearchOptions } from '../search/paginated-search-options.model'; import { PaginationServiceStub } from '../testing/pagination-service.stub'; import { createPaginatedList } from '../testing/utils.test'; import { RSSComponent } from './rss.component'; import { of as observableOf } from 'rxjs'; import { SearchConfigurationServiceStub } from '../testing/search-configuration-service.stub'; +import { PaginatedSearchOptions } from '../search/models/paginated-search-options.model'; +import { Router } from '@angular/router'; +import { RouterMock } from '../mocks/router.mock'; @@ -78,7 +80,8 @@ describe('RssComponent', () => { { provide: LinkHeadService, useValue: linkHeadService }, { provide: ConfigurationDataService, useValue: configurationDataService }, { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, - { provide: PaginationService, useValue: paginationService } + { provide: PaginationService, useValue: paginationService }, + { provide: Router, useValue: new RouterMock() } ], declarations: [RSSComponent] }).compileComponents(); From ffb34da3e74ce1354f3a29559adf36b856947344 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 25 Feb 2022 14:56:36 -0500 Subject: [PATCH 0373/2129] Create link head spec file --- .../core/services/link-head.service.spec.ts | 45 +++++++++++++++++++ src/app/core/services/link-head.service.ts | 17 +++++-- 2 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 src/app/core/services/link-head.service.spec.ts diff --git a/src/app/core/services/link-head.service.spec.ts b/src/app/core/services/link-head.service.spec.ts new file mode 100644 index 00000000000..017fe6af03d --- /dev/null +++ b/src/app/core/services/link-head.service.spec.ts @@ -0,0 +1,45 @@ +import { DOCUMENT } from '@angular/common'; +import { Renderer2, RendererFactory2 } from '@angular/core'; +import { TestBed, waitForAsync } from '@angular/core/testing'; +import { MockProvider } from 'ng-mocks'; +import { LinkHeadService } from './link-head.service'; + +describe('LinkHeadService', () => { + + let service: LinkHeadService; + + const renderer2: Renderer2 = { + createRenderer: jasmine.createSpy('createRenderer'), + createElement: jasmine.createSpy('createElement'), + setAttribute: jasmine.createSpy('setAttribute'), + appendChild: jasmine.createSpy('appendChild') + } as unknown as Renderer2; + + beforeEach(waitForAsync(() => { + return TestBed.configureTestingModule({ + providers: [ + MockProvider(RendererFactory2, { + createRenderer: () => renderer2 + }), + { provide: Document, useExisting: DOCUMENT }, + ] + }); + })); + + beforeEach(() => { + service = new LinkHeadService(TestBed.inject(RendererFactory2), TestBed.inject(DOCUMENT)); + }); + + describe('link', () => { + it('should create a link tag', () => { + const link = service.addTag({ + href: 'test', + type: 'application/atom+xml', + rel: 'alternate', + title: 'Sitewide Atom feed' + }); + expect(link).not.toBeUndefined(); + }); + }); + +}); diff --git a/src/app/core/services/link-head.service.ts b/src/app/core/services/link-head.service.ts index af5dddec8d6..39552a44d36 100644 --- a/src/app/core/services/link-head.service.ts +++ b/src/app/core/services/link-head.service.ts @@ -12,7 +12,13 @@ export class LinkHeadService { ) { } - addTag(tag: LinkDefinition, forceCreation?: boolean) { + + /** + * Method to create a Link tag in the HEAD of the html. + * @param tag LinkDefition is the paramaters to define a link tag. + * @returns Link tag that was created + */ + addTag(tag: LinkDefinition) { try { const renderer = this.rendererFactory.createRenderer(this.document, { @@ -23,7 +29,8 @@ export class LinkHeadService { }); const link = renderer.createElement('link'); - + console.log(tag); + console.log(link); const head = this.document.head; if (head === null) { @@ -35,12 +42,16 @@ export class LinkHeadService { }); renderer.appendChild(head, link); - + return renderer; } catch (e) { console.error('Error within linkService : ', e); } } + /** + * Removes a link tag in header based on the given attrSelector. + * @param attrSelector The attr assigned to a link tag which will be used to determine what link to remove. + */ removeTag(attrSelector: string) { if (attrSelector) { try { From 2b9383d2d59c47d6f90a2f5a43fdabd43d351d14 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Mon, 18 Apr 2022 12:33:29 -0400 Subject: [PATCH 0374/2129] remove unused import from rebase --- src/app/shared/shared.module.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index c6cc3d2bd98..c70aff61920 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -174,10 +174,6 @@ import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component'; import { RSSComponent } from './rss-feed/rss.component'; -import { SearchObjects } from './search/models/search-objects.model'; -import { FacetConfigResponse } from './search/models/facet-config-response.model'; -import { SearchResult } from './search/models/search-result.model'; -import { FacetValues } from './search/models/facet-values.model'; const MODULES = [ CommonModule, From 0bf0e1f2742aa253d4a442a83eebb64ea680902a Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Mon, 18 Apr 2022 13:30:35 -0400 Subject: [PATCH 0375/2129] add providers to browseby --- .../browse-by/browse-by.component.spec.ts | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/app/shared/browse-by/browse-by.component.spec.ts b/src/app/shared/browse-by/browse-by.component.spec.ts index d71d100ca55..8bda44b11c8 100644 --- a/src/app/shared/browse-by/browse-by.component.spec.ts +++ b/src/app/shared/browse-by/browse-by.component.spec.ts @@ -38,6 +38,13 @@ import { HostWindowService } from '../host-window.service'; import { RouteService } from '../../core/services/route.service'; import { routeServiceStub } from '../testing/route-service.stub'; import SpyObj = jasmine.SpyObj; +import { GroupDataService } from '../../core/eperson/group-data.service'; +import { createPaginatedList } from '../testing/utils.test'; +import { LinkHeadService } from '../../core/services/link-head.service'; +import { ConfigurationDataService } from '../../core/data/configuration-data.service'; +import { ConfigurationProperty } from '../../core/shared/configuration-property.model'; +import { SearchConfigurationServiceStub } from '../testing/search-configuration-service.stub'; +import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; @listableObjectComponent(BrowseEntry, ViewMode.ListElement, DEFAULT_CONTEXT, 'custom') @Component({ @@ -73,6 +80,25 @@ describe('BrowseByComponent', () => { ]; const mockItemsRD$ = createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), mockItems)); + const groupDataService = jasmine.createSpyObj('groupsDataService', { + findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])), + getGroupRegistryRouterLink: '', + getUUIDFromString: '', + }); + + const linkHeadService = jasmine.createSpyObj('linkHeadService', { + addTag: '' + }); + + const configurationDataService = jasmine.createSpyObj('configurationDataService', { + findByPropertyName: createSuccessfulRemoteDataObject$(Object.assign(new ConfigurationProperty(), { + name: 'test', + values: [ + 'org.dspace.ctask.general.ProfileFormats = test' + ] + })) + }); + const paginationConfig = Object.assign(new PaginationComponentOptions(), { id: 'test-pagination', currentPage: 1, @@ -103,6 +129,10 @@ describe('BrowseByComponent', () => { ], declarations: [], providers: [ + { provide: SearchConfigurationService, useValue: new SearchConfigurationServiceStub() }, + { provide: ConfigurationDataService, useValue: configurationDataService }, + { provide: LinkHeadService, useValue: linkHeadService }, + { provide: GroupDataService, useValue: groupDataService }, { provide: PaginationService, useValue: paginationService }, { provide: MockThemedBrowseEntryListElementComponent }, { provide: ThemeService, useValue: themeService }, From be8a8f5f6bf9359eecc8034b22c522fe9ac1389f Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Wed, 27 Apr 2022 16:13:01 -0400 Subject: [PATCH 0376/2129] Add typedocs and websvc.opensearch.svccontext --- src/app/core/services/link-head.service.ts | 2 - src/app/shared/rss-feed/rss.component.spec.ts | 6 +-- src/app/shared/rss-feed/rss.component.ts | 53 +++++++++++++------ src/app/shared/shared.module.ts | 1 + src/environments/environment.dev.ts | 17 ------ src/environments/environment.prod.ts | 17 ------ 6 files changed, 41 insertions(+), 55 deletions(-) delete mode 100644 src/environments/environment.dev.ts delete mode 100644 src/environments/environment.prod.ts diff --git a/src/app/core/services/link-head.service.ts b/src/app/core/services/link-head.service.ts index 39552a44d36..d608618ca4d 100644 --- a/src/app/core/services/link-head.service.ts +++ b/src/app/core/services/link-head.service.ts @@ -29,8 +29,6 @@ export class LinkHeadService { }); const link = renderer.createElement('link'); - console.log(tag); - console.log(link); const head = this.document.head; if (head === null) { diff --git a/src/app/shared/rss-feed/rss.component.spec.ts b/src/app/shared/rss-feed/rss.component.spec.ts index b304abda833..fc19c65e607 100644 --- a/src/app/shared/rss-feed/rss.component.spec.ts +++ b/src/app/shared/rss-feed/rss.component.spec.ts @@ -96,17 +96,17 @@ describe('RssComponent', () => { }); it('should formulate the correct url given params in url', () => { - const route = comp.formulateRoute(uuid, options, query); + const route = comp.formulateRoute(uuid, 'opensearch', options, query); expect(route).toBe('/opensearch/search?format=atom&scope=2cfcf65e-0a51-4bcb-8592-b8db7b064790&sort=dc.title&sort_direction=DESC&query=test'); }); it('should skip uuid if its null', () => { - const route = comp.formulateRoute(null, options, query); + const route = comp.formulateRoute(null, 'opensearch', options, query); expect(route).toBe('/opensearch/search?format=atom&sort=dc.title&sort_direction=DESC&query=test'); }); it('should default to query * if none provided', () => { - const route = comp.formulateRoute(null, options, null); + const route = comp.formulateRoute(null, 'opensearch', options, null); expect(route).toBe('/opensearch/search?format=atom&sort=dc.title&sort_direction=DESC&query=*'); }); }); diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 11286e19e39..456e6279419 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -45,10 +45,17 @@ export class RSSComponent implements OnInit, OnDestroy { private router: Router, protected paginationService: PaginationService) { } + /** + * Removes the linktag created when the component gets removed from the page. + */ ngOnDestroy(): void { this.linkHeadService.removeTag("rel='alternate'"); } + + /** + * Generates the link tags and the url to opensearch when the component is loaded. + */ ngOnInit(): void { this.configuration$ = this.searchConfigurationService.getCurrentConfiguration('default'); @@ -58,26 +65,36 @@ export class RSSComponent implements OnInit, OnDestroy { const enabled = (result.payload.values[0] === 'true'); this.isEnabled$.next(enabled); }); - - this.searchConfigurationService.getCurrentQuery('').subscribe((query) => { - this.sortOption$ = this.paginationService.getCurrentSort(this.searchConfigurationService.paginationID, null, true); - this.sortOption$.subscribe((sort) => { - this.uuid = this.groupDataService.getUUIDFromString(this.router.url); - - const route = environment.rest.baseUrl + this.formulateRoute(this.uuid, sort, query); - this.addLinks(route); - this.linkHeadService.addTag({ - href: environment.rest.baseUrl + '/opensearch/service', - type: 'application/atom+xml', - rel: 'search', - title: 'Dspace' + this.configurationService.findByPropertyName('websvc.opensearch.svccontext').pipe( + getFirstCompletedRemoteData(), + ).subscribe((url) => { + this.searchConfigurationService.getCurrentQuery('').subscribe((query) => { + this.sortOption$ = this.paginationService.getCurrentSort(this.searchConfigurationService.paginationID, null, true); + this.sortOption$.subscribe((sort) => { + this.uuid = this.groupDataService.getUUIDFromString(this.router.url); + const route = environment.rest.baseUrl + this.formulateRoute(this.uuid, url.payload.values[0], sort, query); + this.addLinks(route); + this.linkHeadService.addTag({ + href: environment.rest.baseUrl + '/' + url.payload.values[0] + '/service', + type: 'application/atom+xml', + rel: 'search', + title: 'Dspace' + }); + this.route$ = new BehaviorSubject(route); }); - this.route$ = new BehaviorSubject(route); }); }); } - formulateRoute(uuid: string, sort: SortOptions, query: string): string { + /** + * Function created a route given the different params available to opensearch + * @param uuid The uuid if a scope is present + * @param opensearch openSearch uri + * @param sort The sort options for the opensearch request + * @param query The query string that was provided in the search + * @returns The combine URL to opensearch + */ + formulateRoute(uuid: string, opensearch: string, sort: SortOptions, query: string): string { let route = 'search?format=atom'; if (uuid) { route += `&scope=${uuid}`; @@ -90,10 +107,14 @@ export class RSSComponent implements OnInit, OnDestroy { } else { route += `&query=*`; } - route = '/opensearch/' + route; + route = '/' + opensearch +'/' + route; return route; } + /** + * Creates tags in the header of the page + * @param route The composed url to opensearch + */ addLinks(route: string): void { this.linkHeadService.addTag({ href: route, diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index c70aff61920..7c6fe6657a6 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -174,6 +174,7 @@ import { DsSelectComponent } from './ds-select/ds-select.component'; import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component'; import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component'; import { RSSComponent } from './rss-feed/rss.component'; +import { ExternalLinkMenuItemComponent } from './menu/menu-item/external-link-menu-item.component'; const MODULES = [ CommonModule, diff --git a/src/environments/environment.dev.ts b/src/environments/environment.dev.ts deleted file mode 100644 index 999abd32eeb..00000000000 --- a/src/environments/environment.dev.ts +++ /dev/null @@ -1,17 +0,0 @@ -export const environment = { - ui: { - ssl: false, - host: 'localhost', - port: 18080, - nameSpace: '/' - }, - rest: { - ssl: false, - host: 'localhost', - port: 8080, - nameSpace: '/server' - }, - universal: { - preboot: false - } -}; diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts deleted file mode 100644 index c31da7b791f..00000000000 --- a/src/environments/environment.prod.ts +++ /dev/null @@ -1,17 +0,0 @@ -export const environment = { - ui: { - ssl: false, - host: 'localhost', - port: 18080, - nameSpace: '/' - }, - rest: { - ssl: false, - host: 'localhost', - port: 8080, - nameSpace: '/server' - }, - universal: { - preboot: true - } -}; From 90f1fc186c12719fe5f62f2606ef6daf29d22777 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Thu, 28 Apr 2022 09:36:09 -0400 Subject: [PATCH 0377/2129] Link fixes --- src/app/shared/rss-feed/rss.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 456e6279419..d3970199951 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -89,7 +89,7 @@ export class RSSComponent implements OnInit, OnDestroy { /** * Function created a route given the different params available to opensearch * @param uuid The uuid if a scope is present - * @param opensearch openSearch uri + * @param opensearch openSearch uri * @param sort The sort options for the opensearch request * @param query The query string that was provided in the search * @returns The combine URL to opensearch @@ -107,7 +107,7 @@ export class RSSComponent implements OnInit, OnDestroy { } else { route += `&query=*`; } - route = '/' + opensearch +'/' + route; + route = '/' + opensearch + '/' + route; return route; } From 8785270363a4d54ec1bc22d8c90571b7f9ba081d Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Thu, 28 Apr 2022 15:51:21 -0400 Subject: [PATCH 0378/2129] w2p-86403 Changed to subscribe and unsubscribe on destory --- src/app/shared/rss-feed/rss.component.ts | 53 ++++++++++++++---------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index d3970199951..56ed052a9fb 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -5,7 +5,7 @@ import { OnInit, ViewEncapsulation } from '@angular/core'; -import { BehaviorSubject, Observable } from 'rxjs'; +import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { GroupDataService } from '../../core/eperson/group-data.service'; import { LinkHeadService } from '../../core/services/link-head.service'; import { ConfigurationDataService } from '../../core/data/configuration-data.service'; @@ -15,6 +15,9 @@ import { SearchConfigurationService } from '../../core/shared/search/search-conf import { SortOptions } from '../../core/cache/models/sort-options.model'; import { PaginationService } from '../../core/pagination/pagination.service'; import { Router } from '@angular/router'; +import { map, switchMap } from 'rxjs/operators'; +import { RemoteData } from '../../core/data/remote-data'; +import { PaginatedSearchOptions } from '../search/models/paginated-search-options.model'; /** @@ -32,12 +35,14 @@ export class RSSComponent implements OnInit, OnDestroy { route$: BehaviorSubject; - isEnabled$: BehaviorSubject = new BehaviorSubject(false); + isEnabled$: BehaviorSubject = new BehaviorSubject(null); uuid: string; configuration$: Observable; sortOption$: Observable; + subs: Subscription[] = []; + constructor(private groupDataService: GroupDataService, private linkHeadService: LinkHeadService, private configurationService: ConfigurationDataService, @@ -50,6 +55,9 @@ export class RSSComponent implements OnInit, OnDestroy { */ ngOnDestroy(): void { this.linkHeadService.removeTag("rel='alternate'"); + this.subs.forEach(sub => { + sub.unsubscribe(); + }); } @@ -59,31 +67,32 @@ export class RSSComponent implements OnInit, OnDestroy { ngOnInit(): void { this.configuration$ = this.searchConfigurationService.getCurrentConfiguration('default'); - this.configurationService.findByPropertyName('websvc.opensearch.enable').pipe( + this.subs.push(this.configurationService.findByPropertyName('websvc.opensearch.enable').pipe( getFirstCompletedRemoteData(), ).subscribe((result) => { const enabled = (result.payload.values[0] === 'true'); this.isEnabled$.next(enabled); - }); - this.configurationService.findByPropertyName('websvc.opensearch.svccontext').pipe( + })); + this.subs.push(this.configurationService.findByPropertyName('websvc.opensearch.svccontext').pipe( getFirstCompletedRemoteData(), - ).subscribe((url) => { - this.searchConfigurationService.getCurrentQuery('').subscribe((query) => { - this.sortOption$ = this.paginationService.getCurrentSort(this.searchConfigurationService.paginationID, null, true); - this.sortOption$.subscribe((sort) => { - this.uuid = this.groupDataService.getUUIDFromString(this.router.url); - const route = environment.rest.baseUrl + this.formulateRoute(this.uuid, url.payload.values[0], sort, query); - this.addLinks(route); - this.linkHeadService.addTag({ - href: environment.rest.baseUrl + '/' + url.payload.values[0] + '/service', - type: 'application/atom+xml', - rel: 'search', - title: 'Dspace' - }); - this.route$ = new BehaviorSubject(route); - }); + map((response: RemoteData) => response.payload.values[0]), + switchMap((openSearchUri: string) => + this.searchConfigurationService.paginatedSearchOptions.pipe( + map((searchOptions: PaginatedSearchOptions) => ({ openSearchUri, searchOptions })) + ) + ), + ).subscribe(({ openSearchUri, searchOptions }) => { + this.uuid = this.groupDataService.getUUIDFromString(this.router.url); + const route = environment.rest.baseUrl + this.formulateRoute(this.uuid, openSearchUri, searchOptions.sort, searchOptions.query); + this.addLinks(route); + this.linkHeadService.addTag({ + href: environment.rest.baseUrl + '/' + openSearchUri + '/service', + type: 'application/atom+xml', + rel: 'search', + title: 'Dspace' }); - }); + this.route$ = new BehaviorSubject(route); + })); } /** @@ -99,7 +108,7 @@ export class RSSComponent implements OnInit, OnDestroy { if (uuid) { route += `&scope=${uuid}`; } - if (sort.direction && sort.field) { + if (sort && sort.direction && sort.field) { route += `&sort=${sort.field}&sort_direction=${sort.direction}`; } if (query) { From 6cd22fa004b52077ad63c02cd302c1c4d4fb1342 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Wed, 4 May 2022 15:27:10 -0400 Subject: [PATCH 0379/2129] w2p-86403 prevent from displaying on pages where rss feed doesn't make sense --- src/app/shared/rss-feed/rss.component.html | 2 +- src/app/shared/rss-feed/rss.component.ts | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/app/shared/rss-feed/rss.component.html b/src/app/shared/rss-feed/rss.component.html index 8868539b5c0..895a9c2f97d 100644 --- a/src/app/shared/rss-feed/rss.component.html +++ b/src/app/shared/rss-feed/rss.component.html @@ -1,4 +1,4 @@ - +
diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 56ed052a9fb..20fb040013c 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -120,6 +120,17 @@ export class RSSComponent implements OnInit, OnDestroy { return route; } + /** + * Check if the router url contains the specified route + * + * @param {string} route + * @returns + * @memberof MyComponent + */ + hasRoute(route: string) { + return this.router.url.includes(route); + } + /** * Creates tags in the header of the page * @param route The composed url to opensearch From eacbcfd15d803ea02dede2530934458f336a0e46 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 6 May 2022 10:15:51 -0400 Subject: [PATCH 0380/2129] Change to withNotEmptyPayload to pass through if its empty --- src/app/shared/rss-feed/rss.component.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 20fb040013c..880ed8b558b 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -9,7 +9,7 @@ import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { GroupDataService } from '../../core/eperson/group-data.service'; import { LinkHeadService } from '../../core/services/link-head.service'; import { ConfigurationDataService } from '../../core/data/configuration-data.service'; -import { getFirstCompletedRemoteData } from '../../core/shared/operators'; +import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataWithNotEmptyPayload } from '../../core/shared/operators'; import { environment } from '../../../../src/environments/environment'; import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; import { SortOptions } from '../../core/cache/models/sort-options.model'; @@ -68,14 +68,14 @@ export class RSSComponent implements OnInit, OnDestroy { this.configuration$ = this.searchConfigurationService.getCurrentConfiguration('default'); this.subs.push(this.configurationService.findByPropertyName('websvc.opensearch.enable').pipe( - getFirstCompletedRemoteData(), + getFirstSucceededRemoteDataWithNotEmptyPayload(), ).subscribe((result) => { - const enabled = (result.payload.values[0] === 'true'); + const enabled = (result.values[0] === 'true'); this.isEnabled$.next(enabled); })); this.subs.push(this.configurationService.findByPropertyName('websvc.opensearch.svccontext').pipe( - getFirstCompletedRemoteData(), - map((response: RemoteData) => response.payload.values[0]), + getFirstSucceededRemoteDataWithNotEmptyPayload(), + map((result) => result.values[0]), switchMap((openSearchUri: string) => this.searchConfigurationService.paginatedSearchOptions.pipe( map((searchOptions: PaginatedSearchOptions) => ({ openSearchUri, searchOptions })) From cb1b7ceb0a8e134fc1b277de97b83c34931b2115 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 6 May 2022 10:17:30 -0400 Subject: [PATCH 0381/2129] remove rss feed from search --- src/app/shared/rss-feed/rss.component.html | 2 +- src/app/shared/rss-feed/rss.component.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/app/shared/rss-feed/rss.component.html b/src/app/shared/rss-feed/rss.component.html index 895a9c2f97d..e86e72d15a9 100644 --- a/src/app/shared/rss-feed/rss.component.html +++ b/src/app/shared/rss-feed/rss.component.html @@ -1,4 +1,4 @@ - +
diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 880ed8b558b..1d76daabf11 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -9,14 +9,13 @@ import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { GroupDataService } from '../../core/eperson/group-data.service'; import { LinkHeadService } from '../../core/services/link-head.service'; import { ConfigurationDataService } from '../../core/data/configuration-data.service'; -import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataWithNotEmptyPayload } from '../../core/shared/operators'; +import { getFirstSucceededRemoteDataWithNotEmptyPayload } from '../../core/shared/operators'; import { environment } from '../../../../src/environments/environment'; import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; import { SortOptions } from '../../core/cache/models/sort-options.model'; import { PaginationService } from '../../core/pagination/pagination.service'; import { Router } from '@angular/router'; import { map, switchMap } from 'rxjs/operators'; -import { RemoteData } from '../../core/data/remote-data'; import { PaginatedSearchOptions } from '../search/models/paginated-search-options.model'; From 79bf27c659aff1fb798954ce826dcb949dcdbf69 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 6 May 2022 14:03:14 -0400 Subject: [PATCH 0382/2129] Revert to getFirstCompletedRemoteData but check if payload has completed --- src/app/shared/rss-feed/rss.component.ts | 25 +++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 1d76daabf11..9a101e8310f 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -9,7 +9,7 @@ import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { GroupDataService } from '../../core/eperson/group-data.service'; import { LinkHeadService } from '../../core/services/link-head.service'; import { ConfigurationDataService } from '../../core/data/configuration-data.service'; -import { getFirstSucceededRemoteDataWithNotEmptyPayload } from '../../core/shared/operators'; +import { getFirstCompletedRemoteData } from '../../core/shared/operators'; import { environment } from '../../../../src/environments/environment'; import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service'; import { SortOptions } from '../../core/cache/models/sort-options.model'; @@ -17,6 +17,7 @@ import { PaginationService } from '../../core/pagination/pagination.service'; import { Router } from '@angular/router'; import { map, switchMap } from 'rxjs/operators'; import { PaginatedSearchOptions } from '../search/models/paginated-search-options.model'; +import { RemoteData } from '../../core/data/remote-data'; /** @@ -67,20 +68,30 @@ export class RSSComponent implements OnInit, OnDestroy { this.configuration$ = this.searchConfigurationService.getCurrentConfiguration('default'); this.subs.push(this.configurationService.findByPropertyName('websvc.opensearch.enable').pipe( - getFirstSucceededRemoteDataWithNotEmptyPayload(), + getFirstCompletedRemoteData(), ).subscribe((result) => { - const enabled = (result.values[0] === 'true'); - this.isEnabled$.next(enabled); + if (result.hasSucceeded) { + const enabled = (result.payload.values[0] === 'true'); + this.isEnabled$.next(enabled); + } })); this.subs.push(this.configurationService.findByPropertyName('websvc.opensearch.svccontext').pipe( - getFirstSucceededRemoteDataWithNotEmptyPayload(), - map((result) => result.values[0]), - switchMap((openSearchUri: string) => + getFirstCompletedRemoteData(), + map((result: RemoteData) => { + if (result.hasSucceeded) { + return result.payload.values[0]; + } + return null; + }), + switchMap((openSearchUri: string) => this.searchConfigurationService.paginatedSearchOptions.pipe( map((searchOptions: PaginatedSearchOptions) => ({ openSearchUri, searchOptions })) ) ), ).subscribe(({ openSearchUri, searchOptions }) => { + if (!openSearchUri) { + return null; + } this.uuid = this.groupDataService.getUUIDFromString(this.router.url); const route = environment.rest.baseUrl + this.formulateRoute(this.uuid, openSearchUri, searchOptions.sort, searchOptions.query); this.addLinks(route); From 0791287cf9265ff9d329085f5dd9172335c75ca6 Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 6 May 2022 14:09:08 -0400 Subject: [PATCH 0383/2129] lint fixes --- src/app/core/core.module.ts | 3 --- src/app/shared/rss-feed/rss.component.ts | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/app/core/core.module.ts b/src/app/core/core.module.ts index f6cde902532..27e23268183 100644 --- a/src/app/core/core.module.ts +++ b/src/app/core/core.module.ts @@ -164,12 +164,9 @@ import { SequenceService } from './shared/sequence.service'; import { CoreState } from './core-state.model'; import { GroupDataService } from './eperson/group-data.service'; import { SubmissionAccessesModel } from './config/models/config-submission-accesses.model'; -<<<<<<< HEAD import { AccessStatusObject } from '../shared/object-list/access-status-badge/access-status.model'; import { AccessStatusDataService } from './data/access-status-data.service'; -======= import { LinkHeadService } from './services/link-head.service'; ->>>>>>> 354768d98 (w2p-85140 ds-rss component now adds a button to all search pages and community and collection, link-head service adds the rss to the head element) /** * When not in production, endpoint responses can be mocked for testing purposes diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index 9a101e8310f..b694280e3cb 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -77,13 +77,13 @@ export class RSSComponent implements OnInit, OnDestroy { })); this.subs.push(this.configurationService.findByPropertyName('websvc.opensearch.svccontext').pipe( getFirstCompletedRemoteData(), - map((result: RemoteData) => { + map((result: RemoteData) => { if (result.hasSucceeded) { return result.payload.values[0]; } return null; }), - switchMap((openSearchUri: string) => + switchMap((openSearchUri: string) => this.searchConfigurationService.paginatedSearchOptions.pipe( map((searchOptions: PaginatedSearchOptions) => ({ openSearchUri, searchOptions })) ) From 42c459a51d5ebcf2eff3423fe239968e24dfcd9c Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Thu, 12 May 2022 16:13:43 +0200 Subject: [PATCH 0384/2129] [CST-5303] added labels into i18n --- src/assets/i18n/en.json5 | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 9bdf41346dd..bb2bcf8ebc6 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2158,6 +2158,22 @@ "item.preview.dc.title": "Title:", + "item.preview.dc.type": "Type:", + + "item.preview.oaire.citation.issue" : "Issue", + + "item.preview.oaire.citation.volume" : "Volume", + + "item.preview.dc.relation.issn" : "ISSN", + + "item.preview.dc.identifier.isbn" : "ISBN", + + "item.preview.dc.identifier": "Identifier:", + + "item.preview.dc.relation.ispartof" : "Journal or Serie", + + "item.preview.dc.identifier.doi" : "DOI", + "item.preview.person.familyName": "Surname:", "item.preview.person.givenName": "Name:", @@ -3568,6 +3584,22 @@ "submission.import-external.source.arxiv": "arXiv", + "submission.import-external.source.ads": "NASA/ADS", + + "submission.import-external.source.cinii": "CiNii", + + "submission.import-external.source.crossref": "CrossRef", + + "submission.import-external.source.scielo": "SciELO", + + "submission.import-external.source.scopus": "Scopus", + + "submission.import-external.source.vufind": "VuFind", + + "submission.import-external.source.wos": "Web Of Science", + + "submission.import-external.source.epo": "European Patent Office (EPO)", + "submission.import-external.source.loading": "Loading ...", "submission.import-external.source.sherpaJournal": "SHERPA Journals", @@ -3582,10 +3614,14 @@ "submission.import-external.source.pubmed": "Pubmed", + "submission.import-external.source.pubmedeu": "Pubmed Europe", + "submission.import-external.source.lcname": "Library of Congress Names", "submission.import-external.preview.title": "Item Preview", + "submission.import-external.preview.title.Publication": "Publication Preview", + "submission.import-external.preview.subtitle": "The metadata below was imported from an external source. It will be pre-filled when you start the submission.", "submission.import-external.preview.button.import": "Start submission", @@ -3824,6 +3860,18 @@ "submission.sections.describe.relationship-lookup.selection-tab.title.arxiv": "Search Results", + "submission.sections.describe.relationship-lookup.selection-tab.title.crossref": "Search Results", + + "submission.sections.describe.relationship-lookup.selection-tab.title.epo": "Search Results", + + "submission.sections.describe.relationship-lookup.selection-tab.title.scopus": "Search Results", + + "submission.sections.describe.relationship-lookup.selection-tab.title.scielo": "Search Results", + + "submission.sections.describe.relationship-lookup.selection-tab.title.wos": "Search Results", + + "submission.sections.describe.relationship-lookup.selection-tab.title": "Search Results", + "submission.sections.describe.relationship-lookup.name-variant.notification.content": "Would you like to save \"{{ value }}\" as a name variant for this person so you and others can reuse it for future submissions? If you don\'t you can still use it for this submission.", "submission.sections.describe.relationship-lookup.name-variant.notification.confirm": "Save a new name variant", From c1f64ff1ef9a6846b9926968ccfd0d8ec2d548f5 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Thu, 12 May 2022 18:50:25 +0200 Subject: [PATCH 0385/2129] [CST-5329] Add help text to validate only checkbox --- .../metadata-import-page.component.html | 15 +++++++++++---- src/assets/i18n/en.json5 | 2 ++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html index 2c710935d51..24901cc11d3 100644 --- a/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html +++ b/src/app/admin/admin-import-metadata-page/metadata-import-page.component.html @@ -1,10 +1,17 @@

{{'admin.metadata-import.page.help' | translate}}

-

- - {{'admin.metadata-import.page.validateOnly' | translate}} -

+
+
+ + +
+ + {{'admin.metadata-import.page.validateOnly.hint' | translate}} + +
Date: Fri, 13 May 2022 13:45:49 +0200 Subject: [PATCH 0386/2129] 91272: Fixed import statements and position of expandable navbar button --- .../themed-expandable-navbar-section.component.ts | 4 ++-- src/app/navbar/navbar.component.html | 4 ++-- .../expandable-navbar-section.component.ts | 4 ++-- src/themes/dspace/app/navbar/navbar.component.html | 4 ++-- src/themes/dspace/styles/_global-styles.scss | 3 +-- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/app/navbar/expandable-navbar-section/themed-expandable-navbar-section.component.ts b/src/app/navbar/expandable-navbar-section/themed-expandable-navbar-section.component.ts index 744eeb5a027..e33dca41049 100644 --- a/src/app/navbar/expandable-navbar-section/themed-expandable-navbar-section.component.ts +++ b/src/app/navbar/expandable-navbar-section/themed-expandable-navbar-section.component.ts @@ -2,13 +2,13 @@ import { Component } from '@angular/core'; import { ThemedComponent } from '../../shared/theme-support/themed.component'; import { ExpandableNavbarSectionComponent } from './expandable-navbar-section.component'; import { rendersSectionForMenu } from '../../shared/menu/menu-section.decorator'; -import { MenuID } from '../../shared/menu/initial-menus-state'; +import { MenuID } from '../../shared/menu/menu-id.model'; /** * Themed wrapper for ExpandableNavbarSectionComponent */ @Component({ - /* tslint:disable:component-selector */ + /* eslint-disable @angular-eslint/component-selector */ selector: 'li[ds-themed-expandable-navbar-section]', styleUrls: [], templateUrl: '../../shared/theme-support/themed.component.html', diff --git a/src/app/navbar/navbar.component.html b/src/app/navbar/navbar.component.html index 63f308fb32a..b41f2ea7067 100644 --- a/src/app/navbar/navbar.component.html +++ b/src/app/navbar/navbar.component.html @@ -4,7 +4,7 @@
-
- \ No newline at end of file + diff --git a/src/themes/custom/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts b/src/themes/custom/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts index 283b9ca6f65..f7efd1fdcab 100644 --- a/src/themes/custom/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts +++ b/src/themes/custom/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts @@ -4,13 +4,13 @@ import { } from '../../../../../app/navbar/expandable-navbar-section/expandable-navbar-section.component'; import { slide } from '../../../../../app/shared/animations/slide'; import { rendersSectionForMenu } from '../../../../../app/shared/menu/menu-section.decorator'; -import { MenuID } from '../../../../../app/shared/menu/initial-menus-state'; +import { MenuID } from '../../../../../app/shared/menu/menu-id.model'; /** * Represents an expandable section in the navbar */ @Component({ - /* tslint:disable:component-selector */ + /* eslint-disable @angular-eslint/component-selector */ selector: 'li[ds-expandable-navbar-section]', // templateUrl: './expandable-navbar-section.component.html', templateUrl: '../../../../../app/navbar/expandable-navbar-section/expandable-navbar-section.component.html', diff --git a/src/themes/dspace/app/navbar/navbar.component.html b/src/themes/dspace/app/navbar/navbar.component.html index 218fc368ba8..6b71728494f 100644 --- a/src/themes/dspace/app/navbar/navbar.component.html +++ b/src/themes/dspace/app/navbar/navbar.component.html @@ -6,7 +6,7 @@
-
- \ No newline at end of file + diff --git a/src/themes/dspace/styles/_global-styles.scss b/src/themes/dspace/styles/_global-styles.scss index 8682e3dcdf2..3271f15bf22 100644 --- a/src/themes/dspace/styles/_global-styles.scss +++ b/src/themes/dspace/styles/_global-styles.scss @@ -23,8 +23,7 @@ } header { - li > .navbar-section, - li > .expandable-navbar-section { + .navbar-navigation > li { display: flex; flex-direction: column; justify-content: center; From e197e496b51aad5d05e4e6684a84cf435a1e15d4 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 13 May 2022 17:19:42 +0200 Subject: [PATCH 0387/2129] 91272: Fixed accessibility violation --- .../admin-sidebar-section/admin-sidebar-section.component.ts | 2 ++ .../expandable-admin-sidebar-section.component.ts | 2 ++ .../expandable-navbar-section.component.ts | 3 +-- src/app/navbar/navbar-section/navbar-section.component.ts | 2 ++ .../expandable-navbar-section.component.ts | 3 +-- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.ts b/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.ts index 47f693cb994..422431d2c5d 100644 --- a/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.ts +++ b/src/app/admin/admin-sidebar/admin-sidebar-section/admin-sidebar-section.component.ts @@ -14,6 +14,8 @@ import { Router } from '@angular/router'; @Component({ /* eslint-disable @angular-eslint/component-selector */ selector: 'li[ds-admin-sidebar-section]', + // To theme this element remove the surrounding li[] in this component but leave it in the new + // ThemedAdminSidebarSectionComponent templateUrl: './admin-sidebar-section.component.html', styleUrls: ['./admin-sidebar-section.component.scss'], diff --git a/src/app/admin/admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component.ts b/src/app/admin/admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component.ts index 7cd20b15d27..28cadcac5fa 100644 --- a/src/app/admin/admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component.ts +++ b/src/app/admin/admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component.ts @@ -17,6 +17,8 @@ import { Router } from '@angular/router'; @Component({ /* eslint-disable @angular-eslint/component-selector */ selector: 'li[ds-expandable-admin-sidebar-section]', + // To theme this element remove the surrounding li[] in this component but leave it in the new + // ThemedExpandableAdminSidebarSectionComponent templateUrl: './expandable-admin-sidebar-section.component.html', styleUrls: ['./expandable-admin-sidebar-section.component.scss'], animations: [rotate, slide, bgColor] diff --git a/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts b/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts index a6d3a52cd22..5bc69bcbb4e 100644 --- a/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts +++ b/src/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts @@ -11,8 +11,7 @@ import { MenuID } from '../../shared/menu/menu-id.model'; * Represents an expandable section in the navbar */ @Component({ - /* eslint-disable @angular-eslint/component-selector */ - selector: 'li[ds-expandable-navbar-section]', + selector: 'ds-expandable-navbar-section', templateUrl: './expandable-navbar-section.component.html', styleUrls: ['./expandable-navbar-section.component.scss'], animations: [slide] diff --git a/src/app/navbar/navbar-section/navbar-section.component.ts b/src/app/navbar/navbar-section/navbar-section.component.ts index 9f75a96f6e7..20d52995843 100644 --- a/src/app/navbar/navbar-section/navbar-section.component.ts +++ b/src/app/navbar/navbar-section/navbar-section.component.ts @@ -10,6 +10,8 @@ import { MenuID } from '../../shared/menu/menu-id.model'; @Component({ /* eslint-disable @angular-eslint/component-selector */ selector: 'li[ds-navbar-section]', + // To theme this element remove the surrounding li[] in this component but leave it in the new + // ThemedNavbarSectionComponent templateUrl: './navbar-section.component.html', styleUrls: ['./navbar-section.component.scss'] }) diff --git a/src/themes/custom/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts b/src/themes/custom/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts index f7efd1fdcab..3e11271bf0b 100644 --- a/src/themes/custom/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts +++ b/src/themes/custom/app/navbar/expandable-navbar-section/expandable-navbar-section.component.ts @@ -10,8 +10,7 @@ import { MenuID } from '../../../../../app/shared/menu/menu-id.model'; * Represents an expandable section in the navbar */ @Component({ - /* eslint-disable @angular-eslint/component-selector */ - selector: 'li[ds-expandable-navbar-section]', + selector: 'ds-expandable-navbar-section', // templateUrl: './expandable-navbar-section.component.html', templateUrl: '../../../../../app/navbar/expandable-navbar-section/expandable-navbar-section.component.html', // styleUrls: ['./expandable-navbar-section.component.scss'], From 460efa42c732dc80979e8733793c439282141c1e Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 13 May 2022 19:33:40 +0200 Subject: [PATCH 0388/2129] 91272: Fix merge request --- src/app/admin/admin-sidebar/admin-sidebar.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/admin/admin-sidebar/admin-sidebar.component.ts b/src/app/admin/admin-sidebar/admin-sidebar.component.ts index 5febf93deba..d4071b91edf 100644 --- a/src/app/admin/admin-sidebar/admin-sidebar.component.ts +++ b/src/app/admin/admin-sidebar/admin-sidebar.component.ts @@ -41,7 +41,6 @@ import { FeatureID } from '../../core/data/feature-authorization/feature-id'; import { MenuID } from '../../shared/menu/menu-id.model'; import { MenuItemType } from '../../shared/menu/menu-item-type.model'; import { ActivatedRoute } from '@angular/router'; -import { Router, ActivatedRoute } from '@angular/router'; import { ThemeService } from '../../shared/theme-support/theme.service'; /** From 3a6112532edc27b438f7c995e64c2ba05626e6db Mon Sep 17 00:00:00 2001 From: Nathan Buckingham Date: Fri, 13 May 2022 13:32:33 -0400 Subject: [PATCH 0389/2129] for rss sort id should be date.accessioned so defaulted to that when its the case --- src/app/shared/rss-feed/rss.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/rss-feed/rss.component.ts b/src/app/shared/rss-feed/rss.component.ts index b694280e3cb..3fdb859bdce 100644 --- a/src/app/shared/rss-feed/rss.component.ts +++ b/src/app/shared/rss-feed/rss.component.ts @@ -118,7 +118,7 @@ export class RSSComponent implements OnInit, OnDestroy { if (uuid) { route += `&scope=${uuid}`; } - if (sort && sort.direction && sort.field) { + if (sort && sort.direction && sort.field && sort.field !== 'id') { route += `&sort=${sort.field}&sort_direction=${sort.direction}`; } if (query) { From 743513cf848a7db3c5ec1fc97817a07fd6cdc134 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 13 May 2022 20:35:08 +0200 Subject: [PATCH 0390/2129] 89676: Added empty SearchResultsComponent files --- .../shared/search/search-results/search-results.component.html | 0 .../shared/search/search-results/search-results.component.scss | 0 .../app/shared/search/search-results/search-results.component.ts | 1 + 3 files changed, 1 insertion(+) create mode 100644 src/themes/custom/app/shared/search/search-results/search-results.component.html create mode 100644 src/themes/custom/app/shared/search/search-results/search-results.component.scss diff --git a/src/themes/custom/app/shared/search/search-results/search-results.component.html b/src/themes/custom/app/shared/search/search-results/search-results.component.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/themes/custom/app/shared/search/search-results/search-results.component.scss b/src/themes/custom/app/shared/search/search-results/search-results.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/themes/custom/app/shared/search/search-results/search-results.component.ts b/src/themes/custom/app/shared/search/search-results/search-results.component.ts index bdfeea15a58..5084d4d405e 100644 --- a/src/themes/custom/app/shared/search/search-results/search-results.component.ts +++ b/src/themes/custom/app/shared/search/search-results/search-results.component.ts @@ -6,6 +6,7 @@ import { fadeIn, fadeInOut } from '../../../../../../app/shared/animations/fade' selector: 'ds-search-results', // templateUrl: './search-results.component.html', templateUrl: '../../../../../../app/shared/search/search-results/search-results.component.html', + // styleUrls: ['./search-results.component.scss'], animations: [ fadeIn, fadeInOut From 913d128e165e5ef3f3784a2e25dd0bccab26503d Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 13 May 2022 16:57:28 -0500 Subject: [PATCH 0391/2129] Fix accessibility issue: link has no discernible text --- src/app/shared/rss-feed/rss.component.html | 2 +- src/assets/i18n/en.json5 | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/app/shared/rss-feed/rss.component.html b/src/app/shared/rss-feed/rss.component.html index e86e72d15a9..91140c50c5a 100644 --- a/src/app/shared/rss-feed/rss.component.html +++ b/src/app/shared/rss-feed/rss.component.html @@ -1,5 +1,5 @@
- +
diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 110b66c1768..520d38cf69c 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1401,6 +1401,9 @@ "error.validation.groupExists": "This group already exists", + "feed.description": "Syndication feed", + + "file-section.error.header": "Error obtaining files for this item", From 4c5c99d05d3a5ba0b5abd2add953f14082ebea55 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 16 May 2022 16:44:35 +0200 Subject: [PATCH 0392/2129] [CST-5535] Add missing i18n label --- src/assets/i18n/en.json5 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 44d2d073056..c129187023d 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2503,13 +2503,15 @@ "menu.section.icon.find": "Find menu section", + "menu.section.icon.health": "Health check menu section", + "menu.section.icon.import": "Import menu section", "menu.section.icon.new": "New menu section", "menu.section.icon.pin": "Pin sidebar", - "menu.section.icon.processes": "Processes menu section", + "menu.section.icon.processes": "Processes Health", "menu.section.icon.registries": "Registries menu section", From 0de3c2ed48d6f5861ae008eba84757888e7860fe Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 16 May 2022 16:45:00 +0200 Subject: [PATCH 0393/2129] [CST-5535] Replace icons --- .../health-info-component.component.html | 6 +++--- .../health-component/health-component.component.html | 4 ++-- .../health-page/health-panel/health-panel.component.html | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.html b/src/app/health-page/health-info/health-info-component/health-info-component.component.html index 55c1b3372f9..8ce7595980b 100644 --- a/src/app/health-page/health-info/health-info-component/health-info-component.component.html +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.html @@ -1,13 +1,13 @@
-
+
- - + +
diff --git a/src/app/health-page/health-panel/health-component/health-component.component.html b/src/app/health-page/health-panel/health-component/health-component.component.html index 81719177674..4569d06dad3 100644 --- a/src/app/health-page/health-panel/health-component/health-component.component.html +++ b/src/app/health-page/health-panel/health-component/health-component.component.html @@ -6,8 +6,8 @@ {{ entry.key | titlecase }}
- - + +
diff --git a/src/app/health-page/health-panel/health-panel.component.html b/src/app/health-page/health-panel/health-panel.component.html index d582fb77f32..eebcfe55ec3 100644 --- a/src/app/health-page/health-panel/health-panel.component.html +++ b/src/app/health-page/health-panel/health-panel.component.html @@ -1,14 +1,14 @@

{{'health-page.status' | translate}} :

-
+
- - + +
From 80ff8a517ce95c16ab21b376d2e4b664dbe4b5d4 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 16 May 2022 16:46:33 +0200 Subject: [PATCH 0394/2129] [CST-5535] Rename health-data.service --- src/app/health-page/health-page.component.spec.ts | 4 ++-- src/app/health-page/health-page.component.ts | 4 ++-- .../health-page/{health-data.service.ts => health.service.ts} | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename src/app/health-page/{health-data.service.ts => health.service.ts} (97%) diff --git a/src/app/health-page/health-page.component.spec.ts b/src/app/health-page/health-page.component.spec.ts index 205af8036a1..f3847ab0926 100644 --- a/src/app/health-page/health-page.component.spec.ts +++ b/src/app/health-page/health-page.component.spec.ts @@ -7,7 +7,7 @@ import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { HealthPageComponent } from './health-page.component'; -import { HealthDataService } from './health-data.service'; +import { HealthService } from './health.service'; import { HealthInfoResponseObj, HealthResponseObj } from '../shared/mocks/health-endpoint.mocks'; import { RawRestResponse } from '../core/dspace-rest/raw-rest-response.model'; import { TranslateLoaderMock } from '../shared/mocks/translate-loader.mock'; @@ -47,7 +47,7 @@ describe('HealthPageComponent', () => { ], declarations: [ HealthPageComponent ], providers: [ - { provide: HealthDataService, useValue: healthService } + { provide: HealthService, useValue: healthService } ] }) .compileComponents(); diff --git a/src/app/health-page/health-page.component.ts b/src/app/health-page/health-page.component.ts index e4f4be7a03e..eb07b63addf 100644 --- a/src/app/health-page/health-page.component.ts +++ b/src/app/health-page/health-page.component.ts @@ -3,7 +3,7 @@ import { Component, OnInit } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { take } from 'rxjs/operators'; -import { HealthDataService } from './health-data.service'; +import { HealthService } from './health.service'; import { HealthInfoResponse, HealthResponse } from './models/health-component.model'; @Component({ @@ -23,7 +23,7 @@ export class HealthPageComponent implements OnInit { */ healthResponse: BehaviorSubject = new BehaviorSubject(null); - constructor(private healthDataService: HealthDataService) { + constructor(private healthDataService: HealthService) { } /** diff --git a/src/app/health-page/health-data.service.ts b/src/app/health-page/health.service.ts similarity index 97% rename from src/app/health-page/health-data.service.ts rename to src/app/health-page/health.service.ts index bd905006aa9..7c238769a1e 100644 --- a/src/app/health-page/health-data.service.ts +++ b/src/app/health-page/health.service.ts @@ -8,7 +8,7 @@ import { HALEndpointService } from '../core/shared/hal-endpoint.service'; @Injectable({ providedIn: 'root' }) -export class HealthDataService { +export class HealthService { constructor(protected halService: HALEndpointService, protected restService: DspaceRestService) { } From 4f7e37d348dfeccca1cc7e1f8b7efeb526b11207 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 16 May 2022 18:17:35 +0200 Subject: [PATCH 0395/2129] [CST-5535] Use accordion for health status components --- .../health-info-component.component.html | 38 ++++++++++++++--- .../health-info-component.component.spec.ts | 4 +- .../health-info/health-info.component.html | 30 ++++++++++++- .../health-info/health-info.component.spec.ts | 8 +++- .../health-info/health-info.component.ts | 12 +++++- .../health-component.component.html | 3 +- .../health-panel/health-panel.component.html | 42 ++++++++++--------- .../health-panel.component.spec.ts | 9 ++-- .../health-panel/health-panel.component.ts | 11 +++-- src/app/shared/mocks/health-endpoint.mocks.ts | 24 ++++++++++- 10 files changed, 139 insertions(+), 42 deletions(-) diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.html b/src/app/health-page/health-info/health-info-component/health-info-component.component.html index 8ce7595980b..b16e88564fd 100644 --- a/src/app/health-page/health-info/health-info-component/health-info-component.component.html +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.html @@ -1,4 +1,34 @@ - +
+
+
+ +
+ + +
+
+
+
+
+ +
+
+
+
+ +

{{ entry.key | titlecase }} : {{entry.value}}

+
+
+ + + + diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts b/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts index 2297007cd5e..437d53a9536 100644 --- a/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts @@ -46,7 +46,9 @@ describe('HealthInfoComponentComponent', () => { }); it('should display property', () => { - const components = fixture.debugElement.queryAll(By.css('[data-test="component"]')); + const properties = fixture.debugElement.queryAll(By.css('[data-test="property"]')); + expect(properties.length).toBe(14); + const components = fixture.debugElement.queryAll(By.css('[data-test="info-component"]')); expect(components.length).toBe(4); }); diff --git a/src/app/health-page/health-info/health-info.component.html b/src/app/health-page/health-info/health-info.component.html index e4d29adf548..be69df23b46 100644 --- a/src/app/health-page/health-info/health-info.component.html +++ b/src/app/health-page/health-info/health-info.component.html @@ -1,7 +1,33 @@ -
+ + + +
+ +
+ +
+ + +
+
+
+
+ + + +
+
+ + + + diff --git a/src/app/health-page/health-info/health-info.component.spec.ts b/src/app/health-page/health-info/health-info.component.spec.ts index 3af1d71db3b..a7f319b88b3 100644 --- a/src/app/health-page/health-info/health-info.component.spec.ts +++ b/src/app/health-page/health-info/health-info.component.spec.ts @@ -4,6 +4,8 @@ import { HealthInfoComponent } from './health-info.component'; import { HealthInfoResponseObj } from '../../shared/mocks/health-endpoint.mocks'; import { ObjNgFor } from '../../shared/utils/object-ngfor.pipe'; import { By } from '@angular/platform-browser'; +import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; describe('HealthInfoComponent', () => { let component: HealthInfoComponent; @@ -11,10 +13,14 @@ describe('HealthInfoComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ + imports: [ + NgbAccordionModule, + ], declarations: [ HealthInfoComponent, ObjNgFor - ] + ], + schemas: [NO_ERRORS_SCHEMA] }) .compileComponents(); }); diff --git a/src/app/health-page/health-info/health-info.component.ts b/src/app/health-page/health-info/health-info.component.ts index a5fb0b282bc..9fddaeb7e43 100644 --- a/src/app/health-page/health-info/health-info.component.ts +++ b/src/app/health-page/health-info/health-info.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; import { HealthInfoResponse } from '../models/health-component.model'; @@ -7,8 +7,16 @@ import { HealthInfoResponse } from '../models/health-component.model'; templateUrl: './health-info.component.html', styleUrls: ['./health-info.component.scss'] }) -export class HealthInfoComponent { +export class HealthInfoComponent implements OnInit { @Input() healthInfoResponse: HealthInfoResponse; + /** + * The first active panel id + */ + activeId: string; + + ngOnInit(): void { + this.activeId = Object.keys(this.healthInfoResponse)[0]; + } } diff --git a/src/app/health-page/health-panel/health-component/health-component.component.html b/src/app/health-page/health-panel/health-component/health-component.component.html index 4569d06dad3..7089fe25c64 100644 --- a/src/app/health-page/health-panel/health-component/health-component.component.html +++ b/src/app/health-page/health-panel/health-component/health-component.component.html @@ -22,6 +22,7 @@
- {{ item.key | titlecase }} : {{item.value}} +

{{ item.key | titlecase }} : {{item.value}}

+
diff --git a/src/app/health-page/health-panel/health-panel.component.html b/src/app/health-page/health-panel/health-panel.component.html index eebcfe55ec3..d47a73d8204 100644 --- a/src/app/health-page/health-panel/health-panel.component.html +++ b/src/app/health-page/health-panel/health-panel.component.html @@ -1,21 +1,25 @@

{{'health-page.status' | translate}} :

-
-
- -
- - - -
-
-
-
-
- + + + +
+ +
+ +
+ + +
+
-
-
-
+ + + + + + + + diff --git a/src/app/health-page/health-panel/health-panel.component.spec.ts b/src/app/health-page/health-panel/health-panel.component.spec.ts index da392f7ba85..1d9c856ddbb 100644 --- a/src/app/health-page/health-panel/health-panel.component.spec.ts +++ b/src/app/health-page/health-panel/health-panel.component.spec.ts @@ -5,14 +5,14 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NO_ERRORS_SCHEMA } from '@angular/core'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; -import { NgbCollapseModule, NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; +import { NgbAccordionModule, NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; import { HealthPanelComponent } from './health-panel.component'; import { HealthResponseObj } from '../../shared/mocks/health-endpoint.mocks'; import { ObjNgFor } from '../../shared/utils/object-ngfor.pipe'; -describe('HealthComponent', () => { +describe('HealthPanelComponent', () => { let component: HealthPanelComponent; let fixture: ComponentFixture; @@ -20,7 +20,7 @@ describe('HealthComponent', () => { await TestBed.configureTestingModule({ imports: [ NgbNavModule, - NgbCollapseModule, + NgbAccordionModule, CommonModule, BrowserAnimationsModule, TranslateModule.forRoot({ @@ -42,7 +42,6 @@ describe('HealthComponent', () => { fixture = TestBed.createComponent(HealthPanelComponent); component = fixture.componentInstance; component.healthResponse = HealthResponseObj; - component.isCollapsed = false; fixture.detectChanges(); }); @@ -50,7 +49,7 @@ describe('HealthComponent', () => { expect(component).toBeTruthy(); }); - it('should render a card for each component', () => { + it('should render a panel for each component', () => { const components = fixture.debugElement.queryAll(By.css('[data-test="component"]')); expect(components.length).toBe(5); }); diff --git a/src/app/health-page/health-panel/health-panel.component.ts b/src/app/health-page/health-panel/health-panel.component.ts index 549544c370a..8bb670e67f4 100644 --- a/src/app/health-page/health-panel/health-panel.component.ts +++ b/src/app/health-page/health-panel/health-panel.component.ts @@ -1,4 +1,4 @@ -import { Component, Input } from '@angular/core'; +import { Component, Input, OnInit } from '@angular/core'; import { HealthResponse } from '../models/health-component.model'; @Component({ @@ -6,7 +6,7 @@ import { HealthResponse } from '../models/health-component.model'; templateUrl: './health-panel.component.html', styleUrls: ['./health-panel.component.scss'] }) -export class HealthPanelComponent { +export class HealthPanelComponent implements OnInit { /** * Health endpoint response @@ -14,8 +14,11 @@ export class HealthPanelComponent { @Input() healthResponse: HealthResponse; /** - * A boolean representing if div should start collapsed + * The first active panel id */ - public isCollapsed = true; + activeId: string; + ngOnInit(): void { + this.activeId = Object.keys(this.healthResponse.components)[0]; + } } diff --git a/src/app/shared/mocks/health-endpoint.mocks.ts b/src/app/shared/mocks/health-endpoint.mocks.ts index 9bd39561391..a9246d91a10 100644 --- a/src/app/shared/mocks/health-endpoint.mocks.ts +++ b/src/app/shared/mocks/health-endpoint.mocks.ts @@ -134,7 +134,27 @@ export const HealthInfoComponentOne: HealthInfoComponent = { 'name': 'DSpace at My University', 'dir': '/home/giuseppe/development/java/install/dspace7-review', 'url': 'http://localhost:8080/server', - 'db': 'jdbc:postgresql://localhost:5432/dspace7' + 'db': 'jdbc:postgresql://localhost:5432/dspace7', + 'solr': { + 'server': 'http://localhost:8983/solr', + 'prefix': '' + }, + 'mail': { + 'server': 'smtp.example.com', + 'from-address': 'dspace-noreply@myu.edu', + 'feedback-recipient': 'dspace-help@myu.edu', + 'mail-admin': 'dspace-help@myu.edu', + 'mail-helpdesk': 'dspace-help@myu.edu', + 'alert-recipient': 'dspace-help@myu.edu' + }, + 'cors': { + 'allowed-origins': 'http://localhost:4000' + }, + 'ui': { + 'url': 'http://localhost:4000' + } }; -export const HealthInfoComponentTwo = '7.3-SNAPSHOT'; +export const HealthInfoComponentTwo = { + 'version': '7.3-SNAPSHOT' +}; From c508e0035e46c977bb7b0fad2163eff5109c3d81 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 16 May 2022 18:49:11 +0200 Subject: [PATCH 0396/2129] [CST-5535] Add tooltip for status icons --- .../health-status/health-status.component.html | 12 +++++++++--- src/assets/i18n/en.json5 | 8 ++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/app/health-page/health-panel/health-status/health-status.component.html b/src/app/health-page/health-panel/health-status/health-status.component.html index fdd726cddfe..38a6f726018 100644 --- a/src/app/health-page/health-panel/health-status/health-status.component.html +++ b/src/app/health-page/health-panel/health-status/health-status.component.html @@ -1,6 +1,12 @@ - - - + + + diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index c129187023d..78661ced765 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1567,6 +1567,14 @@ + "health-page.status.ok.info": "Operational", + + "health-page.status.error.info": "Problems detected", + + "health-page.status.warning.info": "Possible issues detected", + + + "home.description": "", "home.breadcrumbs": "Home", From 73573793a0eacc52789c4df6b7a653040393f407 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 16 May 2022 18:50:07 +0200 Subject: [PATCH 0397/2129] [CST-5535] Add i18n keys for section's headers --- .../health-info/health-info.component.html | 2 +- .../health-panel/health-panel.component.html | 2 +- src/assets/i18n/en.json5 | 15 +++++++++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/app/health-page/health-info/health-info.component.html b/src/app/health-page/health-info/health-info.component.html index be69df23b46..12764ead45b 100644 --- a/src/app/health-page/health-info/health-info.component.html +++ b/src/app/health-page/health-info/health-info.component.html @@ -5,7 +5,7 @@
diff --git a/src/app/health-page/health-panel/health-panel.component.html b/src/app/health-page/health-panel/health-panel.component.html index d47a73d8204..d095ce2f6d4 100644 --- a/src/app/health-page/health-panel/health-panel.component.html +++ b/src/app/health-page/health-panel/health-panel.component.html @@ -5,7 +5,7 @@
diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 78661ced765..c22ec1c3ee8 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1566,6 +1566,21 @@ "grant-request-copy.success": "Successfully granted item request", + "health-page.section.db.title": "Database", + + "health-page.section.geoIp.title": "GeoIp", + + "health-page.section.solrAuthorityCore.title": "Sor: authority core", + + "health-page.section.solrOaiCore.title": "Sor: oai core", + + "health-page.section.solrSearchCore.title": "Sor: search core", + + "health-page.section.solrStatisticsCore.title": "Sor: statistics core", + + "health-page.section-info.app.title": "Application Backend", + + "health-page.section-info.java.title": "Java", "health-page.status.ok.info": "Operational", From 74b68a5e154f1285ad3e7ec9d13fcb30590378d4 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 16 May 2022 19:19:00 +0200 Subject: [PATCH 0398/2129] [CST-5535] Add fallback message on rest request error --- .../health-page/health-page.component.html | 45 ++++++++++--------- src/app/health-page/health-page.component.ts | 11 +++-- src/assets/i18n/en.json5 | 2 + 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/app/health-page/health-page.component.html b/src/app/health-page/health-page.component.html index 6ec9abddcb4..0647620c733 100644 --- a/src/app/health-page/health-page.component.html +++ b/src/app/health-page/health-page.component.html @@ -1,21 +1,26 @@ -
- -
+
+ +
+ + diff --git a/src/app/health-page/health-page.component.ts b/src/app/health-page/health-page.component.ts index eb07b63addf..a92e72744bf 100644 --- a/src/app/health-page/health-page.component.ts +++ b/src/app/health-page/health-page.component.ts @@ -30,12 +30,15 @@ export class HealthPageComponent implements OnInit { * Retrieve responses from rest */ ngOnInit(): void { - this.healthDataService.getHealth().pipe(take(1)).subscribe((data: any) => { - this.healthResponse.next(data.payload); + this.healthDataService.getHealth().pipe(take(1)).subscribe({ + next: (data: any) => { this.healthResponse.next(data.payload); }, + error: () => { this.healthResponse.next(null); } }); - this.healthDataService.getInfo().pipe(take(1)).subscribe((data) => { - this.healthInfoResponse.next(data.payload); + this.healthDataService.getInfo().pipe(take(1)).subscribe({ + next: (data: any) => { this.healthInfoResponse.next(data.payload); }, + error: () => { this.healthInfoResponse.next(null); } }); + } } diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 4fcdbff335a..216b29fcd01 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1583,6 +1583,8 @@ "grant-request-copy.success": "Successfully granted item request", + "health-page.error.msg": "The health check service is temporarily unavailable", + "health-page.section.db.title": "Database", "health-page.section.geoIp.title": "GeoIp", From 1f9b8ba92a4fcf09e2f0c6cb8661f7b8b6fdd637 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Tue, 17 May 2022 11:16:46 +0200 Subject: [PATCH 0399/2129] Fix issue where you'd get stuck in an infinite redirect loop when going to the page of an item with an entity type containing certain special characters --- src/app/item-page/item-page.resolver.spec.ts | 87 ++++++++++++++++++++ src/app/item-page/item-page.resolver.ts | 10 ++- 2 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/app/item-page/item-page.resolver.spec.ts diff --git a/src/app/item-page/item-page.resolver.spec.ts b/src/app/item-page/item-page.resolver.spec.ts new file mode 100644 index 00000000000..533f97d0c0e --- /dev/null +++ b/src/app/item-page/item-page.resolver.spec.ts @@ -0,0 +1,87 @@ +import { ItemPageResolver } from './item-page.resolver'; +import { createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils'; +import { DSpaceObject } from '../core/shared/dspace-object.model'; +import { MetadataValueFilter } from '../core/shared/metadata.models'; +import { first } from 'rxjs/operators'; +import { Router } from '@angular/router'; +import { TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; + +describe('ItemPageResolver', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [RouterTestingModule.withRoutes([{ + path: 'entities/:entity-type/:id', + component: {} as any + }])] + }); + }); + + describe('resolve', () => { + let resolver: ItemPageResolver; + let itemService: any; + let store: any; + let router: any; + + const uuid = '1234-65487-12354-1235'; + let item: DSpaceObject; + + function runTestsWithEntityType(entityType: string) { + beforeEach(() => { + router = TestBed.inject(Router); + item = Object.assign(new DSpaceObject(), { + uuid: uuid, + firstMetadataValue(_keyOrKeys: string | string[], _valueFilter?: MetadataValueFilter): string { + return entityType; + } + }); + itemService = { + findById: (_id: string) => createSuccessfulRemoteDataObject$(item) + }; + store = jasmine.createSpyObj('store', { + dispatch: {}, + }); + resolver = new ItemPageResolver(itemService, store, router); + }); + + it('should redirect to the correct route for the entity type', (done) => { + spyOn(item, 'firstMetadataValue').and.returnValue(entityType); + spyOn(router, 'navigateByUrl').and.callThrough(); + + resolver.resolve({ params: { id: uuid } } as any, { url: router.parseUrl(`/items/${uuid}`).toString() } as any) + .pipe(first()) + .subscribe( + () => { + expect(router.navigateByUrl).toHaveBeenCalledWith(router.parseUrl(`/entities/${entityType}/${uuid}`).toString()); + done(); + } + ); + }); + + it('should not redirect if we’re already on the correct route', (done) => { + spyOn(item, 'firstMetadataValue').and.returnValue(entityType); + spyOn(router, 'navigateByUrl').and.callThrough(); + + resolver.resolve({ params: { id: uuid } } as any, { url: router.parseUrl(`/entities/${entityType}/${uuid}`).toString() } as any) + .pipe(first()) + .subscribe( + () => { + expect(router.navigateByUrl).not.toHaveBeenCalled(); + done(); + } + ); + }); + } + + describe('when normal entity type is provided', () => { + runTestsWithEntityType('publication'); + }); + + describe('when entity type contains a special character', () => { + runTestsWithEntityType('alligator,loki'); + runTestsWithEntityType('🐊'); + runTestsWithEntityType(' '); + }); + + }); +}); diff --git a/src/app/item-page/item-page.resolver.ts b/src/app/item-page/item-page.resolver.ts index 7edffc53578..e9b287406e0 100644 --- a/src/app/item-page/item-page.resolver.ts +++ b/src/app/item-page/item-page.resolver.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router'; +import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router'; import { Observable } from 'rxjs'; import { RemoteData } from '../core/data/remote-data'; import { ItemDataService } from '../core/data/item-data.service'; @@ -35,8 +35,14 @@ export class ItemPageResolver extends ItemResolver { return super.resolve(route, state).pipe( map((rd: RemoteData) => { if (rd.hasSucceeded && hasValue(rd.payload)) { - const itemRoute = getItemPageRoute(rd.payload); const thisRoute = state.url; + + // Angular uses a custom function for encodeURIComponent, (e.g. it doesn't encode commas + // or semicolons) and thisRoute has been encoded with that function. If we want to compare + // it with itemRoute, we have to run itemRoute through Angular's version as well to ensure + // the same characters are encoded the same way. + const itemRoute = this.router.parseUrl(getItemPageRoute(rd.payload)).toString(); + if (!thisRoute.startsWith(itemRoute)) { const itemId = rd.payload.uuid; const subRoute = thisRoute.substring(thisRoute.indexOf(itemId) + itemId.length, thisRoute.length); From 881af6449542ee174206d5b10ec27b87f0254219 Mon Sep 17 00:00:00 2001 From: Davide Negretti Date: Tue, 17 May 2022 16:36:40 +0200 Subject: [PATCH 0400/2129] [CST-5674] POST replaced with PUT --- .../resource-policy.service.ts | 4 +-- .../form/resource-policy-form.component.html | 34 +++++++++---------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/app/core/resource-policy/resource-policy.service.ts b/src/app/core/resource-policy/resource-policy.service.ts index ca3951109af..8411647beab 100644 --- a/src/app/core/resource-policy/resource-policy.service.ts +++ b/src/app/core/resource-policy/resource-policy.service.ts @@ -29,7 +29,7 @@ import { getFirstCompletedRemoteData } from '../shared/operators'; import { CoreState } from '../core-state.model'; import { FindListOptions } from '../data/find-list-options.model'; import { HttpOptions } from '../dspace-rest/dspace-rest.service'; -import { PostRequest } from '../data/request.models'; +import { PutRequest } from '../data/request.models'; import { GenericConstructor } from '../shared/generic-constructor'; import { ResponseParsingService } from '../data/parsing.service'; import { StatusCodeOnlyResponseParsingService } from '../data/status-code-only-response-parsing.service'; @@ -260,7 +260,7 @@ export class ResourcePolicyService { return targetEndpoint$.pipe(switchMap((targetEndpoint) => { const resourceEndpoint = resourcePolicyHref + '/' + type; - const request = new PostRequest(requestId, resourceEndpoint, targetEndpoint, options); + const request = new PutRequest(requestId, resourceEndpoint, targetEndpoint, options); Object.assign(request, { getResponseParser(): GenericConstructor { return StatusCodeOnlyResponseParsingService; diff --git a/src/app/shared/resource-policies/form/resource-policy-form.component.html b/src/app/shared/resource-policies/form/resource-policy-form.component.html index f7aad55ce8c..66c1fc400e9 100644 --- a/src/app/shared/resource-policies/form/resource-policy-form.component.html +++ b/src/app/shared/resource-policies/form/resource-policy-form.component.html @@ -8,24 +8,22 @@
- - -
-
+ +

From 618ff0ce19607900bfd165aec9ae7ef01a9b19a2 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Tue, 17 May 2022 17:45:27 +0200 Subject: [PATCH 0401/2129] [CST-5303] added missing labels --- src/assets/i18n/en.json5 | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index bb2bcf8ebc6..5bae41d0a14 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3644,6 +3644,26 @@ "submission.sections.describe.relationship-lookup.external-source.import-button-title.isProjectOfPublication": "Project", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.none = "Import remote item", + + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Event": "Import remote event", + + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Product": "Import remote product", + + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Equipment": "Import remote equipment", + + "submission.sections.describe.relationship-lookup.external-source.import-button-title.OrgUnit = "Import remote organizational unit", + + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Funding": "Import remote fund", + + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Person = "Import remote person", + + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Patent": "Import remote patent", + + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Project = "Import remote project", + + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Publication = "Import remote publication", + "submission.sections.describe.relationship-lookup.external-source.import-modal.isProjectOfPublication.added.new-entity": "New Entity Added!", "submission.sections.describe.relationship-lookup.external-source.import-modal.isProjectOfPublication.title": "Project", From a732f1534de03fbdc89aad33af769dc50f40fb72 Mon Sep 17 00:00:00 2001 From: Mykhaylo Date: Wed, 18 May 2022 09:33:08 +0200 Subject: [PATCH 0402/2129] [CST-5303] fix wrong format --- src/assets/i18n/en.json5 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 5bae41d0a14..dffbbd4b7ed 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -3644,7 +3644,7 @@ "submission.sections.describe.relationship-lookup.external-source.import-button-title.isProjectOfPublication": "Project", - "submission.sections.describe.relationship-lookup.external-source.import-button-title.none = "Import remote item", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.none": "Import remote item", "submission.sections.describe.relationship-lookup.external-source.import-button-title.Event": "Import remote event", @@ -3652,17 +3652,17 @@ "submission.sections.describe.relationship-lookup.external-source.import-button-title.Equipment": "Import remote equipment", - "submission.sections.describe.relationship-lookup.external-source.import-button-title.OrgUnit = "Import remote organizational unit", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.OrgUnit": "Import remote organizational unit", "submission.sections.describe.relationship-lookup.external-source.import-button-title.Funding": "Import remote fund", - "submission.sections.describe.relationship-lookup.external-source.import-button-title.Person = "Import remote person", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Person": "Import remote person", "submission.sections.describe.relationship-lookup.external-source.import-button-title.Patent": "Import remote patent", - "submission.sections.describe.relationship-lookup.external-source.import-button-title.Project = "Import remote project", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Project": "Import remote project", - "submission.sections.describe.relationship-lookup.external-source.import-button-title.Publication = "Import remote publication", + "submission.sections.describe.relationship-lookup.external-source.import-button-title.Publication": "Import remote publication", "submission.sections.describe.relationship-lookup.external-source.import-modal.isProjectOfPublication.added.new-entity": "New Entity Added!", From d4dc176870d46506ad72670ba391f9f041e1c495 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Wed, 18 May 2022 13:04:04 +0200 Subject: [PATCH 0403/2129] [CST-5535] Add Possibility to have translation also for properties --- .../health-info-component.component.html | 4 ++-- .../health-info-component.component.scss | 3 +++ .../health-info-component.component.spec.ts | 10 +++++++++- .../health-info-component.component.ts | 12 ++++++++++-- .../health-info/health-info.component.html | 4 ++-- .../health-info/health-info.component.scss | 3 +++ .../health-info/health-info.component.spec.ts | 8 ++++++++ .../health-info/health-info.component.ts | 15 +++++++++++++++ .../health-component.component.html | 4 ++-- .../health-component.component.scss | 3 +++ .../health-component.component.spec.ts | 10 +++++++++- .../health-component.component.ts | 17 ++++++++++++++++- .../health-panel/health-panel.component.html | 4 ++-- .../health-panel/health-panel.component.scss | 3 +++ .../health-panel/health-panel.component.ts | 16 ++++++++++++++++ .../health-status.component.spec.ts | 12 ++++++++++++ src/assets/i18n/en.json5 | 2 ++ 17 files changed, 117 insertions(+), 13 deletions(-) diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.html b/src/app/health-page/health-info/health-info-component/health-info-component.component.html index b16e88564fd..b607d95f45d 100644 --- a/src/app/health-page/health-info/health-info-component/health-info-component.component.html +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.html @@ -1,6 +1,6 @@
-
+
-

{{ entry.key | titlecase }} : {{entry.value}}

+

{{ getPropertyLabel(entry.key) | titlecase }} : {{entry.value}}

diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.scss b/src/app/health-page/health-info/health-info-component/health-info-component.component.scss index e69de29bb2d..a6f0e734136 100644 --- a/src/app/health-page/health-info/health-info-component/health-info-component.component.scss +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.scss @@ -0,0 +1,3 @@ +.collapse-toggle { + cursor: pointer; +} diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts b/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts index 437d53a9536..b4532415b89 100644 --- a/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.spec.ts @@ -8,6 +8,8 @@ import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap'; import { HealthInfoComponentComponent } from './health-info-component.component'; import { HealthInfoComponentOne, HealthInfoComponentTwo } from '../../../shared/mocks/health-endpoint.mocks'; import { ObjNgFor } from '../../../shared/utils/object-ngfor.pipe'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { TranslateLoaderMock } from '../../../shared/mocks/translate-loader.mock'; describe('HealthInfoComponentComponent', () => { let component: HealthInfoComponentComponent; @@ -18,7 +20,13 @@ describe('HealthInfoComponentComponent', () => { imports: [ CommonModule, NgbCollapseModule, - NoopAnimationsModule + NoopAnimationsModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock + } + }) ], declarations: [ HealthInfoComponentComponent, diff --git a/src/app/health-page/health-info/health-info-component/health-info-component.component.ts b/src/app/health-page/health-info/health-info-component/health-info-component.component.ts index b6c31214c8f..159462cd6d5 100644 --- a/src/app/health-page/health-info/health-info-component/health-info-component.component.ts +++ b/src/app/health-page/health-info/health-info-component/health-info-component.component.ts @@ -1,13 +1,14 @@ import { Component, Input } from '@angular/core'; import { HealthInfoComponent } from '../../models/health-component.model'; +import { HealthComponentComponent } from '../../health-panel/health-component/health-component.component'; @Component({ selector: 'ds-health-info-component', templateUrl: './health-info-component.component.html', styleUrls: ['./health-info-component.component.scss'] }) -export class HealthInfoComponentComponent { +export class HealthInfoComponentComponent extends HealthComponentComponent { /** * The HealthInfoComponent object to display @@ -27,9 +28,16 @@ export class HealthInfoComponentComponent { /** * A boolean representing if div should start collapsed */ - public isCollapsed = true; + public isCollapsed = false; + /** + * Check if the HealthInfoComponent is has only string property or contains object + * + * @param entry The HealthInfoComponent to check + * @return boolean + */ isPlainProperty(entry: HealthInfoComponent | string): boolean { return typeof entry === 'string'; } + } diff --git a/src/app/health-page/health-info/health-info.component.html b/src/app/health-page/health-info/health-info.component.html index 12764ead45b..47e4cfb4d2f 100644 --- a/src/app/health-page/health-info/health-info.component.html +++ b/src/app/health-page/health-info/health-info.component.html @@ -2,10 +2,10 @@ -
+
diff --git a/src/app/health-page/health-info/health-info.component.scss b/src/app/health-page/health-info/health-info.component.scss index e69de29bb2d..a6f0e734136 100644 --- a/src/app/health-page/health-info/health-info.component.scss +++ b/src/app/health-page/health-info/health-info.component.scss @@ -0,0 +1,3 @@ +.collapse-toggle { + cursor: pointer; +} diff --git a/src/app/health-page/health-info/health-info.component.spec.ts b/src/app/health-page/health-info/health-info.component.spec.ts index a7f319b88b3..5a9b8bf0aa5 100644 --- a/src/app/health-page/health-info/health-info.component.spec.ts +++ b/src/app/health-page/health-info/health-info.component.spec.ts @@ -6,6 +6,8 @@ import { ObjNgFor } from '../../shared/utils/object-ngfor.pipe'; import { By } from '@angular/platform-browser'; import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap'; import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; describe('HealthInfoComponent', () => { let component: HealthInfoComponent; @@ -15,6 +17,12 @@ describe('HealthInfoComponent', () => { await TestBed.configureTestingModule({ imports: [ NgbAccordionModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock + } + }) ], declarations: [ HealthInfoComponent, diff --git a/src/app/health-page/health-info/health-info.component.ts b/src/app/health-page/health-info/health-info.component.ts index 9fddaeb7e43..d8c629636b1 100644 --- a/src/app/health-page/health-info/health-info.component.ts +++ b/src/app/health-page/health-info/health-info.component.ts @@ -1,6 +1,7 @@ import { Component, Input, OnInit } from '@angular/core'; import { HealthInfoResponse } from '../models/health-component.model'; +import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'ds-health-info', @@ -16,7 +17,21 @@ export class HealthInfoComponent implements OnInit { */ activeId: string; + constructor(private translate: TranslateService) { + } + ngOnInit(): void { this.activeId = Object.keys(this.healthInfoResponse)[0]; } + /** + * Return translated label if exist for the given property + * + * @param property + */ + public getPanelLabel(panelKey: string): string { + const translationKey = `health-page.section-info.${panelKey}.title`; + const translation = this.translate.instant(translationKey); + + return (translation === translationKey) ? panelKey : translation; + } } diff --git a/src/app/health-page/health-panel/health-component/health-component.component.html b/src/app/health-page/health-panel/health-component/health-component.component.html index 7089fe25c64..c254f128d98 100644 --- a/src/app/health-page/health-panel/health-component/health-component.component.html +++ b/src/app/health-page/health-panel/health-component/health-component.component.html @@ -1,6 +1,6 @@
-
+
diff --git a/src/app/health-page/health-panel/health-panel.component.scss b/src/app/health-page/health-panel/health-panel.component.scss index e69de29bb2d..a6f0e734136 100644 --- a/src/app/health-page/health-panel/health-panel.component.scss +++ b/src/app/health-page/health-panel/health-panel.component.scss @@ -0,0 +1,3 @@ +.collapse-toggle { + cursor: pointer; +} diff --git a/src/app/health-page/health-panel/health-panel.component.ts b/src/app/health-page/health-panel/health-panel.component.ts index 8bb670e67f4..3137334d6f7 100644 --- a/src/app/health-page/health-panel/health-panel.component.ts +++ b/src/app/health-page/health-panel/health-panel.component.ts @@ -1,5 +1,6 @@ import { Component, Input, OnInit } from '@angular/core'; import { HealthResponse } from '../models/health-component.model'; +import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'ds-health-panel', @@ -18,7 +19,22 @@ export class HealthPanelComponent implements OnInit { */ activeId: string; + constructor(private translate: TranslateService) { + } + ngOnInit(): void { this.activeId = Object.keys(this.healthResponse.components)[0]; } + + /** + * Return translated label if exist for the given property + * + * @param property + */ + public getPanelLabel(panelKey: string): string { + const translationKey = `health-page.section.${panelKey}.title`; + const translation = this.translate.instant(translationKey); + + return (translation === translationKey) ? panelKey : translation; + } } diff --git a/src/app/health-page/health-panel/health-status/health-status.component.spec.ts b/src/app/health-page/health-panel/health-status/health-status.component.spec.ts index 13df9c23e36..f0f61ebdbbe 100644 --- a/src/app/health-page/health-panel/health-status/health-status.component.spec.ts +++ b/src/app/health-page/health-panel/health-status/health-status.component.spec.ts @@ -3,6 +3,9 @@ import { By } from '@angular/platform-browser'; import { HealthStatusComponent } from './health-status.component'; import { HealthStatus } from '../../models/health-component.model'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { TranslateLoaderMock } from '../../../shared/mocks/translate-loader.mock'; +import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; describe('HealthStatusComponent', () => { let component: HealthStatusComponent; @@ -10,6 +13,15 @@ describe('HealthStatusComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ + imports: [ + NgbTooltipModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock + } + }) + ], declarations: [ HealthStatusComponent ] }) .compileComponents(); diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 216b29fcd01..18a406b77b8 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -1585,6 +1585,8 @@ "health-page.error.msg": "The health check service is temporarily unavailable", + "health-page.property.status": "Status code", + "health-page.section.db.title": "Database", "health-page.section.geoIp.title": "GeoIp", From ef332af17ea62afce19ef83763ac30b356e63289 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Wed, 18 May 2022 13:31:09 +0200 Subject: [PATCH 0404/2129] [CST-5535] Fix issue with error notice message on health page loading --- .../health-page/health-page.component.html | 2 +- src/app/health-page/health-page.component.ts | 30 ++++++++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/app/health-page/health-page.component.html b/src/app/health-page/health-page.component.html index 0647620c733..605927dc552 100644 --- a/src/app/health-page/health-page.component.html +++ b/src/app/health-page/health-page.component.html @@ -1,4 +1,4 @@ -
+
From 19d0975df517ed9e49f8770ca2d828a46311ba1e Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 10 Feb 2023 12:21:33 +0100 Subject: [PATCH 1455/2129] 99053: Fixed encoded parameters being encoded twice in WorkflowItemActionPageComponent.previousPage() --- .../workflow-item-action-page.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/workflowitems-edit-page/workflow-item-action-page.component.ts b/src/app/workflowitems-edit-page/workflow-item-action-page.component.ts index 0f6a222d85a..276b2054fe4 100644 --- a/src/app/workflowitems-edit-page/workflow-item-action-page.component.ts +++ b/src/app/workflowitems-edit-page/workflow-item-action-page.component.ts @@ -78,7 +78,7 @@ export abstract class WorkflowItemActionPageComponent implements OnInit { const params: Params = {}; if (url.split('?').length > 1) { for (const param of url.split('?')[1].split('&')) { - params[param.split('=')[0]] = param.split('=')[1]; + params[param.split('=')[0]] = decodeURIComponent(param.split('=')[1]); } } void this.router.navigate([url.split('?')[0]], { queryParams: params }); From 99f9f592a0223a523887cf48cc6d4dfbcade99b0 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 10 Feb 2023 12:50:36 +0100 Subject: [PATCH 1456/2129] 99053: Passed previousSearchQuery to AdvancedWorkflowActionSelectReviewerComponent --- ...claimed-task-actions-abstract.component.ts | 16 +++++++--- ...k-action-select-reviewer.component.spec.ts | 24 ++++++++++++++- ...d-task-action-select-reviewer.component.ts | 12 +++++++- src/app/shared/testing/active-router.stub.ts | 3 +- ...w-action-select-reviewer.component.spec.ts | 29 +++++++++++++++---- ...rkflow-action-select-reviewer.component.ts | 13 +++++++-- 6 files changed, 82 insertions(+), 15 deletions(-) diff --git a/src/app/shared/mydspace-actions/claimed-task/abstract/advanced-claimed-task-actions-abstract.component.ts b/src/app/shared/mydspace-actions/claimed-task/abstract/advanced-claimed-task-actions-abstract.component.ts index 06d51d67a3b..32d9a230eb8 100644 --- a/src/app/shared/mydspace-actions/claimed-task/abstract/advanced-claimed-task-actions-abstract.component.ts +++ b/src/app/shared/mydspace-actions/claimed-task/abstract/advanced-claimed-task-actions-abstract.component.ts @@ -3,6 +3,7 @@ import { ClaimedTaskActionsAbstractComponent } from './claimed-task-actions-abst import { getFirstSucceededRemoteDataPayload } from '../../../../core/shared/operators'; import { WorkflowItem } from '../../../../core/submission/models/workflowitem.model'; import { getAdvancedWorkflowRoute } from '../../../../workflowitems-edit-page/workflowitems-edit-page-routing-paths'; +import { Params } from '@angular/router'; /** * Abstract component for rendering an advanced claimed task's action @@ -47,11 +48,18 @@ export abstract class AdvancedClaimedTaskActionsAbstractComponent extends Claime */ openAdvancedClaimedTaskTab(): void { void this.router.navigate([this.workflowTaskPageRoute], { - queryParams: { - workflow: this.workflowType, - claimedTask: this.object.id, - }, + queryParams: this.getQueryParams(), }); } + /** + * The {@link Params} that need to be given to the workflow page. + */ + getQueryParams(): Params { + return { + workflow: this.workflowType, + claimedTask: this.object.id, + }; + } + } diff --git a/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.spec.ts b/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.spec.ts index db670e3cdcb..60f47a60b8a 100644 --- a/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.spec.ts +++ b/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.spec.ts @@ -2,7 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdvancedClaimedTaskActionSelectReviewerComponent } from './advanced-claimed-task-action-select-reviewer.component'; -import { Router } from '@angular/router'; +import { Router, ActivatedRoute } from '@angular/router'; import { RouterStub } from '../../../testing/router.stub'; import { NotificationsServiceStub } from '../../../testing/notifications-service.stub'; import { NotificationsService } from '../../../notifications/notifications.service'; @@ -22,6 +22,7 @@ import { } from '../../../../workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component'; import { WorkflowItem } from '../../../../core/submission/models/workflowitem.model'; import { of as observableOf } from 'rxjs'; +import { ActivatedRouteStub } from '../../../testing/active-router.stub'; const taskId = 'claimed-task-1'; const workflowId = 'workflow-1'; @@ -36,12 +37,14 @@ describe('AdvancedClaimedTaskActionSelectReviewerComponent', () => { let component: AdvancedClaimedTaskActionSelectReviewerComponent; let fixture: ComponentFixture; + let route: ActivatedRouteStub; let claimedTaskDataService: ClaimedTaskDataServiceStub; let notificationService: NotificationsServiceStub; let router: RouterStub; let searchService: SearchServiceStub; beforeEach(async () => { + route = new ActivatedRouteStub(); claimedTaskDataService = new ClaimedTaskDataServiceStub(); notificationService = new NotificationsServiceStub(); router = new RouterStub(); @@ -56,6 +59,7 @@ describe('AdvancedClaimedTaskActionSelectReviewerComponent', () => { NgbTooltip, ], providers: [ + { provide: ActivatedRoute, useValue: route }, { provide: ClaimedTaskDataService, useValue: claimedTaskDataService }, { provide: NotificationsService, useValue: notificationService }, { provide: RequestService, useValue: {} }, @@ -95,4 +99,22 @@ describe('AdvancedClaimedTaskActionSelectReviewerComponent', () => { }, }); }); + + it('should navigate to the advanced workflow page with a previousSearchQuery when clicked anq a query is defined', () => { + spyOnProperty(route, 'snapshot').and.returnValue({ + queryParams: { + query: 'Thor%20Love%20and%20Thunder', + } + }); + component.workflowTaskPageRoute = `/workflowitems/${workflowId}/advanced`; + fixture.debugElement.query(By.css('.selectReviewerAction')).nativeElement.click(); + + expect(router.navigate).toHaveBeenCalledWith([`/workflowitems/${workflowId}/advanced`], { + queryParams: { + workflow: ADVANCED_WORKFLOW_ACTION_SELECT_REVIEWER, + claimedTask: taskId, + previousSearchQuery: 'Thor%20Love%20and%20Thunder', + }, + }); + }); }); diff --git a/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.ts b/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.ts index 7473c737d9d..2331a8bd7fb 100644 --- a/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.ts +++ b/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.ts @@ -3,7 +3,7 @@ import { rendersWorkflowTaskOption } from '../switcher/claimed-task-actions-deco import { AdvancedClaimedTaskActionsAbstractComponent } from '../abstract/advanced-claimed-task-actions-abstract.component'; -import { Router } from '@angular/router'; +import { Router, Params, ActivatedRoute } from '@angular/router'; import { NotificationsService } from '../../../notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; import { SearchService } from '../../../../core/shared/search/search.service'; @@ -12,6 +12,7 @@ import { ADVANCED_WORKFLOW_ACTION_SELECT_REVIEWER, ADVANCED_WORKFLOW_TASK_OPTION_SELECT_REVIEWER } from '../../../../workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component'; +import { hasValue } from '../../../empty.util'; /** * Advanced Workflow button that redirect to the {@link AdvancedWorkflowActionSelectReviewerComponent} @@ -38,8 +39,17 @@ export class AdvancedClaimedTaskActionSelectReviewerComponent extends AdvancedCl protected translate: TranslateService, protected searchService: SearchService, protected requestService: RequestService, + protected route: ActivatedRoute, ) { super(injector, router, notificationsService, translate, searchService, requestService); } + getQueryParams(): Params { + const params: Params = super.getQueryParams(); + if (hasValue(this.route.snapshot.queryParams.query)) { + params.previousSearchQuery = this.route.snapshot.queryParams.query; + } + return params; + } + } diff --git a/src/app/shared/testing/active-router.stub.ts b/src/app/shared/testing/active-router.stub.ts index aa4bfce438d..86d92a2fb87 100644 --- a/src/app/shared/testing/active-router.stub.ts +++ b/src/app/shared/testing/active-router.stub.ts @@ -54,7 +54,8 @@ export class ActivatedRouteStub { get snapshot() { return { params: this.testParams, - queryParamMap: convertToParamMap(this.testParams) + queryParamMap: convertToParamMap(this.testParams), + queryParams: {} as Params, }; } } diff --git a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts index 2884dbcc8e4..42d68748998 100644 --- a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts +++ b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts @@ -1,12 +1,11 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdvancedWorkflowActionSelectReviewerComponent, - ADVANCED_WORKFLOW_TASK_OPTION_SELECT_REVIEWER + ADVANCED_WORKFLOW_TASK_OPTION_SELECT_REVIEWER, } from './advanced-workflow-action-select-reviewer.component'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { WorkflowItemDataService } from '../../../core/submission/workflowitem-data.service'; import { WorkflowItemDataServiceStub } from '../../../shared/testing/workflow-item-data-service.stub'; -import { RouterTestingModule } from '@angular/router/testing'; import { WorkflowActionDataServiceStub } from '../../../shared/testing/workflow-action-data-service.stub'; import { WorkflowActionDataService } from '../../../core/data/workflow-action-data.service'; import { RouteService } from '../../../core/services/route.service'; @@ -25,6 +24,7 @@ import { ProcessTaskResponse } from '../../../core/tasks/models/process-task-res import { NO_ERRORS_SCHEMA } from '@angular/core'; import { RequestService } from '../../../core/data/request.service'; import { RequestServiceStub } from '../../../shared/testing/request-service.stub'; +import { RouterStub } from '../../../shared/testing/router.stub'; const claimedTaskId = '2'; const workflowId = '1'; @@ -37,18 +37,19 @@ describe('AdvancedWorkflowActionSelectReviewerComponent', () => { let claimedTaskDataService: ClaimedTaskDataServiceStub; let notificationService: NotificationsServiceStub; + let router: RouterStub; let workflowActionDataService: WorkflowItemDataServiceStub; let workflowItemDataService: WorkflowItemDataServiceStub; beforeEach(async () => { claimedTaskDataService = new ClaimedTaskDataServiceStub(); notificationService = new NotificationsServiceStub(); + router = new RouterStub(); workflowActionDataService = new WorkflowActionDataServiceStub(); workflowItemDataService = new WorkflowItemDataServiceStub(); await TestBed.configureTestingModule({ imports: [ - RouterTestingModule, TranslateModule.forRoot(), ], declarations: [ @@ -66,10 +67,12 @@ describe('AdvancedWorkflowActionSelectReviewerComponent', () => { queryParams: { claimedTask: claimedTaskId, workflow: 'testaction', + previousSearchQuery: 'Thor%20Love%20and%20Thunder', }, }, }, }, + { provide: Router, useValue: router }, { provide: ClaimedTaskDataService, useValue: claimedTaskDataService }, { provide: NotificationsService, useValue: notificationService }, { provide: RouteService, useValue: routeServiceStub }, @@ -85,14 +88,30 @@ describe('AdvancedWorkflowActionSelectReviewerComponent', () => { fixture = TestBed.createComponent(AdvancedWorkflowActionSelectReviewerComponent); component = fixture.componentInstance; fixture.detectChanges(); - spyOn(component, 'previousPage'); }); afterEach(() => { fixture.debugElement.nativeElement.remove(); }); + describe('previousPage', () => { + it('should navigate back to the Workflow tasks page with the previous query', () => { + component.previousPage(); + + expect(router.navigate).toHaveBeenCalledWith(['/mydspace'], { + queryParams: { + configuration: 'workflow', + query: 'Thor Love and Thunder', + }, + }); + }); + }); + describe('performAction', () => { + beforeEach(() => { + spyOn(component, 'previousPage'); + }); + it('should call the claimedTaskDataService with the list of selected ePersons', () => { spyOn(claimedTaskDataService, 'submitTask').and.returnValue(observableOf(new ProcessTaskResponse(true))); component.selectedReviewers = [EPersonMock, EPersonMock2]; diff --git a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts index b9f90e1736a..54eb87f2cd2 100644 --- a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts +++ b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts @@ -12,7 +12,7 @@ import { } from '../../../access-control/group-registry/group-form/members-list/members-list.component'; import { Subscription } from 'rxjs'; import { EPerson } from '../../../core/eperson/models/eperson.model'; -import { ActivatedRoute, Router } from '@angular/router'; +import { ActivatedRoute, Params, Router } from '@angular/router'; import { WorkflowItemDataService } from '../../../core/submission/workflowitem-data.service'; import { RouteService } from '../../../core/services/route.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; @@ -20,7 +20,8 @@ import { TranslateService } from '@ngx-translate/core'; import { WorkflowActionDataService } from '../../../core/data/workflow-action-data.service'; import { ClaimedTaskDataService } from '../../../core/tasks/claimed-task-data.service'; import { ReviewersListComponent } from './reviewers-list/reviewers-list.component'; -import { RequestService } from 'src/app/core/data/request.service'; +import { RequestService } from '../../../core/data/request.service'; +import { hasValue } from '../../../shared/empty.util'; export const ADVANCED_WORKFLOW_TASK_OPTION_SELECT_REVIEWER = 'submit_select_reviewer'; export const ADVANCED_WORKFLOW_ACTION_SELECT_REVIEWER = 'selectrevieweraction'; @@ -138,7 +139,13 @@ export class AdvancedWorkflowActionSelectReviewerComponent extends AdvancedWorkf * switching between the different pages */ previousPage(): void { - void this.router.navigate(['/mydspace'], { queryParams: { configuration: 'workflow' } }); + const queryParams: Params = { + configuration: 'workflow', + }; + if (hasValue(this.route.snapshot.queryParams.previousSearchQuery)) { + queryParams.query = decodeURIComponent(this.route.snapshot.queryParams.previousSearchQuery); + } + void this.router.navigate(['/mydspace'], { queryParams: queryParams }); } } From f0ceb645c75d54e21f9705939caabbc920dfe118 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 10 Feb 2023 12:50:36 +0100 Subject: [PATCH 1457/2129] 99053: Passed previousSearchQuery to AdvancedWorkflowActionSelectReviewerComponent --- ...claimed-task-actions-abstract.component.ts | 16 +++++++--- ...k-action-select-reviewer.component.spec.ts | 24 ++++++++++++++- ...d-task-action-select-reviewer.component.ts | 12 +++++++- src/app/shared/testing/active-router.stub.ts | 3 +- ...w-action-select-reviewer.component.spec.ts | 29 +++++++++++++++---- ...rkflow-action-select-reviewer.component.ts | 14 ++++++--- 6 files changed, 82 insertions(+), 16 deletions(-) diff --git a/src/app/shared/mydspace-actions/claimed-task/abstract/advanced-claimed-task-actions-abstract.component.ts b/src/app/shared/mydspace-actions/claimed-task/abstract/advanced-claimed-task-actions-abstract.component.ts index 06d51d67a3b..32d9a230eb8 100644 --- a/src/app/shared/mydspace-actions/claimed-task/abstract/advanced-claimed-task-actions-abstract.component.ts +++ b/src/app/shared/mydspace-actions/claimed-task/abstract/advanced-claimed-task-actions-abstract.component.ts @@ -3,6 +3,7 @@ import { ClaimedTaskActionsAbstractComponent } from './claimed-task-actions-abst import { getFirstSucceededRemoteDataPayload } from '../../../../core/shared/operators'; import { WorkflowItem } from '../../../../core/submission/models/workflowitem.model'; import { getAdvancedWorkflowRoute } from '../../../../workflowitems-edit-page/workflowitems-edit-page-routing-paths'; +import { Params } from '@angular/router'; /** * Abstract component for rendering an advanced claimed task's action @@ -47,11 +48,18 @@ export abstract class AdvancedClaimedTaskActionsAbstractComponent extends Claime */ openAdvancedClaimedTaskTab(): void { void this.router.navigate([this.workflowTaskPageRoute], { - queryParams: { - workflow: this.workflowType, - claimedTask: this.object.id, - }, + queryParams: this.getQueryParams(), }); } + /** + * The {@link Params} that need to be given to the workflow page. + */ + getQueryParams(): Params { + return { + workflow: this.workflowType, + claimedTask: this.object.id, + }; + } + } diff --git a/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.spec.ts b/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.spec.ts index db670e3cdcb..60f47a60b8a 100644 --- a/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.spec.ts +++ b/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.spec.ts @@ -2,7 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdvancedClaimedTaskActionSelectReviewerComponent } from './advanced-claimed-task-action-select-reviewer.component'; -import { Router } from '@angular/router'; +import { Router, ActivatedRoute } from '@angular/router'; import { RouterStub } from '../../../testing/router.stub'; import { NotificationsServiceStub } from '../../../testing/notifications-service.stub'; import { NotificationsService } from '../../../notifications/notifications.service'; @@ -22,6 +22,7 @@ import { } from '../../../../workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component'; import { WorkflowItem } from '../../../../core/submission/models/workflowitem.model'; import { of as observableOf } from 'rxjs'; +import { ActivatedRouteStub } from '../../../testing/active-router.stub'; const taskId = 'claimed-task-1'; const workflowId = 'workflow-1'; @@ -36,12 +37,14 @@ describe('AdvancedClaimedTaskActionSelectReviewerComponent', () => { let component: AdvancedClaimedTaskActionSelectReviewerComponent; let fixture: ComponentFixture; + let route: ActivatedRouteStub; let claimedTaskDataService: ClaimedTaskDataServiceStub; let notificationService: NotificationsServiceStub; let router: RouterStub; let searchService: SearchServiceStub; beforeEach(async () => { + route = new ActivatedRouteStub(); claimedTaskDataService = new ClaimedTaskDataServiceStub(); notificationService = new NotificationsServiceStub(); router = new RouterStub(); @@ -56,6 +59,7 @@ describe('AdvancedClaimedTaskActionSelectReviewerComponent', () => { NgbTooltip, ], providers: [ + { provide: ActivatedRoute, useValue: route }, { provide: ClaimedTaskDataService, useValue: claimedTaskDataService }, { provide: NotificationsService, useValue: notificationService }, { provide: RequestService, useValue: {} }, @@ -95,4 +99,22 @@ describe('AdvancedClaimedTaskActionSelectReviewerComponent', () => { }, }); }); + + it('should navigate to the advanced workflow page with a previousSearchQuery when clicked anq a query is defined', () => { + spyOnProperty(route, 'snapshot').and.returnValue({ + queryParams: { + query: 'Thor%20Love%20and%20Thunder', + } + }); + component.workflowTaskPageRoute = `/workflowitems/${workflowId}/advanced`; + fixture.debugElement.query(By.css('.selectReviewerAction')).nativeElement.click(); + + expect(router.navigate).toHaveBeenCalledWith([`/workflowitems/${workflowId}/advanced`], { + queryParams: { + workflow: ADVANCED_WORKFLOW_ACTION_SELECT_REVIEWER, + claimedTask: taskId, + previousSearchQuery: 'Thor%20Love%20and%20Thunder', + }, + }); + }); }); diff --git a/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.ts b/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.ts index 7473c737d9d..2331a8bd7fb 100644 --- a/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.ts +++ b/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.ts @@ -3,7 +3,7 @@ import { rendersWorkflowTaskOption } from '../switcher/claimed-task-actions-deco import { AdvancedClaimedTaskActionsAbstractComponent } from '../abstract/advanced-claimed-task-actions-abstract.component'; -import { Router } from '@angular/router'; +import { Router, Params, ActivatedRoute } from '@angular/router'; import { NotificationsService } from '../../../notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; import { SearchService } from '../../../../core/shared/search/search.service'; @@ -12,6 +12,7 @@ import { ADVANCED_WORKFLOW_ACTION_SELECT_REVIEWER, ADVANCED_WORKFLOW_TASK_OPTION_SELECT_REVIEWER } from '../../../../workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component'; +import { hasValue } from '../../../empty.util'; /** * Advanced Workflow button that redirect to the {@link AdvancedWorkflowActionSelectReviewerComponent} @@ -38,8 +39,17 @@ export class AdvancedClaimedTaskActionSelectReviewerComponent extends AdvancedCl protected translate: TranslateService, protected searchService: SearchService, protected requestService: RequestService, + protected route: ActivatedRoute, ) { super(injector, router, notificationsService, translate, searchService, requestService); } + getQueryParams(): Params { + const params: Params = super.getQueryParams(); + if (hasValue(this.route.snapshot.queryParams.query)) { + params.previousSearchQuery = this.route.snapshot.queryParams.query; + } + return params; + } + } diff --git a/src/app/shared/testing/active-router.stub.ts b/src/app/shared/testing/active-router.stub.ts index aa4bfce438d..86d92a2fb87 100644 --- a/src/app/shared/testing/active-router.stub.ts +++ b/src/app/shared/testing/active-router.stub.ts @@ -54,7 +54,8 @@ export class ActivatedRouteStub { get snapshot() { return { params: this.testParams, - queryParamMap: convertToParamMap(this.testParams) + queryParamMap: convertToParamMap(this.testParams), + queryParams: {} as Params, }; } } diff --git a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts index 2884dbcc8e4..42d68748998 100644 --- a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts +++ b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts @@ -1,12 +1,11 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AdvancedWorkflowActionSelectReviewerComponent, - ADVANCED_WORKFLOW_TASK_OPTION_SELECT_REVIEWER + ADVANCED_WORKFLOW_TASK_OPTION_SELECT_REVIEWER, } from './advanced-workflow-action-select-reviewer.component'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { WorkflowItemDataService } from '../../../core/submission/workflowitem-data.service'; import { WorkflowItemDataServiceStub } from '../../../shared/testing/workflow-item-data-service.stub'; -import { RouterTestingModule } from '@angular/router/testing'; import { WorkflowActionDataServiceStub } from '../../../shared/testing/workflow-action-data-service.stub'; import { WorkflowActionDataService } from '../../../core/data/workflow-action-data.service'; import { RouteService } from '../../../core/services/route.service'; @@ -25,6 +24,7 @@ import { ProcessTaskResponse } from '../../../core/tasks/models/process-task-res import { NO_ERRORS_SCHEMA } from '@angular/core'; import { RequestService } from '../../../core/data/request.service'; import { RequestServiceStub } from '../../../shared/testing/request-service.stub'; +import { RouterStub } from '../../../shared/testing/router.stub'; const claimedTaskId = '2'; const workflowId = '1'; @@ -37,18 +37,19 @@ describe('AdvancedWorkflowActionSelectReviewerComponent', () => { let claimedTaskDataService: ClaimedTaskDataServiceStub; let notificationService: NotificationsServiceStub; + let router: RouterStub; let workflowActionDataService: WorkflowItemDataServiceStub; let workflowItemDataService: WorkflowItemDataServiceStub; beforeEach(async () => { claimedTaskDataService = new ClaimedTaskDataServiceStub(); notificationService = new NotificationsServiceStub(); + router = new RouterStub(); workflowActionDataService = new WorkflowActionDataServiceStub(); workflowItemDataService = new WorkflowItemDataServiceStub(); await TestBed.configureTestingModule({ imports: [ - RouterTestingModule, TranslateModule.forRoot(), ], declarations: [ @@ -66,10 +67,12 @@ describe('AdvancedWorkflowActionSelectReviewerComponent', () => { queryParams: { claimedTask: claimedTaskId, workflow: 'testaction', + previousSearchQuery: 'Thor%20Love%20and%20Thunder', }, }, }, }, + { provide: Router, useValue: router }, { provide: ClaimedTaskDataService, useValue: claimedTaskDataService }, { provide: NotificationsService, useValue: notificationService }, { provide: RouteService, useValue: routeServiceStub }, @@ -85,14 +88,30 @@ describe('AdvancedWorkflowActionSelectReviewerComponent', () => { fixture = TestBed.createComponent(AdvancedWorkflowActionSelectReviewerComponent); component = fixture.componentInstance; fixture.detectChanges(); - spyOn(component, 'previousPage'); }); afterEach(() => { fixture.debugElement.nativeElement.remove(); }); + describe('previousPage', () => { + it('should navigate back to the Workflow tasks page with the previous query', () => { + component.previousPage(); + + expect(router.navigate).toHaveBeenCalledWith(['/mydspace'], { + queryParams: { + configuration: 'workflow', + query: 'Thor Love and Thunder', + }, + }); + }); + }); + describe('performAction', () => { + beforeEach(() => { + spyOn(component, 'previousPage'); + }); + it('should call the claimedTaskDataService with the list of selected ePersons', () => { spyOn(claimedTaskDataService, 'submitTask').and.returnValue(observableOf(new ProcessTaskResponse(true))); component.selectedReviewers = [EPersonMock, EPersonMock2]; diff --git a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts index b9f90e1736a..226ddccf4c9 100644 --- a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts +++ b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts @@ -12,15 +12,15 @@ import { } from '../../../access-control/group-registry/group-form/members-list/members-list.component'; import { Subscription } from 'rxjs'; import { EPerson } from '../../../core/eperson/models/eperson.model'; -import { ActivatedRoute, Router } from '@angular/router'; +import { ActivatedRoute, Params, Router } from '@angular/router'; import { WorkflowItemDataService } from '../../../core/submission/workflowitem-data.service'; import { RouteService } from '../../../core/services/route.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; import { WorkflowActionDataService } from '../../../core/data/workflow-action-data.service'; import { ClaimedTaskDataService } from '../../../core/tasks/claimed-task-data.service'; -import { ReviewersListComponent } from './reviewers-list/reviewers-list.component'; -import { RequestService } from 'src/app/core/data/request.service'; +import { RequestService } from '../../../core/data/request.service'; +import { hasValue } from '../../../shared/empty.util'; export const ADVANCED_WORKFLOW_TASK_OPTION_SELECT_REVIEWER = 'submit_select_reviewer'; export const ADVANCED_WORKFLOW_ACTION_SELECT_REVIEWER = 'selectrevieweraction'; @@ -138,7 +138,13 @@ export class AdvancedWorkflowActionSelectReviewerComponent extends AdvancedWorkf * switching between the different pages */ previousPage(): void { - void this.router.navigate(['/mydspace'], { queryParams: { configuration: 'workflow' } }); + const queryParams: Params = { + configuration: 'workflow', + }; + if (hasValue(this.route.snapshot.queryParams.previousSearchQuery)) { + queryParams.query = decodeURIComponent(this.route.snapshot.queryParams.previousSearchQuery); + } + void this.router.navigate(['/mydspace'], { queryParams: queryParams }); } } From 356962a571663a425916397334e807fe95bbc05a Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 10 Feb 2023 15:52:51 +0100 Subject: [PATCH 1458/2129] 99053: Pass all queryParameters to advanced workflow pages by default --- ...claimed-task-actions-abstract.component.ts | 29 ++++++++++++++++--- .../claimed-task-actions.component.ts | 1 - ...aimed-task-action-rating.component.spec.ts | 6 +++- ...ed-claimed-task-action-rating.component.ts | 5 ++-- ...k-action-select-reviewer.component.spec.ts | 18 ------------ ...d-task-action-select-reviewer.component.ts | 13 ++------- src/app/shared/testing/location.stub.ts | 7 +++++ ...w-action-select-reviewer.component.spec.ts | 14 ++++++++- ...rkflow-action-select-reviewer.component.ts | 12 ++++---- 9 files changed, 62 insertions(+), 43 deletions(-) create mode 100644 src/app/shared/testing/location.stub.ts diff --git a/src/app/shared/mydspace-actions/claimed-task/abstract/advanced-claimed-task-actions-abstract.component.ts b/src/app/shared/mydspace-actions/claimed-task/abstract/advanced-claimed-task-actions-abstract.component.ts index 32d9a230eb8..cf627fc1ceb 100644 --- a/src/app/shared/mydspace-actions/claimed-task/abstract/advanced-claimed-task-actions-abstract.component.ts +++ b/src/app/shared/mydspace-actions/claimed-task/abstract/advanced-claimed-task-actions-abstract.component.ts @@ -1,9 +1,13 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, Injector } from '@angular/core'; import { ClaimedTaskActionsAbstractComponent } from './claimed-task-actions-abstract.component'; import { getFirstSucceededRemoteDataPayload } from '../../../../core/shared/operators'; import { WorkflowItem } from '../../../../core/submission/models/workflowitem.model'; import { getAdvancedWorkflowRoute } from '../../../../workflowitems-edit-page/workflowitems-edit-page-routing-paths'; -import { Params } from '@angular/router'; +import { Params, Router, ActivatedRoute, NavigationExtras } from '@angular/router'; +import { NotificationsService } from '../../../notifications/notifications.service'; +import { TranslateService } from '@ngx-translate/core'; +import { SearchService } from '../../../../core/shared/search/search.service'; +import { RequestService } from '../../../../core/data/request.service'; /** * Abstract component for rendering an advanced claimed task's action @@ -27,6 +31,18 @@ export abstract class AdvancedClaimedTaskActionsAbstractComponent extends Claime */ workflowTaskPageRoute: string; + constructor( + protected injector: Injector, + protected router: Router, + protected notificationsService: NotificationsService, + protected translate: TranslateService, + protected searchService: SearchService, + protected requestService: RequestService, + protected route: ActivatedRoute, + ) { + super(injector, router, notificationsService, translate, searchService, requestService); + } + ngOnInit(): void { super.ngOnInit(); this.initPageRoute(); @@ -47,9 +63,14 @@ export abstract class AdvancedClaimedTaskActionsAbstractComponent extends Claime * Navigates to the advanced workflow page based on the {@link workflow}. */ openAdvancedClaimedTaskTab(): void { - void this.router.navigate([this.workflowTaskPageRoute], { + const navigationExtras: NavigationExtras = { queryParams: this.getQueryParams(), - }); + }; + if (Object.keys(this.route.snapshot.queryParams).length > 0) { + navigationExtras.state = {}; + navigationExtras.state.previousQueryParams = this.route.snapshot.queryParams; + } + void this.router.navigate([this.workflowTaskPageRoute], navigationExtras); } /** diff --git a/src/app/shared/mydspace-actions/claimed-task/claimed-task-actions.component.ts b/src/app/shared/mydspace-actions/claimed-task/claimed-task-actions.component.ts index 8f4d109ba19..9f31c342798 100644 --- a/src/app/shared/mydspace-actions/claimed-task/claimed-task-actions.component.ts +++ b/src/app/shared/mydspace-actions/claimed-task/claimed-task-actions.component.ts @@ -16,7 +16,6 @@ import { RequestService } from '../../../core/data/request.service'; import { SearchService } from '../../../core/shared/search/search.service'; import { WorkflowAction } from '../../../core/tasks/models/workflow-action-object.model'; import { WorkflowActionDataService } from '../../../core/data/workflow-action-data.service'; -import { WORKFLOW_TASK_OPTION_RETURN_TO_POOL } from './return-to-pool/claimed-task-actions-return-to-pool.component'; import { getWorkflowItemViewRoute } from '../../../workflowitems-edit-page/workflowitems-edit-page-routing-paths'; /** diff --git a/src/app/shared/mydspace-actions/claimed-task/rating/advanced-claimed-task-action-rating.component.spec.ts b/src/app/shared/mydspace-actions/claimed-task/rating/advanced-claimed-task-action-rating.component.spec.ts index c192a68aa78..bb41fedfb5d 100644 --- a/src/app/shared/mydspace-actions/claimed-task/rating/advanced-claimed-task-action-rating.component.spec.ts +++ b/src/app/shared/mydspace-actions/claimed-task/rating/advanced-claimed-task-action-rating.component.spec.ts @@ -9,7 +9,7 @@ import { SearchServiceStub } from '../../../testing/search-service.stub'; import { ClaimedTaskDataService } from '../../../../core/tasks/claimed-task-data.service'; import { NotificationsService } from '../../../notifications/notifications.service'; import { RequestService } from '../../../../core/data/request.service'; -import { Router } from '@angular/router'; +import { Router, ActivatedRoute } from '@angular/router'; import { SearchService } from '../../../../core/shared/search/search.service'; import { Location } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; @@ -19,6 +19,7 @@ import { } from '../../../../workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-rating/advanced-workflow-action-rating.component'; import { of as observableOf } from 'rxjs'; import { WorkflowItem } from '../../../../core/submission/models/workflowitem.model'; +import { ActivatedRouteStub } from '../../../testing/active-router.stub'; const taskId = 'claimed-task-1'; const workflowId = 'workflow-1'; @@ -35,12 +36,14 @@ describe('AdvancedClaimedTaskActionRatingComponent', () => { let claimedTaskDataService: ClaimedTaskDataServiceStub; let notificationService: NotificationsServiceStub; + let route: ActivatedRouteStub; let router: RouterStub; let searchService: SearchServiceStub; beforeEach(async () => { claimedTaskDataService = new ClaimedTaskDataServiceStub(); notificationService = new NotificationsServiceStub(); + route = new ActivatedRouteStub(); router = new RouterStub(); searchService = new SearchServiceStub(); @@ -52,6 +55,7 @@ describe('AdvancedClaimedTaskActionRatingComponent', () => { AdvancedClaimedTaskActionRatingComponent, ], providers: [ + { provide: ActivatedRoute, useValue: route }, { provide: ClaimedTaskDataService, useValue: claimedTaskDataService }, { provide: NotificationsService, useValue: notificationService }, { provide: RequestService, useValue: {} }, diff --git a/src/app/shared/mydspace-actions/claimed-task/rating/advanced-claimed-task-action-rating.component.ts b/src/app/shared/mydspace-actions/claimed-task/rating/advanced-claimed-task-action-rating.component.ts index 8699dc702e0..a1cc81e050c 100644 --- a/src/app/shared/mydspace-actions/claimed-task/rating/advanced-claimed-task-action-rating.component.ts +++ b/src/app/shared/mydspace-actions/claimed-task/rating/advanced-claimed-task-action-rating.component.ts @@ -1,5 +1,5 @@ import { Component, Injector } from '@angular/core'; -import { Router } from '@angular/router'; +import { Router, ActivatedRoute } from '@angular/router'; import { NotificationsService } from '../../../notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; import { SearchService } from '../../../../core/shared/search/search.service'; @@ -38,8 +38,9 @@ export class AdvancedClaimedTaskActionRatingComponent extends AdvancedClaimedTas protected translate: TranslateService, protected searchService: SearchService, protected requestService: RequestService, + protected route: ActivatedRoute, ) { - super(injector, router, notificationsService, translate, searchService, requestService); + super(injector, router, notificationsService, translate, searchService, requestService, route); } } diff --git a/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.spec.ts b/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.spec.ts index 60f47a60b8a..81fe4234813 100644 --- a/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.spec.ts +++ b/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.spec.ts @@ -99,22 +99,4 @@ describe('AdvancedClaimedTaskActionSelectReviewerComponent', () => { }, }); }); - - it('should navigate to the advanced workflow page with a previousSearchQuery when clicked anq a query is defined', () => { - spyOnProperty(route, 'snapshot').and.returnValue({ - queryParams: { - query: 'Thor%20Love%20and%20Thunder', - } - }); - component.workflowTaskPageRoute = `/workflowitems/${workflowId}/advanced`; - fixture.debugElement.query(By.css('.selectReviewerAction')).nativeElement.click(); - - expect(router.navigate).toHaveBeenCalledWith([`/workflowitems/${workflowId}/advanced`], { - queryParams: { - workflow: ADVANCED_WORKFLOW_ACTION_SELECT_REVIEWER, - claimedTask: taskId, - previousSearchQuery: 'Thor%20Love%20and%20Thunder', - }, - }); - }); }); diff --git a/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.ts b/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.ts index 2331a8bd7fb..d6217320ba7 100644 --- a/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.ts +++ b/src/app/shared/mydspace-actions/claimed-task/select-reviewer/advanced-claimed-task-action-select-reviewer.component.ts @@ -3,7 +3,7 @@ import { rendersWorkflowTaskOption } from '../switcher/claimed-task-actions-deco import { AdvancedClaimedTaskActionsAbstractComponent } from '../abstract/advanced-claimed-task-actions-abstract.component'; -import { Router, Params, ActivatedRoute } from '@angular/router'; +import { Router, ActivatedRoute } from '@angular/router'; import { NotificationsService } from '../../../notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; import { SearchService } from '../../../../core/shared/search/search.service'; @@ -12,7 +12,6 @@ import { ADVANCED_WORKFLOW_ACTION_SELECT_REVIEWER, ADVANCED_WORKFLOW_TASK_OPTION_SELECT_REVIEWER } from '../../../../workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component'; -import { hasValue } from '../../../empty.util'; /** * Advanced Workflow button that redirect to the {@link AdvancedWorkflowActionSelectReviewerComponent} @@ -41,15 +40,7 @@ export class AdvancedClaimedTaskActionSelectReviewerComponent extends AdvancedCl protected requestService: RequestService, protected route: ActivatedRoute, ) { - super(injector, router, notificationsService, translate, searchService, requestService); - } - - getQueryParams(): Params { - const params: Params = super.getQueryParams(); - if (hasValue(this.route.snapshot.queryParams.query)) { - params.previousSearchQuery = this.route.snapshot.queryParams.query; - } - return params; + super(injector, router, notificationsService, translate, searchService, requestService, route); } } diff --git a/src/app/shared/testing/location.stub.ts b/src/app/shared/testing/location.stub.ts new file mode 100644 index 00000000000..7e130c4de20 --- /dev/null +++ b/src/app/shared/testing/location.stub.ts @@ -0,0 +1,7 @@ +export class LocationStub { + + getState(): unknown { + return {}; + } + +} diff --git a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts index 42d68748998..cf2be8e0b8e 100644 --- a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts +++ b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts @@ -1,4 +1,5 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Location } from '@angular/common'; import { AdvancedWorkflowActionSelectReviewerComponent, ADVANCED_WORKFLOW_TASK_OPTION_SELECT_REVIEWER, @@ -25,6 +26,7 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { RequestService } from '../../../core/data/request.service'; import { RequestServiceStub } from '../../../shared/testing/request-service.stub'; import { RouterStub } from '../../../shared/testing/router.stub'; +import { LocationStub } from '../../../shared/testing/location.stub'; const claimedTaskId = '2'; const workflowId = '1'; @@ -36,6 +38,7 @@ describe('AdvancedWorkflowActionSelectReviewerComponent', () => { let fixture: ComponentFixture; let claimedTaskDataService: ClaimedTaskDataServiceStub; + let location: LocationStub; let notificationService: NotificationsServiceStub; let router: RouterStub; let workflowActionDataService: WorkflowItemDataServiceStub; @@ -43,6 +46,7 @@ describe('AdvancedWorkflowActionSelectReviewerComponent', () => { beforeEach(async () => { claimedTaskDataService = new ClaimedTaskDataServiceStub(); + location = new LocationStub(); notificationService = new NotificationsServiceStub(); router = new RouterStub(); workflowActionDataService = new WorkflowActionDataServiceStub(); @@ -72,9 +76,10 @@ describe('AdvancedWorkflowActionSelectReviewerComponent', () => { }, }, }, - { provide: Router, useValue: router }, { provide: ClaimedTaskDataService, useValue: claimedTaskDataService }, + { provide: Location, useValue: location }, { provide: NotificationsService, useValue: notificationService }, + { provide: Router, useValue: router }, { provide: RouteService, useValue: routeServiceStub }, { provide: WorkflowActionDataService, useValue: workflowActionDataService }, { provide: WorkflowItemDataService, useValue: workflowItemDataService }, @@ -96,6 +101,13 @@ describe('AdvancedWorkflowActionSelectReviewerComponent', () => { describe('previousPage', () => { it('should navigate back to the Workflow tasks page with the previous query', () => { + spyOn(location, 'getState').and.returnValue({ + previousQueryParams: { + configuration: 'workflow', + query: 'Thor Love and Thunder', + }, + }); + component.previousPage(); expect(router.navigate).toHaveBeenCalledWith(['/mydspace'], { diff --git a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts index 226ddccf4c9..5d8ece8c01a 100644 --- a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts +++ b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Location } from '@angular/common'; import { rendersAdvancedWorkflowTaskOption } from '../../../shared/mydspace-actions/claimed-task/switcher/claimed-task-actions-decorator'; @@ -62,6 +63,7 @@ export class AdvancedWorkflowActionSelectReviewerComponent extends AdvancedWorkf protected workflowActionService: WorkflowActionDataService, protected claimedTaskDataService: ClaimedTaskDataService, protected requestService: RequestService, + protected location: Location, ) { super(route, workflowItemService, router, routeService, notificationsService, translationService, workflowActionService, claimedTaskDataService, requestService); } @@ -138,11 +140,11 @@ export class AdvancedWorkflowActionSelectReviewerComponent extends AdvancedWorkf * switching between the different pages */ previousPage(): void { - const queryParams: Params = { - configuration: 'workflow', - }; - if (hasValue(this.route.snapshot.queryParams.previousSearchQuery)) { - queryParams.query = decodeURIComponent(this.route.snapshot.queryParams.previousSearchQuery); + let queryParams: Params = (this.location.getState() as { [key: string]: any }).previousQueryParams; + if (!hasValue(queryParams)) { + queryParams = { + configuration: 'workflow', + }; } void this.router.navigate(['/mydspace'], { queryParams: queryParams }); } From dce84dbe70d4ea200a3c38576008792e013b165f Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 10 Feb 2023 16:39:27 +0100 Subject: [PATCH 1459/2129] 99053: Save queryParams in init to prevent them being overwritten --- .../advanced-workflow-action-rating.component.spec.ts | 3 +++ ...anced-workflow-action-select-reviewer.component.spec.ts | 1 + .../advanced-workflow-action-select-reviewer.component.ts | 4 ++-- .../advanced-workflow-action.component.spec.ts | 6 +++++- .../advanced-workflow-action.component.ts | 4 +++- .../workflow-item-action-page.component.spec.ts | 6 +++++- .../workflow-item-action-page.component.ts | 7 ++++++- .../workflow-item-delete.component.spec.ts | 4 +++- .../workflow-item-delete/workflow-item-delete.component.ts | 7 +++++-- .../workflow-item-send-back.component.spec.ts | 4 +++- .../workflow-item-send-back.component.ts | 7 +++++-- 11 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-rating/advanced-workflow-action-rating.component.spec.ts b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-rating/advanced-workflow-action-rating.component.spec.ts index 8fe495c617e..d6d6f973c44 100644 --- a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-rating/advanced-workflow-action-rating.component.spec.ts +++ b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-rating/advanced-workflow-action-rating.component.spec.ts @@ -1,4 +1,5 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Location } from '@angular/common'; import { AdvancedWorkflowActionRatingComponent, ADVANCED_WORKFLOW_TASK_OPTION_RATING @@ -28,6 +29,7 @@ import { ProcessTaskResponse } from '../../../core/tasks/models/process-task-res import { RatingAdvancedWorkflowInfo } from '../../../core/tasks/models/rating-advanced-workflow-info.model'; import { RequestService } from '../../../core/data/request.service'; import { RequestServiceStub } from '../../../shared/testing/request-service.stub'; +import { LocationStub } from '../../../shared/testing/location.stub'; const claimedTaskId = '2'; const workflowId = '1'; @@ -77,6 +79,7 @@ describe('AdvancedWorkflowActionRatingComponent', () => { }, }, { provide: ClaimedTaskDataService, useValue: claimedTaskDataService }, + { provide: Location, useValue: new LocationStub() }, { provide: NotificationsService, useValue: notificationService }, { provide: RouteService, useValue: routeServiceStub }, { provide: Router, useValue: new RouterStub() }, diff --git a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts index cf2be8e0b8e..71952ce9c70 100644 --- a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts +++ b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.spec.ts @@ -108,6 +108,7 @@ describe('AdvancedWorkflowActionSelectReviewerComponent', () => { }, }); + component.ngOnInit(); component.previousPage(); expect(router.navigate).toHaveBeenCalledWith(['/mydspace'], { diff --git a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts index 5d8ece8c01a..329af733510 100644 --- a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts +++ b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action-select-reviewer/advanced-workflow-action-select-reviewer.component.ts @@ -65,7 +65,7 @@ export class AdvancedWorkflowActionSelectReviewerComponent extends AdvancedWorkf protected requestService: RequestService, protected location: Location, ) { - super(route, workflowItemService, router, routeService, notificationsService, translationService, workflowActionService, claimedTaskDataService, requestService); + super(route, workflowItemService, router, routeService, notificationsService, translationService, workflowActionService, claimedTaskDataService, requestService, location); } ngOnDestroy(): void { @@ -140,7 +140,7 @@ export class AdvancedWorkflowActionSelectReviewerComponent extends AdvancedWorkf * switching between the different pages */ previousPage(): void { - let queryParams: Params = (this.location.getState() as { [key: string]: any }).previousQueryParams; + let queryParams: Params = this.previousQueryParameters; if (!hasValue(queryParams)) { queryParams = { configuration: 'workflow', diff --git a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action/advanced-workflow-action.component.spec.ts b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action/advanced-workflow-action.component.spec.ts index f57adcb05ff..f6dfbf627f1 100644 --- a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action/advanced-workflow-action.component.spec.ts +++ b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action/advanced-workflow-action.component.spec.ts @@ -1,4 +1,5 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { Location } from '@angular/common'; import { AdvancedWorkflowActionComponent } from './advanced-workflow-action.component'; import { Component } from '@angular/core'; import { MockComponent } from 'ng-mocks'; @@ -20,6 +21,7 @@ import { ProcessTaskResponse } from '../../../core/tasks/models/process-task-res import { WorkflowItemDataServiceStub } from '../../../shared/testing/workflow-item-data-service.stub'; import { RequestService } from '../../../core/data/request.service'; import { RequestServiceStub } from '../../../shared/testing/request-service.stub'; +import { LocationStub } from '../../../shared/testing/location.stub'; const workflowId = '1'; @@ -28,17 +30,18 @@ describe('AdvancedWorkflowActionComponent', () => { let fixture: ComponentFixture; let claimedTaskDataService: ClaimedTaskDataServiceStub; + let location: LocationStub; let notificationService: NotificationsServiceStub; let workflowActionDataService: WorkflowActionDataServiceStub; let workflowItemDataService: WorkflowItemDataServiceStub; beforeEach(async () => { claimedTaskDataService = new ClaimedTaskDataServiceStub(); + location = new LocationStub(); notificationService = new NotificationsServiceStub(); workflowActionDataService = new WorkflowActionDataServiceStub(); workflowItemDataService = new WorkflowItemDataServiceStub(); - await TestBed.configureTestingModule({ imports: [ TranslateModule.forRoot(), @@ -63,6 +66,7 @@ describe('AdvancedWorkflowActionComponent', () => { }, }, { provide: ClaimedTaskDataService, useValue: claimedTaskDataService }, + { provide: Location, useValue: location }, { provide: NotificationsService, useValue: notificationService }, { provide: RouteService, useValue: routeServiceStub }, { provide: WorkflowActionDataService, useValue: workflowActionDataService }, diff --git a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action/advanced-workflow-action.component.ts b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action/advanced-workflow-action.component.ts index 5621e565782..73fd6dc63ed 100644 --- a/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action/advanced-workflow-action.component.ts +++ b/src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-action/advanced-workflow-action.component.ts @@ -13,6 +13,7 @@ import { ClaimedTaskDataService } from '../../../core/tasks/claimed-task-data.se import { map } from 'rxjs/operators'; import { ProcessTaskResponse } from '../../../core/tasks/models/process-task-response'; import { RequestService } from '../../../core/data/request.service'; +import { Location } from '@angular/common'; /** * Abstract component for rendering an advanced claimed task's workflow page @@ -38,8 +39,9 @@ export abstract class AdvancedWorkflowActionComponent extends WorkflowItemAction protected workflowActionService: WorkflowActionDataService, protected claimedTaskDataService: ClaimedTaskDataService, protected requestService: RequestService, + protected location: Location, ) { - super(route, workflowItemService, router, routeService, notificationsService, translationService, requestService); + super(route, workflowItemService, router, routeService, notificationsService, translationService, requestService, location); } ngOnInit(): void { diff --git a/src/app/workflowitems-edit-page/workflow-item-action-page.component.spec.ts b/src/app/workflowitems-edit-page/workflow-item-action-page.component.spec.ts index 11f88788dc8..c4dea0f30cf 100644 --- a/src/app/workflowitems-edit-page/workflow-item-action-page.component.spec.ts +++ b/src/app/workflowitems-edit-page/workflow-item-action-page.component.spec.ts @@ -18,6 +18,8 @@ import { RouterStub } from '../shared/testing/router.stub'; import { NotificationsServiceStub } from '../shared/testing/notifications-service.stub'; import { RequestService } from '../core/data/request.service'; import { RequestServiceStub } from '../shared/testing/request-service.stub'; +import { Location } from '@angular/common'; +import { LocationStub } from '../shared/testing/location.stub'; const type = 'testType'; describe('WorkflowItemActionPageComponent', () => { @@ -52,6 +54,7 @@ describe('WorkflowItemActionPageComponent', () => { { provide: ActivatedRoute, useValue: new ActivatedRouteStub({}, { wfi: createSuccessfulRemoteDataObject(wfi) }) }, { provide: Router, useClass: RouterStub }, { provide: RouteService, useValue: {} }, + { provide: Location, useValue: new LocationStub() }, { provide: NotificationsService, useClass: NotificationsServiceStub }, { provide: WorkflowItemDataService, useValue: wfiService }, { provide: RequestService, useClass: RequestServiceStub }, @@ -115,8 +118,9 @@ class TestComponent extends WorkflowItemActionPageComponent { protected notificationsService: NotificationsService, protected translationService: TranslateService, protected requestService: RequestService, + protected location: Location, ) { - super(route, workflowItemService, router, routeService, notificationsService, translationService, requestService); + super(route, workflowItemService, router, routeService, notificationsService, translationService, requestService, location); } getType(): string { diff --git a/src/app/workflowitems-edit-page/workflow-item-action-page.component.ts b/src/app/workflowitems-edit-page/workflow-item-action-page.component.ts index 276b2054fe4..b8998a6dd72 100644 --- a/src/app/workflowitems-edit-page/workflow-item-action-page.component.ts +++ b/src/app/workflowitems-edit-page/workflow-item-action-page.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit } from '@angular/core'; +import { Location } from '@angular/common'; import { Observable, forkJoin } from 'rxjs'; import { map, switchMap, take } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; @@ -24,6 +25,7 @@ export abstract class WorkflowItemActionPageComponent implements OnInit { public type; public wfi$: Observable; public item$: Observable; + protected previousQueryParameters?: Params; constructor(protected route: ActivatedRoute, protected workflowItemService: WorkflowItemDataService, @@ -32,6 +34,7 @@ export abstract class WorkflowItemActionPageComponent implements OnInit { protected notificationsService: NotificationsService, protected translationService: TranslateService, protected requestService: RequestService, + protected location: Location, ) { } @@ -42,6 +45,7 @@ export abstract class WorkflowItemActionPageComponent implements OnInit { this.type = this.getType(); this.wfi$ = this.route.data.pipe(map((data: Data) => data.wfi as RemoteData), getRemoteDataPayload()); this.item$ = this.wfi$.pipe(switchMap((wfi: WorkflowItem) => (wfi.item as Observable>).pipe(getAllSucceededRemoteData(), getRemoteDataPayload()))); + this.previousQueryParameters = (this.location.getState() as { [key: string]: any }).previousQueryParams; } /** @@ -72,10 +76,11 @@ export abstract class WorkflowItemActionPageComponent implements OnInit { previousPage() { this.routeService.getPreviousUrl().pipe(take(1)) .subscribe((url) => { + let params: Params = {}; if (isEmpty(url)) { url = '/mydspace'; + params = this.previousQueryParameters; } - const params: Params = {}; if (url.split('?').length > 1) { for (const param of url.split('?')[1].split('&')) { params[param.split('=')[0]] = decodeURIComponent(param.split('=')[1]); diff --git a/src/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.spec.ts b/src/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.spec.ts index a4e8f7d849f..89a7029b4a1 100644 --- a/src/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.spec.ts +++ b/src/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.spec.ts @@ -1,5 +1,5 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; - +import { Location } from '@angular/common'; import { WorkflowItemDeleteComponent } from './workflow-item-delete.component'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { ActivatedRoute, Router } from '@angular/router'; @@ -17,6 +17,7 @@ import { ActivatedRouteStub } from '../../shared/testing/active-router.stub'; import { RouterStub } from '../../shared/testing/router.stub'; import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; +import { LocationStub } from '../../shared/testing/location.stub'; describe('WorkflowItemDeleteComponent', () => { let component: WorkflowItemDeleteComponent; @@ -50,6 +51,7 @@ describe('WorkflowItemDeleteComponent', () => { { provide: ActivatedRoute, useValue: new ActivatedRouteStub({}, { wfi: createSuccessfulRemoteDataObject(wfi) }) }, { provide: Router, useClass: RouterStub }, { provide: RouteService, useValue: {} }, + { provide: Location, useValue: new LocationStub() }, { provide: NotificationsService, useClass: NotificationsServiceStub }, { provide: WorkflowItemDataService, useValue: wfiService }, { provide: RequestService, useValue: getMockRequestService() }, diff --git a/src/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts b/src/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts index faa2bf543a8..011398369db 100644 --- a/src/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts +++ b/src/app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component.ts @@ -11,6 +11,7 @@ import { map } from 'rxjs/operators'; import { RemoteData } from '../../core/data/remote-data'; import { NoContent } from '../../core/shared/NoContent.model'; import { getFirstCompletedRemoteData } from '../../core/shared/operators'; +import { Location } from '@angular/common'; @Component({ selector: 'ds-workflow-item-delete', @@ -26,8 +27,10 @@ export class WorkflowItemDeleteComponent extends WorkflowItemActionPageComponent protected routeService: RouteService, protected notificationsService: NotificationsService, protected translationService: TranslateService, - protected requestService: RequestService) { - super(route, workflowItemService, router, routeService, notificationsService, translationService, requestService); + protected requestService: RequestService, + protected location: Location, + ) { + super(route, workflowItemService, router, routeService, notificationsService, translationService, requestService, location); } /** diff --git a/src/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.spec.ts b/src/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.spec.ts index d9dde8244c2..1196e05593d 100644 --- a/src/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.spec.ts +++ b/src/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.spec.ts @@ -1,5 +1,5 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; - +import { Location } from '@angular/common'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { ActivatedRoute, Router } from '@angular/router'; import { RouteService } from '../../core/services/route.service'; @@ -17,6 +17,7 @@ import { RouterStub } from '../../shared/testing/router.stub'; import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub'; import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; import { getMockRequestService } from '../../shared/mocks/request.service.mock'; +import { LocationStub } from '../../shared/testing/location.stub'; describe('WorkflowItemSendBackComponent', () => { let component: WorkflowItemSendBackComponent; @@ -50,6 +51,7 @@ describe('WorkflowItemSendBackComponent', () => { { provide: ActivatedRoute, useValue: new ActivatedRouteStub({}, { wfi: createSuccessfulRemoteDataObject(wfi) }) }, { provide: Router, useClass: RouterStub }, { provide: RouteService, useValue: {} }, + { provide: Location, useValue: new LocationStub() }, { provide: NotificationsService, useClass: NotificationsServiceStub }, { provide: WorkflowItemDataService, useValue: wfiService }, { provide: RequestService, useValue: getMockRequestService() }, diff --git a/src/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts b/src/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts index 432b417f432..a3c03bcfb1f 100644 --- a/src/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts +++ b/src/app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component.ts @@ -7,6 +7,7 @@ import { RouteService } from '../../core/services/route.service'; import { NotificationsService } from '../../shared/notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; import { RequestService } from '../../core/data/request.service'; +import { Location } from '@angular/common'; @Component({ selector: 'ds-workflow-item-send-back', @@ -22,8 +23,10 @@ export class WorkflowItemSendBackComponent extends WorkflowItemActionPageCompone protected routeService: RouteService, protected notificationsService: NotificationsService, protected translationService: TranslateService, - protected requestService: RequestService) { - super(route, workflowItemService, router, routeService, notificationsService, translationService, requestService); + protected requestService: RequestService, + protected location: Location, + ) { + super(route, workflowItemService, router, routeService, notificationsService, translationService, requestService, location); } /** From 1d69e1581adbffd53b01b1c7342669b383273242 Mon Sep 17 00:00:00 2001 From: Alexandre Vryghem Date: Fri, 10 Feb 2023 17:45:59 +0100 Subject: [PATCH 1460/2129] 97755: Call spy before component is created --- src/app/admin/admin-sidebar/admin-sidebar.component.spec.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/app/admin/admin-sidebar/admin-sidebar.component.spec.ts b/src/app/admin/admin-sidebar/admin-sidebar.component.spec.ts index 65026c1504c..fe8e4187d33 100644 --- a/src/app/admin/admin-sidebar/admin-sidebar.component.spec.ts +++ b/src/app/admin/admin-sidebar/admin-sidebar.component.spec.ts @@ -55,6 +55,7 @@ describe('AdminSidebarComponent', () => { isAuthorized: observableOf(true) }); scriptService = jasmine.createSpyObj('scriptService', { scriptWithNameExistsAndCanExecute: observableOf(true) }); + spyOn(menuService, 'addSection').and.callThrough(); TestBed.configureTestingModule({ imports: [TranslateModule.forRoot(), NoopAnimationsModule, RouterTestingModule], declarations: [AdminSidebarComponent], @@ -184,10 +185,6 @@ describe('AdminSidebarComponent', () => { }); describe('menu', () => { - beforeEach(() => { - spyOn(menuService, 'addSection'); - }); - describe('for regular user', () => { beforeEach(() => { authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake(() => { From 8ddcd42d04f9a6afa0c84c2bc8576f9cd3588e51 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Feb 2023 18:14:15 +0000 Subject: [PATCH 1461/2129] Bump http-cache-semantics from 4.1.0 to 4.1.1 Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/kornelski/http-cache-semantics/releases) - [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1) --- updated-dependencies: - dependency-name: http-cache-semantics dependency-type: indirect ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3843ac4dabd..2fd4fa3bc8b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6140,9 +6140,9 @@ htmlparser2@^6.0.0, htmlparser2@^6.1.0: entities "^2.0.0" http-cache-semantics@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== http-deceiver@^1.2.7: version "1.2.7" From d82526af8abd4d5c6be501fa045f509326015e8b Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Fri, 10 Feb 2023 19:47:20 +0100 Subject: [PATCH 1462/2129] [CST-7755] WIP refactoring --- ...admin-workflow-list-element.component.html | 6 +- ...t-admin-workflow-list-element.component.ts | 127 ++++++++++++++++-- .../models/submission-object.model.ts | 4 +- ...table-object-component-loader.component.ts | 14 +- .../abstract-listable-element.component.ts | 5 + .../item/item-list-element.component.html | 2 +- .../object-list/object-list.component.html | 7 +- .../object-list/object-list.component.ts | 5 + ...-search-result-list-element.component.html | 37 ++--- ...em-search-result-list-element.component.ts | 14 +- .../supervision-order-status.component.html | 13 ++ .../supervision-order-status.component.scss | 0 ...supervision-order-status.component.spec.ts | 25 ++++ .../supervision-order-status.component.ts | 88 ++++++++++++ src/app/shared/shared.module.ts | 42 +++--- src/assets/i18n/en.json5 | 16 +-- 16 files changed, 330 insertions(+), 75 deletions(-) create mode 100644 src/app/shared/object-list/supervision-order-status/supervision-order-status.component.html create mode 100644 src/app/shared/object-list/supervision-order-status/supervision-order-status.component.scss create mode 100644 src/app/shared/object-list/supervision-order-status/supervision-order-status.component.spec.ts create mode 100644 src/app/shared/object-list/supervision-order-status/supervision-order-status.component.ts diff --git a/src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-search-result-admin-workflow-list-element.component.html b/src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-search-result-admin-workflow-list-element.component.html index 32ba7b9cc8f..8963db01bd0 100644 --- a/src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-search-result-admin-workflow-list-element.component.html +++ b/src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-search-result-admin-workflow-list-element.component.html @@ -6,9 +6,13 @@
+
+ +
+ diff --git a/src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-search-result-admin-workflow-list-element.component.ts b/src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-search-result-admin-workflow-list-element.component.ts index ee6cb16bbe2..c57d918126e 100644 --- a/src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-search-result-admin-workflow-list-element.component.ts +++ b/src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-list-element/workflow-item/workflow-item-search-result-admin-workflow-list-element.component.ts @@ -1,21 +1,46 @@ import { Component, Inject, OnInit } from '@angular/core'; + +import { BehaviorSubject, Observable } from 'rxjs'; +import { map, mergeMap, take, tap } from 'rxjs/operators'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { TranslateService } from '@ngx-translate/core'; + import { ViewMode } from '../../../../../core/shared/view-mode.model'; -import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; +import { + listableObjectComponent +} from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator'; import { Context } from '../../../../../core/shared/context.model'; import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model'; -import { Observable } from 'rxjs'; import { LinkService } from '../../../../../core/cache/builders/link.service'; import { followLink } from '../../../../../shared/utils/follow-link-config.model'; import { RemoteData } from '../../../../../core/data/remote-data'; -import { getAllSucceededRemoteData, getRemoteDataPayload } from '../../../../../core/shared/operators'; +import { + getAllSucceededRemoteData, + getFirstCompletedRemoteData, + getRemoteDataPayload +} from '../../../../../core/shared/operators'; import { Item } from '../../../../../core/shared/item.model'; -import { SearchResultListElementComponent } from '../../../../../shared/object-list/search-result-list-element/search-result-list-element.component'; +import { + SearchResultListElementComponent +} from '../../../../../shared/object-list/search-result-list-element/search-result-list-element.component'; import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service'; -import { WorkflowItemSearchResult } from '../../../../../shared/object-collection/shared/workflow-item-search-result.model'; +import { + WorkflowItemSearchResult +} from '../../../../../shared/object-collection/shared/workflow-item-search-result.model'; import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service'; import { APP_CONFIG, AppConfig } from '../../../../../../config/app-config.interface'; -import { WorkspaceItemSearchResult } from '../../../../../shared/object-collection/shared/workspace-item-search-result.model'; +import { + WorkspaceItemSearchResult +} from '../../../../../shared/object-collection/shared/workspace-item-search-result.model'; import { SupervisionOrder } from '../../../../../core/supervision-order/models/supervision-order.model'; +import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; +import { PaginatedList } from '../../../../../core/data/paginated-list.model'; +import { ConfirmationModalComponent } from '../../../../../shared/confirmation-modal/confirmation-modal.component'; +import { hasValue } from '../../../../../shared/empty.util'; +import { + SupervisionOrderListEntry +} from '../../../../../shared/object-list/supervision-order-status/supervision-order-status.component'; +import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; @listableObjectComponent(WorkflowItemSearchResult, ViewMode.ListElement, Context.AdminWorkflowSearch) @listableObjectComponent(WorkspaceItemSearchResult, ViewMode.ListElement, Context.AdminWorkflowSearch) @@ -25,7 +50,7 @@ import { SupervisionOrder } from '../../../../../core/supervision-order/models/s templateUrl: './workflow-item-search-result-admin-workflow-list-element.component.html' }) /** - * The component for displaying a list element for an workflow item on the admin workflow search page + * The component for displaying a list element for a workflow item on the admin workflow search page */ export class WorkflowItemSearchResultAdminWorkflowListElementComponent extends SearchResultListElementComponent implements OnInit { @@ -34,14 +59,25 @@ export class WorkflowItemSearchResultAdminWorkflowListElementComponent extends S */ public item$: Observable; + /** + * The id of the item linked to the workflow item + */ + public itemId: string; + /** * The supervision orders linked to the workflow item */ - public supervisionOrder$: Observable; + public supervisionOrder$: BehaviorSubject = new BehaviorSubject([]); + + private messagePrefix = 'workflow-item.search.result'; constructor(private linkService: LinkService, - protected truncatableService: TruncatableService, protected dsoNameService: DSONameService, + protected modalService: NgbModal, + protected notificationsService: NotificationsService, + protected supervisionOrderDataService: SupervisionOrderDataService, + protected translateService: TranslateService, + protected truncatableService: TruncatableService, @Inject(APP_CONFIG) protected appConfig: AppConfig ) { super(truncatableService, dsoNameService, appConfig); @@ -53,7 +89,78 @@ export class WorkflowItemSearchResultAdminWorkflowListElementComponent extends S ngOnInit(): void { super.ngOnInit(); this.dso = this.linkService.resolveLink(this.dso, followLink('item')); - this.supervisionOrder$ = (this.dso.supervisionOrders as Observable>)?.pipe(getAllSucceededRemoteData(), getRemoteDataPayload()); this.item$ = (this.dso.item as Observable>).pipe(getAllSucceededRemoteData(), getRemoteDataPayload()); + + this.item$.pipe( + take(1), + tap((item: Item) => this.itemId = item.id), + mergeMap((item: Item) => this.retrieveSupervisorOrders(item.id)) + ).subscribe((supervisionOrderList: SupervisionOrder[]) => { + this.supervisionOrder$.next(supervisionOrderList); + }) + } + + /** + * Deletes the Group from the Repository. The Group will be the only that this form is showing. + * It'll either show a success or error message depending on whether the delete was successful or not. + */ + deleteSupervisionOrder(supervisionOrderEntry: SupervisionOrderListEntry) { + const modalRef = this.modalService.open(ConfirmationModalComponent); + modalRef.componentInstance.dso = supervisionOrderEntry.group; + modalRef.componentInstance.headerLabel = this.messagePrefix + '.delete-supervision.modal.header'; + modalRef.componentInstance.infoLabel = this.messagePrefix + '.delete-supervision.modal.info'; + modalRef.componentInstance.cancelLabel = this.messagePrefix + '.delete-supervision.modal.cancel'; + modalRef.componentInstance.confirmLabel = this.messagePrefix + '.delete-supervision.modal.confirm'; + modalRef.componentInstance.brandColor = 'danger'; + modalRef.componentInstance.confirmIcon = 'fas fa-trash'; + modalRef.componentInstance.response.pipe( + take(1), + mergeMap((confirm: boolean) => { + if (confirm && hasValue(supervisionOrderEntry.supervisionOrder.id)) { + return this.supervisionOrderDataService.delete(supervisionOrderEntry.supervisionOrder.id).pipe( + take(1), + tap((result: boolean) => { + if (result) { + this.notificationsService.success( + null, + this.translateService.get( + this.messagePrefix + '.notification.deleted.success', + { name: this.dsoNameService.getName(supervisionOrderEntry.group) } + ) + ); + } else { + this.notificationsService.error( + null, + this.translateService.get( + this.messagePrefix + '.notification.deleted.failure', + { name: this.dsoNameService.getName(supervisionOrderEntry.group) } + ) + ); + } + }), + mergeMap((result: boolean) => result ? this.retrieveSupervisorOrders(this.itemId) : this.supervisionOrder$.asObservable()) + ) + } else { + return this.supervisionOrder$.asObservable() + } + }) + ).subscribe((supervisionOrderList: SupervisionOrder[]) => { + this.supervisionOrder$.next(supervisionOrderList) + }) + } + + /** + * Retrieve the list of SupervisionOrder object related to the given item + * + * @param itemId + * @private + */ + private retrieveSupervisorOrders(itemId): Observable { + return this.supervisionOrderDataService.searchByItem( + itemId, false, true, followLink('group') + ).pipe( + getFirstCompletedRemoteData(), + map((soRD: RemoteData>) => soRD.hasSucceeded && !soRD.hasNoContent ? soRD.payload.page : []) + ); } } diff --git a/src/app/core/submission/models/submission-object.model.ts b/src/app/core/submission/models/submission-object.model.ts index 3d373d25229..e2d1a4396bb 100644 --- a/src/app/core/submission/models/submission-object.model.ts +++ b/src/app/core/submission/models/submission-object.model.ts @@ -15,6 +15,8 @@ import { excludeFromEquals } from '../../utilities/equals.decorators'; import { WorkspaceitemSectionsObject } from './workspaceitem-sections.model'; import { CacheableObject } from '../../cache/cacheable-object.model'; import { SUPERVISION_ORDER } from '../../supervision-order/models/supervision-order.resource-type'; +import { PaginatedList } from '../../data/paginated-list.model'; +import { SupervisionOrder } from '../../supervision-order/models/supervision-order.model'; export interface SubmissionObjectError { message: string; @@ -101,6 +103,6 @@ export abstract class SubmissionObject extends DSpaceObject implements Cacheable */ @link(SUPERVISION_ORDER) /* This was changed from 'Observable> | WorkspaceItem' to 'any' to prevent issues in templates with async */ - supervisionOrders?: any; + supervisionOrders?: Observable>>; } diff --git a/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts b/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts index 9779ecd830b..59ce71ff6cd 100644 --- a/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts +++ b/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts @@ -13,7 +13,7 @@ import { ViewChild } from '@angular/core'; -import { Observable, Subscription } from 'rxjs'; +import { Subscription } from 'rxjs'; import { take } from 'rxjs/operators'; import { ListableObject } from '../listable-object.model'; @@ -41,11 +41,6 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnChanges */ @Input() object: ListableObject; - /** - * The supervision order to determine supervision orders - */ - @Input() supervisionOrders: Observable; - /** * The index of the object in the list */ @@ -76,6 +71,11 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnChanges */ @Input() showLabel = true; + /** + * Whether to show the supervision orders badges or not + */ + @Input() showSupervisionOrderBadges = false; + /** * The value to display for this element */ @@ -128,7 +128,7 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnChanges */ protected inAndOutputNames: string[] = [ 'object', - 'supervisionOrders', + 'showSupervisionOrderBadges', 'index', 'linkType', 'listID', diff --git a/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts b/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts index dde9cf61dce..f292ac5b76f 100644 --- a/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts +++ b/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts @@ -46,6 +46,11 @@ export class AbstractListableElementComponent { */ @Input() showLabel = true; + /** + * Whether to show the supervision orders badges or not + */ + @Input() showSupervisionOrderBadges = false; + /** * The context we matched on to get this component */ diff --git a/src/app/shared/object-list/item-list-element/item-types/item/item-list-element.component.html b/src/app/shared/object-list/item-list-element/item-types/item/item-list-element.component.html index f244da97bd1..4bf45e7f3b6 100644 --- a/src/app/shared/object-list/item-list-element/item-types/item/item-list-element.component.html +++ b/src/app/shared/object-list/item-list-element/item-types/item/item-list-element.component.html @@ -1 +1 @@ - + diff --git a/src/app/shared/object-list/object-list.component.html b/src/app/shared/object-list/object-list.component.html index 863d328a693..a0ef3e1cb9f 100644 --- a/src/app/shared/object-list/object-list.component.html +++ b/src/app/shared/object-list/object-list.component.html @@ -25,8 +25,13 @@ - diff --git a/src/app/shared/object-list/object-list.component.ts b/src/app/shared/object-list/object-list.component.ts index 65e2b508daa..9d064115e63 100644 --- a/src/app/shared/object-list/object-list.component.ts +++ b/src/app/shared/object-list/object-list.component.ts @@ -81,6 +81,11 @@ export class ObjectListComponent { */ @Input() showPaginator = true; + /** + * Whether to show the supervision orders badges or not + */ + @Input() showSupervisionOrderBadges = false; + /** * Emit when one of the listed object has changed. */ diff --git a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.html b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.html index 64108681f62..bf1d51bfc26 100644 --- a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.html +++ b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.html @@ -23,37 +23,24 @@ - - - ( - ) - - - - - ; + + + ( + ) + + + + + ; + - - - + +
- -
-
- {{'item.search.result.list.element.supervised-by' | translate}} -
-
- - {{supervisionOrder.group._name}} - X - -
-
-
diff --git a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts index 2fa72d2ac09..7ed96fdc68f 100644 --- a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts +++ b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts @@ -1,5 +1,7 @@ import { Component, Inject } from '@angular/core'; -import { listableObjectComponent } from '../../../../../object-collection/shared/listable-object/listable-object.decorator'; +import { + listableObjectComponent +} from '../../../../../object-collection/shared/listable-object/listable-object.decorator'; import { ViewMode } from '../../../../../../core/shared/view-mode.model'; import { ItemSearchResult } from '../../../../../object-collection/shared/item-search-result.model'; import { SearchResultListElementComponent } from '../../../search-result-list-element.component'; @@ -8,7 +10,7 @@ import { getItemPageRoute } from '../../../../../../item-page/item-page-routing- import { SupervisionOrderDataService } from '../../../../../../core/supervision-order/supervision-order-data.service'; import { TruncatableService } from '../../../../../../shared/truncatable/truncatable.service'; import { DSONameService } from '../../../../../../core/breadcrumbs/dso-name.service'; -import { AppConfig, APP_CONFIG } from '../../../../../../../config/app-config.interface'; +import { APP_CONFIG, AppConfig } from '../../../../../../../config/app-config.interface'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { combineLatest, filter, map, Observable, switchMap, take } from 'rxjs'; import { ConfirmationModalComponent } from '../../../../../../shared/confirmation-modal/confirmation-modal.component'; @@ -16,11 +18,15 @@ import { hasValue } from '../../../../../../shared/empty.util'; import { NotificationsService } from '../../../../../../shared/notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; import { followLink } from '../../../../../../shared/utils/follow-link-config.model'; -import { getAllSucceededRemoteListPayload, getFirstSucceededRemoteDataPayload } from '../../../../../../core/shared/operators'; +import { + getAllSucceededRemoteData, + getAllSucceededRemoteListPayload, + getFirstSucceededRemoteDataPayload, + getRemoteDataPayload +} from '../../../../../../core/shared/operators'; import { SupervisionOrder } from '../../../../../../core/supervision-order/models/supervision-order.model'; import { Group } from '../../../../../../core/eperson/models/group.model'; import { ResourcePolicyDataService } from '../../../../../../core/resource-policy/resource-policy-data.service'; -import { getAllSucceededRemoteData, getRemoteDataPayload } from '../../../../../../core/shared/operators'; import { AuthService } from '../../../../../../core/auth/auth.service'; import { EPerson } from '../../../../../../core/eperson/models/eperson.model'; import { EPersonDataService } from '../../../../../../core/eperson/eperson-data.service'; diff --git a/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.html b/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.html new file mode 100644 index 00000000000..2e4f8d39cd9 --- /dev/null +++ b/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.html @@ -0,0 +1,13 @@ + +
+
+ {{'workflow-item.search.result.list.element.supervised-by' | translate}} +
+
+ + {{supervisionOrder.group.name}} + X + +
+
+
diff --git a/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.scss b/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.spec.ts b/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.spec.ts new file mode 100644 index 00000000000..9a5516b8e95 --- /dev/null +++ b/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SupervisionOrderStatusComponent } from './supervision-order-status.component'; + +describe('SupervisionOrderStatusComponent', () => { + let component: SupervisionOrderStatusComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SupervisionOrderStatusComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SupervisionOrderStatusComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.ts b/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.ts new file mode 100644 index 00000000000..92cbf178857 --- /dev/null +++ b/src/app/shared/object-list/supervision-order-status/supervision-order-status.component.ts @@ -0,0 +1,88 @@ +import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; + +import { BehaviorSubject, from, Observable } from 'rxjs'; +import { map, mergeMap, reduce } from 'rxjs/operators'; + +import { SupervisionOrder } from '../../../core/supervision-order/models/supervision-order.model'; +import { Group } from '../../../core/eperson/models/group.model'; +import { getFirstCompletedRemoteData } from '../../../core/shared/operators'; +import { isNotEmpty } from '../../empty.util'; +import { RemoteData } from '../../../core/data/remote-data'; + +export interface SupervisionOrderListEntry { + supervisionOrder: SupervisionOrder; + group: Group +} + +@Component({ + selector: 'ds-supervision-order-status', + templateUrl: './supervision-order-status.component.html', + styleUrls: ['./supervision-order-status.component.scss'] +}) +export class SupervisionOrderStatusComponent implements OnChanges { + + /** + * The list of supervision order object to show + */ + @Input() supervisionOrderList: SupervisionOrder[] = []; + + /** + * The groups the user belongs to + */ + groups: Group[]; + + /** + * List of the supervision orders combined with the group + */ + supervisionOrderEntries$: BehaviorSubject = new BehaviorSubject([]); + + @Output() delete: EventEmitter = new EventEmitter(); + + ngOnChanges(changes: SimpleChanges): void { + if (changes && changes.supervisionOrderList) { + this.getSupervisionOrderEntries(changes.supervisionOrderList.currentValue) + .subscribe((supervisionOrderEntries: SupervisionOrderListEntry[]) => { + this.supervisionOrderEntries$.next(supervisionOrderEntries) + }) + } + console.log('ngOnChanges', changes); + } + + /** + * Create a list of SupervisionOrderListEntry by the given SupervisionOrder list + * + * @param supervisionOrderList + */ + private getSupervisionOrderEntries(supervisionOrderList: SupervisionOrder[]): Observable { + return from(supervisionOrderList).pipe( + mergeMap((so: SupervisionOrder) => so.group.pipe( + getFirstCompletedRemoteData(), + map((sogRD: RemoteData) => { + if (sogRD.hasSucceeded) { + const entry: SupervisionOrderListEntry = { + supervisionOrder: so, + group: sogRD.payload + }; + return entry; + } else { + return null; + } + }) + )), + reduce((acc: SupervisionOrderListEntry[], value: any) => { + if (isNotEmpty(value)) { + return [...acc, value] + } else { + return acc; + } + }, []), + ) + } + + /** + * Emit a delete event with the given SupervisionOrderListEntry. + */ + deleteSupervisionOrder(supervisionOrder: SupervisionOrderListEntry) { + this.delete.emit(supervisionOrder); + } +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 3c985d46b96..624d519ad1f 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -100,19 +100,19 @@ import { CreateCommunityParentSelectorComponent } from './dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component'; import { - ThemedCreateCommunityParentSelectorComponent + ThemedCreateCommunityParentSelectorComponent } from './dso-selector/modal-wrappers/create-community-parent-selector/themed-create-community-parent-selector.component'; import { CreateItemParentSelectorComponent } from './dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component'; import { - ThemedCreateItemParentSelectorComponent + ThemedCreateItemParentSelectorComponent } from './dso-selector/modal-wrappers/create-item-parent-selector/themed-create-item-parent-selector.component'; import { CreateCollectionParentSelectorComponent } from './dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component'; import { - ThemedCreateCollectionParentSelectorComponent + ThemedCreateCollectionParentSelectorComponent } from './dso-selector/modal-wrappers/create-collection-parent-selector/themed-create-collection-parent-selector.component'; import { CommunitySearchResultListElementComponent @@ -124,19 +124,19 @@ import { EditItemSelectorComponent } from './dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component'; import { - ThemedEditItemSelectorComponent + ThemedEditItemSelectorComponent } from './dso-selector/modal-wrappers/edit-item-selector/themed-edit-item-selector.component'; import { EditCommunitySelectorComponent } from './dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component'; import { - ThemedEditCommunitySelectorComponent + ThemedEditCommunitySelectorComponent } from './dso-selector/modal-wrappers/edit-community-selector/themed-edit-community-selector.component'; import { EditCollectionSelectorComponent } from './dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component'; import { - ThemedEditCollectionSelectorComponent + ThemedEditCollectionSelectorComponent } from './dso-selector/modal-wrappers/edit-collection-selector/themed-edit-collection-selector.component'; import { RoleDirective } from './roles/role.directive'; import { UserMenuComponent } from './auth-nav-menu/user-menu/user-menu.component'; @@ -242,14 +242,20 @@ import { MenuModule } from './menu/menu.module'; import { ListableNotificationObjectComponent } from './object-list/listable-notification-object/listable-notification-object.component'; -import { SupervisionGroupSelectorComponent } from './dso-selector/modal-wrappers/supervision-group-selector/supervision-group-selector.component'; +import { + SupervisionGroupSelectorComponent +} from './dso-selector/modal-wrappers/supervision-group-selector/supervision-group-selector.component'; import { EpersonGroupListComponent } from './form/eperson-group-list/eperson-group-list.component'; import { EpersonSearchBoxComponent } from './form/eperson-group-list/eperson-search-box/eperson-search-box.component'; import { GroupSearchBoxComponent } from './form/eperson-group-list/group-search-box/group-search-box.component'; import { ThemedCollectionDropdownComponent } from './collection-dropdown/themed-collection-dropdown.component'; import { MetadataFieldWrapperComponent } from './metadata-field-wrapper/metadata-field-wrapper.component'; -import { LogInExternalProviderComponent } from './log-in/methods/log-in-external-provider/log-in-external-provider.component'; - +import { + LogInExternalProviderComponent +} from './log-in/methods/log-in-external-provider/log-in-external-provider.component'; +import { + SupervisionOrderStatusComponent +} from './object-list/supervision-order-status/supervision-order-status.component'; const MODULES = [ @@ -452,18 +458,20 @@ const DIRECTIVES = [ ...COMPONENTS, ...ENTRY_COMPONENTS, ...DIRECTIVES, + SupervisionOrderStatusComponent, ], providers: [ ...PROVIDERS ], - exports: [ - ...MODULES, - ...PIPES, - ...COMPONENTS, - ...ENTRY_COMPONENTS, - ...DIRECTIVES, - TranslateModule, - ] + exports: [ + ...MODULES, + ...PIPES, + ...COMPONENTS, + ...ENTRY_COMPONENTS, + ...DIRECTIVES, + TranslateModule, + SupervisionOrderStatusComponent, + ] }) /** diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 47fbbaf5188..892f686fb86 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -2271,21 +2271,21 @@ "item.truncatable-part.show-less": "Collapse", - "item.search.result.delete-supervision.modal.header": "Delete Supervision Order", + "workflow-item.search.result.delete-supervision.modal.header": "Delete Supervision Order", - "item.search.result.delete-supervision.modal.info": "Are you sure you want to delete Supervision Order", + "workflow-item.search.result.delete-supervision.modal.info": "Are you sure you want to delete Supervision Order", - "item.search.result.delete-supervision.modal.cancel": "Cancel", + "workflow-item.search.result.delete-supervision.modal.cancel": "Cancel", - "item.search.result.delete-supervision.modal.confirm": "Delete", + "workflow-item.search.result.delete-supervision.modal.confirm": "Delete", - "item.search.result.notification.deleted.success": "Successfully deleted supervision order \"{{name}}\"", + "workflow-item.search.result.notification.deleted.success": "Successfully deleted supervision order \"{{name}}\"", - "item.search.result.notification.deleted.failure.title": "Failed to delete supervision order \"{{name}}\"", + "workflow-item.search.result.notification.deleted.failure": "Failed to delete supervision order \"{{name}}\"", - "item.search.result.notification.deleted.failure.content": "Failed to delete supervision order", + "workflow-item.search.result.list.element.supervised-by": "Supervised by:", - "item.search.result.list.element.supervised-by": "Supervised by:", + "workflow-item.search.result.list.element.supervised.remove-tooltip": "Remove supervision group", From 851fe7869ed5c47089e0430e82542c4d08a89477 Mon Sep 17 00:00:00 2001 From: Davide Negretti Date: Sat, 11 Feb 2023 03:29:17 +0100 Subject: [PATCH 1463/2129] [CST-7757] Missing label --- src/assets/i18n/en.json5 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index bf32aebe47c..fa6f2694fa1 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -4748,6 +4748,8 @@ "subscriptions.modal.new-subscription-form.submit": "Submit", + "subscriptions.modal.new-subscription-form.processing": "Processing...", + "subscriptions.modal.create.success": "Subscribed to {{ type }} successfully.", "subscriptions.modal.delete.success": "Subscription deleted successfully", From c74ef49797cb0fe9e816cb9648a7503b7094304f Mon Sep 17 00:00:00 2001 From: cris Date: Sat, 11 Feb 2023 17:13:52 +0000 Subject: [PATCH 1464/2129] fixed issue in browser console --- .../mydspace-item-collection/item-collection.component.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/shared/object-collection/shared/mydspace-item-collection/item-collection.component.ts b/src/app/shared/object-collection/shared/mydspace-item-collection/item-collection.component.ts index 8f857540d4c..2f2a20ede36 100644 --- a/src/app/shared/object-collection/shared/mydspace-item-collection/item-collection.component.ts +++ b/src/app/shared/object-collection/shared/mydspace-item-collection/item-collection.component.ts @@ -40,7 +40,9 @@ export class ItemCollectionComponent implements OnInit { */ ngOnInit() { - this.linkService.resolveLinks(this.object, followLink('workflowitem', {}, + this.linkService.resolveLinks(this.object, followLink('workflowitem', { + isOptional: true + }, followLink('collection',{}) )); this.collection$ = (this.object.workflowitem as Observable>).pipe( From eeda26e122859bfac8fcbc6ea806eae86c19431e Mon Sep 17 00:00:00 2001 From: aroman-arvo Date: Mon, 13 Feb 2023 10:42:56 +0100 Subject: [PATCH 1465/2129] 8408 - sort ordering is parametrized and used only when no text query is send. --- config/config.example.yml | 5 +++++ config/config.yml | 6 +++--- .../dso-selector/dso-selector.component.ts | 4 +++- .../create-community-parent-selector.component.ts | 6 ------ .../dso-selector-modal-wrapper.component.ts | 5 +++-- .../scope-selector-modal.component.ts | 7 +------ src/config/app-config.interface.ts | 2 ++ src/config/default-app-config.ts | 7 +++++++ src/config/discovery-sort.config.ts | 14 ++++++++++++++ src/environments/environment.test.ts | 4 ++++ 10 files changed, 42 insertions(+), 18 deletions(-) create mode 100644 src/config/discovery-sort.config.ts diff --git a/config/config.example.yml b/config/config.example.yml index 9abf167b901..c5a9ea6f85b 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -310,3 +310,8 @@ info: markdown: enabled: false mathjax: false + +# Default collection/community sorting order at Advanced search, Create/update community and collection when there are not a query. +collectionSelectionSort: + sortMetadata: "dc.title" + sortDirection: "ASC" \ No newline at end of file diff --git a/config/config.yml b/config/config.yml index b5eecd112f0..38ac562b15f 100644 --- a/config/config.yml +++ b/config/config.yml @@ -1,5 +1,5 @@ rest: - ssl: true - host: api7.dspace.org - port: 443 + ssl: false + host: localhost + port: 9090 nameSpace: /server diff --git a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts index 4b5d8c76143..52ca9224b1f 100644 --- a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts +++ b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts @@ -227,6 +227,8 @@ export class DSOSelectorComponent implements OnInit, OnDestroy { * @param useCache Whether or not to use the cache */ search(query: string, page: number, useCache: boolean = true): Observable>>> { + // default sort is only used when there is not query + var efectiveSort=query?null:this.sort; return this.searchService.search( new PaginatedSearchOptions({ query: query, @@ -234,7 +236,7 @@ export class DSOSelectorComponent implements OnInit, OnDestroy { pagination: Object.assign({}, this.defaultPagination, { currentPage: page }), - sort: this.sort + sort: efectiveSort }), null, useCache, diff --git a/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts b/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts index f344c1c3f30..a7f583df50f 100644 --- a/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts @@ -12,7 +12,6 @@ import { getCommunityCreateRoute, COMMUNITY_PARENT_PARAMETER } from '../../../../community-page/community-page-routing-paths'; -import {SortDirection, SortOptions} from '../../../../core/cache/models/sort-options.model'; /** * Component to wrap a button - for top communities - @@ -31,11 +30,6 @@ export class CreateCommunityParentSelectorComponent extends DSOSelectorModalWrap selectorTypes = [DSpaceObjectType.COMMUNITY]; action = SelectorActionType.CREATE; - /** - * Default DSO ordering - */ - defaultSort = new SortOptions('dc.title', SortDirection.ASC); - constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router) { super(activeModal, route); } diff --git a/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.ts b/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.ts index 2a25da2f722..fcb8aea9d2e 100644 --- a/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.ts @@ -5,7 +5,8 @@ import { RemoteData } from '../../../core/data/remote-data'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model'; import { hasValue, isNotEmpty } from '../../empty.util'; -import {SortDirection, SortOptions} from '../../../core/cache/models/sort-options.model'; +import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; +import { environment } from '../../../../environments/environment'; export enum SelectorActionType { CREATE = 'create', @@ -53,7 +54,7 @@ export abstract class DSOSelectorModalWrapperComponent implements OnInit { /** * Default DSO ordering */ - defaultSort = new SortOptions('dc.title', SortDirection.ASC); + defaultSort = new SortOptions(environment.collectionSelectionSort.sortMetadata, environment.collectionSelectionSort.sortDirection as SortDirection); constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute) { } diff --git a/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.ts b/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.ts index 416242520c4..86c30102875 100644 --- a/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.ts +++ b/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.ts @@ -4,7 +4,7 @@ import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model'; import { DSOSelectorModalWrapperComponent, SelectorActionType } from '../../dso-selector/modal-wrappers/dso-selector-modal-wrapper.component'; import { DSpaceObject } from '../../../core/shared/dspace-object.model'; -import {SortDirection, SortOptions} from '../../../core/cache/models/sort-options.model'; + /** * Component to wrap a button - to select the entire repository - * and a list of parent communities - for scope selection @@ -33,11 +33,6 @@ export class ScopeSelectorModalComponent extends DSOSelectorModalWrapperComponen */ scopeChange = new EventEmitter(); - /** - * Default DSO ordering - */ - defaultSort = new SortOptions('dc.title', SortDirection.ASC); - constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute) { super(activeModal, route); } diff --git a/src/config/app-config.interface.ts b/src/config/app-config.interface.ts index ce9c8b3bf7a..cc7227d11ec 100644 --- a/src/config/app-config.interface.ts +++ b/src/config/app-config.interface.ts @@ -20,6 +20,7 @@ import { InfoConfig } from './info-config.interface'; import { CommunityListConfig } from './community-list-config.interface'; import { HomeConfig } from './homepage-config.interface'; import { MarkdownConfig } from './markdown-config.interface'; +import { DiscoverySortConfig } from './discovery-sort.config'; interface AppConfig extends Config { ui: UIServerConfig; @@ -44,6 +45,7 @@ interface AppConfig extends Config { actuators: ActuatorsConfig info: InfoConfig; markdown: MarkdownConfig; + collectionSelectionSort: DiscoverySortConfig; } /** diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index 276d2d71502..572f757f86b 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -20,6 +20,7 @@ import { InfoConfig } from './info-config.interface'; import { CommunityListConfig } from './community-list-config.interface'; import { HomeConfig } from './homepage-config.interface'; import { MarkdownConfig } from './markdown-config.interface'; +import { DiscoverySortConfig } from './discovery-sort.config'; export class DefaultAppConfig implements AppConfig { production = false; @@ -385,4 +386,10 @@ export class DefaultAppConfig implements AppConfig { enabled: false, mathjax: false, }; + + // Configuration that determines the metadata sorting of community and collection edition and creation when there are not a search query. + collectionSelectionSort: DiscoverySortConfig = { + sortMetadata:"dc.title", + sortDirection:"ASC", + }; } diff --git a/src/config/discovery-sort.config.ts b/src/config/discovery-sort.config.ts new file mode 100644 index 00000000000..02428f70a85 --- /dev/null +++ b/src/config/discovery-sort.config.ts @@ -0,0 +1,14 @@ +import { Config } from './config.interface'; + +/** + * Config that determines a metadata sorting config. + * It's created mainly to sort by metadata community and collection edition and creation + */ +export class DiscoverySortConfig implements Config { + + public sortMetadata: string; + /** + * ASC / DESC values expected + */ + public sortDirection: string; +} diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index 19eec26a140..2cdbee9c290 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -283,4 +283,8 @@ export const environment: BuildConfig = { enabled: false, mathjax: false, }, + collectionSelectionSort: { + sortMetadata:"dc.title", + sortDirection:"ASC", + }, }; From 363136027ec0e05d01e2a9d5c1ba6cbbc9dbba45 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Mon, 13 Feb 2023 10:36:13 +0100 Subject: [PATCH 1466/2129] [CST-7755] WIP revert changes on list components --- ...arch-result-list-element.component.spec.ts | 103 +------------ ...arch-result-list-element.component.spec.ts | 101 +------------ ...arch-result-list-element.component.spec.ts | 101 +------------ ...arch-result-list-element.component.spec.ts | 99 +------------ ...arch-result-list-element.component.spec.ts | 98 +------------ ...on-search-result-list-element.component.ts | 20 +-- ...arch-result-list-element.component.spec.ts | 103 +------------ ...table-object-component-loader.component.ts | 6 - .../abstract-listable-element.component.ts | 10 -- .../item/item-list-element.component.html | 2 +- .../object-list/object-list.component.html | 1 - .../object-list/object-list.component.ts | 5 - ...arch-result-list-element.component.spec.ts | 102 +------------ ...em-search-result-list-element.component.ts | 136 +----------------- 14 files changed, 16 insertions(+), 871 deletions(-) diff --git a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.spec.ts b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.spec.ts index 3a0e73e46c2..178ed86c40c 100644 --- a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.spec.ts +++ b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-issue/journal-issue-search-result-list-element.component.spec.ts @@ -1,7 +1,7 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model'; import { JournalIssueSearchResultListElementComponent } from './journal-issue-search-result-list-element.component'; import { Item } from '../../../../../core/shared/item.model'; @@ -10,43 +10,9 @@ import { TruncatableService } from '../../../../../shared/truncatable/truncatabl import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service'; import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service.mock'; import { APP_CONFIG } from '../../../../../../config/app-config.interface'; -import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; -import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; -import { TranslateService } from '@ngx-translate/core'; -import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils'; -import { PageInfo } from '../../../../../core/shared/page-info.model'; -import { buildPaginatedList } from '../../../../../core/data/paginated-list.model'; -import { GroupMock } from '../../../../../shared/testing/group-mock'; -import { hot } from 'jasmine-marbles'; -import { AuthService } from '../../../../../core/auth/auth.service'; -import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service'; -import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service'; -import { ResourcePolicyDataService } from '../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub'; -import { EPersonMock } from '../../../../../shared/testing/eperson.mock'; -import { EPerson } from '../../../../../core/eperson/models/eperson.model'; -import { createPaginatedList } from '../../../../../shared/testing/utils.test'; let journalIssueListElementComponent: JournalIssueSearchResultListElementComponent; let fixture: ComponentFixture; -let authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) -}); - -const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { - getAuthenticatedUserFromStore: () => { - return of(EPersonMock); - } -}); - -const user = Object.assign(new EPerson(), { - id: 'userId', - groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: { self: { href: 'test.com/uuid/1234567654321' } } -}); -const epersonService = jasmine.createSpyObj('epersonService', { - findById: createSuccessfulRemoteDataObject$(user), -}); const mockItemWithMetadata: ItemSearchResult = Object.assign( new ItemSearchResult(), @@ -104,65 +70,12 @@ const enviromentNoThumbs = { } }; -const supervisionOrderDataService: any = jasmine.createSpyObj('supervisionOrderDataService', { - searchByItem: jasmine.createSpy('searchByItem'), -}); - -const supervisionOrder: any = { - id: '1', - type: 'supervisionOrder', - uuid: 'supervision-order-1', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; -const anothersupervisionOrder: any = { - id: '2', - type: 'supervisionOrder', - uuid: 'supervision-order-2', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; - -const pageInfo = new PageInfo(); -const array = [supervisionOrder, anothersupervisionOrder]; -const paginatedList = buildPaginatedList(pageInfo, array); -const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); - describe('JournalIssueSearchResultListElementComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [JournalIssueSearchResultListElementComponent, TruncatePipe], providers: [ { provide: TruncatableService, useValue: {} }, - { provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - { provide: NotificationsService, useValue: {}}, - { provide: TranslateService, useValue: {}}, - { provide: ResourcePolicyDataService, useValue: {}}, - { provide: AuthService, useValue: authService}, - { provide: EPersonDataService, useValue: epersonService}, - { provide: AuthorizationDataService, useValue: authorizationService}, { provide: DSONameService, useClass: DSONameServiceMock }, { provide: APP_CONFIG, useValue: environmentUseThumbs } ], @@ -174,9 +87,6 @@ describe('JournalIssueSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(JournalIssueSearchResultListElementComponent); journalIssueListElementComponent = fixture.componentInstance; @@ -254,13 +164,6 @@ describe('JournalIssueSearchResultListElementComponent', () => { declarations: [JournalIssueSearchResultListElementComponent, TruncatePipe], providers: [ {provide: TruncatableService, useValue: {}}, - {provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - {provide: NotificationsService, useValue: {}}, - {provide: TranslateService, useValue: {}}, - {provide: ResourcePolicyDataService, useValue: {}}, - {provide: AuthService, useValue: authService}, - {provide: EPersonDataService, useValue: epersonService}, - {provide: AuthorizationDataService, useValue: authorizationService}, {provide: DSONameService, useClass: DSONameServiceMock}, { provide: APP_CONFIG, useValue: enviromentNoThumbs } ], @@ -278,9 +181,7 @@ describe('JournalIssueSearchResultListElementComponent', () => { describe('with environment.browseBy.showThumbnails set to false', () => { beforeEach(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); + journalIssueListElementComponent.object = mockItemWithMetadata; fixture.detectChanges(); }); diff --git a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.spec.ts b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.spec.ts index 67665403d1d..71fa83a3b1e 100644 --- a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.spec.ts +++ b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal-volume/journal-volume-search-result-list-element.component.spec.ts @@ -1,7 +1,7 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model'; import { Item } from '../../../../../core/shared/item.model'; import { JournalVolumeSearchResultListElementComponent } from './journal-volume-search-result-list-element.component'; @@ -10,43 +10,10 @@ import { TruncatableService } from '../../../../../shared/truncatable/truncatabl import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service'; import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service.mock'; import { APP_CONFIG } from '../../../../../../config/app-config.interface'; -import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; -import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; -import { TranslateService } from '@ngx-translate/core'; -import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils'; -import { PageInfo } from '../../../../../core/shared/page-info.model'; -import { buildPaginatedList } from '../../../../../core/data/paginated-list.model'; -import { GroupMock } from '../../../../../shared/testing/group-mock'; -import { hot } from 'jasmine-marbles'; -import { ResourcePolicyDataService } from '../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthService } from '../../../../../core/auth/auth.service'; -import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service'; -import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service'; -import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub'; -import { EPersonMock } from '../../../../../shared/testing/eperson.mock'; -import { EPerson } from '../../../../../core/eperson/models/eperson.model'; -import { createPaginatedList } from '../../../../../shared/testing/utils.test'; let journalVolumeListElementComponent: JournalVolumeSearchResultListElementComponent; let fixture: ComponentFixture; -let authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) -}); - -const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { - getAuthenticatedUserFromStore: () => { - return of(EPersonMock); - } -}); -const user = Object.assign(new EPerson(), { - id: 'userId', - groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: { self: { href: 'test.com/uuid/1234567654321' } } -}); -const epersonService = jasmine.createSpyObj('epersonService', { - findById: createSuccessfulRemoteDataObject$(user), -}); const mockItemWithMetadata: ItemSearchResult = Object.assign( new ItemSearchResult(), { @@ -102,65 +69,12 @@ const enviromentNoThumbs = { } }; -const supervisionOrderDataService: any = jasmine.createSpyObj('supervisionOrderDataService', { - searchByItem: jasmine.createSpy('searchByItem'), -}); - -const supervisionOrder: any = { - id: '1', - type: 'supervisionOrder', - uuid: 'supervision-order-1', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; -const anothersupervisionOrder: any = { - id: '2', - type: 'supervisionOrder', - uuid: 'supervision-order-2', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; - -const pageInfo = new PageInfo(); -const array = [supervisionOrder, anothersupervisionOrder]; -const paginatedList = buildPaginatedList(pageInfo, array); -const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); - describe('JournalVolumeSearchResultListElementComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [JournalVolumeSearchResultListElementComponent, TruncatePipe], providers: [ { provide: TruncatableService, useValue: {} }, - { provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - { provide: NotificationsService, useValue: {}}, - { provide: TranslateService, useValue: {}}, - { provide: ResourcePolicyDataService, useValue: {}}, - { provide: AuthService, useValue: authService}, - { provide: EPersonDataService, useValue: epersonService}, - { provide: AuthorizationDataService, useValue: authorizationService}, { provide: DSONameService, useClass: DSONameServiceMock }, { provide: APP_CONFIG, useValue: environmentUseThumbs } ], @@ -172,9 +86,6 @@ describe('JournalVolumeSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(JournalVolumeSearchResultListElementComponent); journalVolumeListElementComponent = fixture.componentInstance; @@ -251,13 +162,6 @@ describe('JournalVolumeSearchResultListElementComponent', () => { declarations: [JournalVolumeSearchResultListElementComponent, TruncatePipe], providers: [ {provide: TruncatableService, useValue: {}}, - {provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - {provide: NotificationsService, useValue: {}}, - {provide: TranslateService, useValue: {}}, - {provide: ResourcePolicyDataService, useValue: {}}, - {provide: AuthService, useValue: authService}, - {provide: EPersonDataService, useValue: epersonService}, - {provide: AuthorizationDataService, useValue: authorizationService}, {provide: DSONameService, useClass: DSONameServiceMock}, { provide: APP_CONFIG, useValue: enviromentNoThumbs } ], @@ -269,9 +173,6 @@ describe('JournalVolumeSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(JournalVolumeSearchResultListElementComponent); journalVolumeListElementComponent = fixture.componentInstance; })); diff --git a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.spec.ts b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.spec.ts index 63e8abda28e..07970d71282 100644 --- a/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.spec.ts +++ b/src/app/entity-groups/journal-entities/item-list-elements/search-result-list-elements/journal/journal-search-result-list-element.component.spec.ts @@ -1,7 +1,7 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { JournalSearchResultListElementComponent } from './journal-search-result-list-element.component'; import { Item } from '../../../../../core/shared/item.model'; import { TruncatePipe } from '../../../../../shared/utils/truncate.pipe'; @@ -10,42 +10,9 @@ import { ItemSearchResult } from '../../../../../shared/object-collection/shared import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service'; import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service.mock'; import { APP_CONFIG } from '../../../../../../config/app-config.interface'; -import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; -import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; -import { TranslateService } from '@ngx-translate/core'; -import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils'; -import { PageInfo } from '../../../../../core/shared/page-info.model'; -import { buildPaginatedList } from '../../../../../core/data/paginated-list.model'; -import { GroupMock } from '../../../../../shared/testing/group-mock'; -import { hot } from 'jasmine-marbles'; -import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub'; -import { AuthService } from '../../../../../core/auth/auth.service'; -import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service'; -import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service'; -import { ResourcePolicyDataService } from '../../../../../core/resource-policy/resource-policy-data.service'; -import { EPersonMock } from '../../../../../shared/testing/eperson.mock'; -import { EPerson } from '../../../../../core/eperson/models/eperson.model'; -import { createPaginatedList } from '../../../../../shared/testing/utils.test'; let journalListElementComponent: JournalSearchResultListElementComponent; let fixture: ComponentFixture; -let authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) -}); - -const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { - getAuthenticatedUserFromStore: () => { - return of(EPersonMock); - } -}); -const user = Object.assign(new EPerson(), { - id: 'userId', - groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: { self: { href: 'test.com/uuid/1234567654321' } } -}); -const epersonService = jasmine.createSpyObj('epersonService', { - findById: createSuccessfulRemoteDataObject$(user), -}); const mockItemWithMetadata: ItemSearchResult = Object.assign( new ItemSearchResult(), @@ -98,65 +65,12 @@ const enviromentNoThumbs = { } }; -const supervisionOrderDataService: any = jasmine.createSpyObj('supervisionOrderDataService', { - searchByItem: jasmine.createSpy('searchByItem'), -}); - -const supervisionOrder: any = { - id: '1', - type: 'supervisionOrder', - uuid: 'supervision-order-1', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; -const anothersupervisionOrder: any = { - id: '2', - type: 'supervisionOrder', - uuid: 'supervision-order-2', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; - -const pageInfo = new PageInfo(); -const array = [supervisionOrder, anothersupervisionOrder]; -const paginatedList = buildPaginatedList(pageInfo, array); -const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); - describe('JournalSearchResultListElementComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [JournalSearchResultListElementComponent, TruncatePipe], providers: [ { provide: TruncatableService, useValue: {} }, - { provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - { provide: NotificationsService, useValue: {}}, - { provide: TranslateService, useValue: {}}, - { provide: ResourcePolicyDataService, useValue: {}}, - { provide: AuthService, useValue: authService}, - { provide: EPersonDataService, useValue: epersonService}, - { provide: AuthorizationDataService, useValue: authorizationService}, { provide: DSONameService, useClass: DSONameServiceMock }, { provide: APP_CONFIG, useValue: environmentUseThumbs } ], @@ -168,9 +82,6 @@ describe('JournalSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(JournalSearchResultListElementComponent); journalListElementComponent = fixture.componentInstance; @@ -223,13 +134,6 @@ describe('JournalSearchResultListElementComponent', () => { declarations: [JournalSearchResultListElementComponent, TruncatePipe], providers: [ {provide: TruncatableService, useValue: {}}, - {provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - {provide: NotificationsService, useValue: {}}, - {provide: TranslateService, useValue: {}}, - {provide: ResourcePolicyDataService, useValue: {}}, - {provide: AuthService, useValue: authService}, - {provide: EPersonDataService, useValue: epersonService}, - {provide: AuthorizationDataService, useValue: authorizationService}, {provide: DSONameService, useClass: DSONameServiceMock}, { provide: APP_CONFIG, useValue: enviromentNoThumbs } ], @@ -241,9 +145,6 @@ describe('JournalSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(JournalSearchResultListElementComponent); journalListElementComponent = fixture.componentInstance; })); diff --git a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.spec.ts b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.spec.ts index 102393ed8f5..9609a9582aa 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.spec.ts +++ b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/org-unit/org-unit-search-result-list-element.component.spec.ts @@ -1,7 +1,7 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { OrgUnitSearchResultListElementComponent } from './org-unit-search-result-list-element.component'; import { Item } from '../../../../../core/shared/item.model'; import { TruncatePipe } from '../../../../../shared/utils/truncate.pipe'; @@ -12,41 +12,9 @@ import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service import { APP_CONFIG } from '../../../../../../config/app-config.interface'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateLoaderMock } from '../../../../../shared/mocks/translate-loader.mock'; -import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; -import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; -import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils'; -import { PageInfo } from '../../../../../core/shared/page-info.model'; -import { buildPaginatedList } from '../../../../../core/data/paginated-list.model'; -import { GroupMock } from '../../../../../shared/testing/group-mock'; -import { hot } from 'jasmine-marbles'; -import { AuthService } from '../../../../../core/auth/auth.service'; -import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service'; -import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service'; -import { ResourcePolicyDataService } from '../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub'; -import { EPersonMock } from '../../../../../shared/testing/eperson.mock'; -import { EPerson } from '../../../../../core/eperson/models/eperson.model'; -import { createPaginatedList } from '../../../../../shared/testing/utils.test'; let orgUnitListElementComponent: OrgUnitSearchResultListElementComponent; let fixture: ComponentFixture; -let authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) -}); - -const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { - getAuthenticatedUserFromStore: () => { - return of(EPersonMock); - } -}); -const user = Object.assign(new EPerson(), { - id: 'userId', - groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: { self: { href: 'test.com/uuid/1234567654321' } } -}); -const epersonService = jasmine.createSpyObj('epersonService', { - findById: createSuccessfulRemoteDataObject$(user), -}); const mockItemWithMetadata: ItemSearchResult = Object.assign( new ItemSearchResult(), @@ -97,52 +65,6 @@ const enviromentNoThumbs = { } }; -const supervisionOrderDataService: any = jasmine.createSpyObj('supervisionOrderDataService', { - searchByItem: jasmine.createSpy('searchByItem'), -}); - -const supervisionOrder: any = { - id: '1', - type: 'supervisionOrder', - uuid: 'supervision-order-1', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; -const anothersupervisionOrder: any = { - id: '2', - type: 'supervisionOrder', - uuid: 'supervision-order-2', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; - -const pageInfo = new PageInfo(); -const array = [supervisionOrder, anothersupervisionOrder]; -const paginatedList = buildPaginatedList(pageInfo, array); -const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); - describe('OrgUnitSearchResultListElementComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ @@ -156,12 +78,6 @@ describe('OrgUnitSearchResultListElementComponent', () => { declarations: [ OrgUnitSearchResultListElementComponent , TruncatePipe], providers: [ { provide: TruncatableService, useValue: {} }, - { provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - { provide: NotificationsService, useValue: {}}, - { provide: ResourcePolicyDataService, useValue: {}}, - { provide: AuthService, useValue: authService}, - { provide: EPersonDataService, useValue: epersonService}, - { provide: AuthorizationDataService, useValue: authorizationService}, { provide: DSONameService, useClass: DSONameServiceMock }, { provide: APP_CONFIG, useValue: environmentUseThumbs } ], @@ -173,9 +89,6 @@ describe('OrgUnitSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(OrgUnitSearchResultListElementComponent); orgUnitListElementComponent = fixture.componentInstance; @@ -235,12 +148,6 @@ describe('OrgUnitSearchResultListElementComponent', () => { declarations: [OrgUnitSearchResultListElementComponent, TruncatePipe], providers: [ {provide: TruncatableService, useValue: {}}, - {provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - {provide: NotificationsService, useValue: {}}, - {provide: ResourcePolicyDataService, useValue: {}}, - {provide: AuthService, useValue: authService}, - {provide: EPersonDataService, useValue: epersonService}, - {provide: AuthorizationDataService, useValue: authorizationService}, {provide: DSONameService, useClass: DSONameServiceMock}, { provide: APP_CONFIG, useValue: enviromentNoThumbs } ], @@ -258,9 +165,7 @@ describe('OrgUnitSearchResultListElementComponent', () => { describe('with environment.browseBy.showThumbnails set to false', () => { beforeEach(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); + orgUnitListElementComponent.object = mockItemWithMetadata; fixture.detectChanges(); }); diff --git a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.spec.ts b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.spec.ts index 25b3a37c832..31018520f62 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.spec.ts +++ b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.spec.ts @@ -1,7 +1,7 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model'; import { PersonSearchResultListElementComponent } from './person-search-result-list-element.component'; import { Item } from '../../../../../core/shared/item.model'; @@ -12,44 +12,9 @@ import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service import { APP_CONFIG } from '../../../../../../config/app-config.interface'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateLoaderMock } from '../../../../../shared/mocks/translate-loader.mock'; -import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; -import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; -import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils'; -import { hot } from 'jasmine-marbles'; -import { PageInfo } from '../../../../../core/shared/page-info.model'; -import { GroupMock } from '../../../../../shared/testing/group-mock'; -import { buildPaginatedList } from '../../../../../core/data/paginated-list.model'; -import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub'; -import { EPersonMock } from '../../../../../shared/testing/eperson.mock'; -import { ResourcePolicyDataService } from '../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthService } from '../../../../../core/auth/auth.service'; -import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service'; -import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service'; -import { EPerson } from '../../../../../core/eperson/models/eperson.model'; -import { createPaginatedList } from '../../../../../shared/testing/utils.test'; let personListElementComponent: PersonSearchResultListElementComponent; let fixture: ComponentFixture; -const supervisionOrderDataService: any = jasmine.createSpyObj('supervisionOrderDataService', { - searchByItem: jasmine.createSpy('searchByItem'), -}); -let authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) -}); - -const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { - getAuthenticatedUserFromStore: () => { - return of(EPersonMock); - } -}); -const user = Object.assign(new EPerson(), { - id: 'userId', - groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: { self: { href: 'test.com/uuid/1234567654321' } } -}); -const epersonService = jasmine.createSpyObj('epersonService', { - findById: createSuccessfulRemoteDataObject$(user), -}); const mockItemWithMetadata: ItemSearchResult = Object.assign( new ItemSearchResult(), @@ -100,48 +65,6 @@ const enviromentNoThumbs = { } }; -const supervisionOrder: any = { - id: '1', - type: 'supervisionOrder', - uuid: 'supervision-order-1', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; -const anothersupervisionOrder: any = { - id: '2', - type: 'supervisionOrder', - uuid: 'supervision-order-2', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; - -const pageInfo = new PageInfo(); -const array = [supervisionOrder, anothersupervisionOrder]; -const paginatedList = buildPaginatedList(pageInfo, array); -const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); - describe('PersonSearchResultListElementComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ @@ -155,12 +78,6 @@ describe('PersonSearchResultListElementComponent', () => { declarations: [PersonSearchResultListElementComponent, TruncatePipe], providers: [ { provide: TruncatableService, useValue: {} }, - { provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - { provide: NotificationsService, useValue: {} }, - { provide: ResourcePolicyDataService, useValue: {}}, - { provide: AuthService, useValue: authService}, - { provide: EPersonDataService, useValue: epersonService}, - { provide: AuthorizationDataService, useValue: authorizationService}, { provide: DSONameService, useClass: DSONameServiceMock }, { provide: APP_CONFIG, useValue: environmentUseThumbs } ], @@ -172,9 +89,6 @@ describe('PersonSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(PersonSearchResultListElementComponent); personListElementComponent = fixture.componentInstance; @@ -234,12 +148,6 @@ describe('PersonSearchResultListElementComponent', () => { declarations: [PersonSearchResultListElementComponent, TruncatePipe], providers: [ {provide: TruncatableService, useValue: {}}, - {provide: SupervisionOrderDataService, useValue: supervisionOrderDataService}, - {provide: NotificationsService, useValue: {}}, - {provide: ResourcePolicyDataService, useValue: {}}, - {provide: AuthService, useValue: authService}, - {provide: EPersonDataService, useValue: epersonService}, - {provide: AuthorizationDataService, useValue: authorizationService}, {provide: DSONameService, useClass: DSONameServiceMock}, { provide: APP_CONFIG, useValue: enviromentNoThumbs } ], @@ -257,9 +165,7 @@ describe('PersonSearchResultListElementComponent', () => { describe('with environment.browseBy.showThumbnails set to false', () => { beforeEach(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); + personListElementComponent.object = mockItemWithMetadata; fixture.detectChanges(); }); diff --git a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.ts b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.ts index 09142fc02e8..217d7baef95 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.ts +++ b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/person/person-search-result-list-element.component.ts @@ -9,14 +9,6 @@ import { import { TruncatableService } from '../../../../../shared/truncatable/truncatable.service'; import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service'; import { APP_CONFIG, AppConfig } from '../../../../../../config/app-config.interface'; -import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; -import { TranslateService } from '@ngx-translate/core'; -import { ResourcePolicyDataService } from '../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthService } from '../../../../../core/auth/auth.service'; -import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service'; -import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service'; @listableObjectComponent('PersonSearchResult', ViewMode.ListElement) @Component({ @@ -32,17 +24,9 @@ export class PersonSearchResultListElementComponent extends ItemSearchResultList public constructor( protected truncatableService: TruncatableService, protected dsoNameService: DSONameService, - @Inject(APP_CONFIG) protected appConfig: AppConfig, - protected supervisionOrderDataService: SupervisionOrderDataService, - protected modalService: NgbModal, - protected notificationsService: NotificationsService, - protected translateService: TranslateService, - protected resourcePolicyService: ResourcePolicyDataService, - protected authService: AuthService, - protected epersonService: EPersonDataService, - protected authorizationService: AuthorizationDataService + @Inject(APP_CONFIG) protected appConfig: AppConfig ) { - super(truncatableService, dsoNameService, appConfig, supervisionOrderDataService, modalService, notificationsService, translateService, resourcePolicyService, authService, epersonService, authorizationService); + super(truncatableService, dsoNameService, appConfig); } /** diff --git a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/project/project-search-result-list-element.component.spec.ts b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/project/project-search-result-list-element.component.spec.ts index 60487af8c80..0cb3e63e870 100644 --- a/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/project/project-search-result-list-element.component.spec.ts +++ b/src/app/entity-groups/research-entities/item-list-elements/search-result-list-elements/project/project-search-result-list-element.component.spec.ts @@ -1,6 +1,6 @@ import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { ItemSearchResult } from '../../../../../shared/object-collection/shared/item-search-result.model'; import { ProjectSearchResultListElementComponent } from './project-search-result-list-element.component'; import { Item } from '../../../../../core/shared/item.model'; @@ -10,43 +10,9 @@ import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service import { DSONameServiceMock } from '../../../../../shared/mocks/dso-name.service.mock'; import { By } from '@angular/platform-browser'; import { APP_CONFIG } from '../../../../../../config/app-config.interface'; -import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service'; -import { NotificationsService } from '../../../../../shared/notifications/notifications.service'; -import { TranslateService } from '@ngx-translate/core'; -import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../../../shared/remote-data.utils'; -import { PageInfo } from '../../../../../core/shared/page-info.model'; -import { buildPaginatedList } from '../../../../../core/data/paginated-list.model'; -import { GroupMock } from '../../../../../shared/testing/group-mock'; -import { hot } from 'jasmine-marbles'; -import { AuthService } from '../../../../../core/auth/auth.service'; -import { AuthorizationDataService } from '../../../../../core/data/feature-authorization/authorization-data.service'; -import { EPersonDataService } from '../../../../../core/eperson/eperson-data.service'; -import { ResourcePolicyDataService } from '../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthServiceStub } from '../../../../../shared/testing/auth-service.stub'; -import { EPersonMock } from '../../../../../shared/testing/eperson.mock'; -import { EPerson } from '../../../../../core/eperson/models/eperson.model'; -import { createPaginatedList } from '../../../../../shared/testing/utils.test'; let projectListElementComponent: ProjectSearchResultListElementComponent; let fixture: ComponentFixture; -let authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) -}); - -const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { - getAuthenticatedUserFromStore: () => { - return of(EPersonMock); - } -}); - -const user = Object.assign(new EPerson(), { - id: 'userId', - groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: { self: { href: 'test.com/uuid/1234567654321' } } -}); -const epersonService = jasmine.createSpyObj('epersonService', { - findById: createSuccessfulRemoteDataObject$(user), -}); const mockItemWithMetadata: ItemSearchResult = Object.assign( new ItemSearchResult(), @@ -98,65 +64,12 @@ const enviromentNoThumbs = { } }; -const supervisionOrderDataService: any = jasmine.createSpyObj('supervisionOrderDataService', { - searchByItem: jasmine.createSpy('searchByItem'), -}); - -const supervisionOrder: any = { - id: '1', - type: 'supervisionOrder', - uuid: 'supervision-order-1', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; -const anothersupervisionOrder: any = { - id: '2', - type: 'supervisionOrder', - uuid: 'supervision-order-2', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; - -const pageInfo = new PageInfo(); -const array = [supervisionOrder, anothersupervisionOrder]; -const paginatedList = buildPaginatedList(pageInfo, array); -const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); - describe('ProjectSearchResultListElementComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ProjectSearchResultListElementComponent, TruncatePipe], providers: [ { provide: TruncatableService, useValue: {} }, - { provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - { provide: NotificationsService, useValue: {}}, - { provide: TranslateService, useValue: {}}, - { provide: ResourcePolicyDataService, useValue: {}}, - { provide: AuthService, useValue: authService}, - { provide: EPersonDataService, useValue: epersonService}, - { provide: AuthorizationDataService, useValue: authorizationService}, { provide: DSONameService, useClass: DSONameServiceMock }, { provide: APP_CONFIG, useValue: environmentUseThumbs } ], @@ -168,9 +81,6 @@ describe('ProjectSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(ProjectSearchResultListElementComponent); projectListElementComponent = fixture.componentInstance; @@ -223,13 +133,6 @@ describe('ProjectSearchResultListElementComponent', () => { declarations: [ProjectSearchResultListElementComponent, TruncatePipe], providers: [ {provide: TruncatableService, useValue: {}}, - {provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - {provide: NotificationsService, useValue: {}}, - {provide: TranslateService, useValue: {}}, - {provide: ResourcePolicyDataService, useValue: {}}, - {provide: AuthService, useValue: authService}, - {provide: EPersonDataService, useValue: epersonService}, - {provide: AuthorizationDataService, useValue: authorizationService}, {provide: DSONameService, useClass: DSONameServiceMock}, { provide: APP_CONFIG, useValue: enviromentNoThumbs } @@ -248,9 +151,7 @@ describe('ProjectSearchResultListElementComponent', () => { describe('with environment.browseBy.showThumbnails set to false', () => { beforeEach(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); + projectListElementComponent.object = mockItemWithMetadata; fixture.detectChanges(); }); diff --git a/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts b/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts index 59ce71ff6cd..6b75c591816 100644 --- a/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts +++ b/src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts @@ -71,11 +71,6 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnChanges */ @Input() showLabel = true; - /** - * Whether to show the supervision orders badges or not - */ - @Input() showSupervisionOrderBadges = false; - /** * The value to display for this element */ @@ -128,7 +123,6 @@ export class ListableObjectComponentLoaderComponent implements OnInit, OnChanges */ protected inAndOutputNames: string[] = [ 'object', - 'showSupervisionOrderBadges', 'index', 'linkType', 'listID', diff --git a/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts b/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts index f292ac5b76f..7d4e107b2b3 100644 --- a/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts +++ b/src/app/shared/object-collection/shared/object-collection-element/abstract-listable-element.component.ts @@ -16,11 +16,6 @@ export class AbstractListableElementComponent { */ @Input() object: T; - /** - * The supervision orders to render in this list element - */ - @Input() supervisionOrders: T; - /** * The link type to determine the type of link rendered in this element */ @@ -46,11 +41,6 @@ export class AbstractListableElementComponent { */ @Input() showLabel = true; - /** - * Whether to show the supervision orders badges or not - */ - @Input() showSupervisionOrderBadges = false; - /** * The context we matched on to get this component */ diff --git a/src/app/shared/object-list/item-list-element/item-types/item/item-list-element.component.html b/src/app/shared/object-list/item-list-element/item-types/item/item-list-element.component.html index 4bf45e7f3b6..3877e2f335b 100644 --- a/src/app/shared/object-list/item-list-element/item-types/item/item-list-element.component.html +++ b/src/app/shared/object-list/item-list-element/item-types/item/item-list-element.component.html @@ -1 +1 @@ - + diff --git a/src/app/shared/object-list/object-list.component.html b/src/app/shared/object-list/object-list.component.html index a0ef3e1cb9f..b8712b85c57 100644 --- a/src/app/shared/object-list/object-list.component.html +++ b/src/app/shared/object-list/object-list.component.html @@ -31,7 +31,6 @@ [context]="context" [linkType]="linkType" [listID]="selectionConfig?.listId" - [showSupervisionOrderBadges]="showSupervisionOrderBadges" (contentChange)="contentChange.emit($event)"> diff --git a/src/app/shared/object-list/object-list.component.ts b/src/app/shared/object-list/object-list.component.ts index 9d064115e63..65e2b508daa 100644 --- a/src/app/shared/object-list/object-list.component.ts +++ b/src/app/shared/object-list/object-list.component.ts @@ -81,11 +81,6 @@ export class ObjectListComponent { */ @Input() showPaginator = true; - /** - * Whether to show the supervision orders badges or not - */ - @Input() showSupervisionOrderBadges = false; - /** * Emit when one of the listed object has changed. */ diff --git a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.spec.ts b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.spec.ts index d4ca14c1057..7665b7d64e3 100644 --- a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.spec.ts +++ b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.spec.ts @@ -1,7 +1,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core'; import { By } from '@angular/platform-browser'; -import { of as observableOf, of } from 'rxjs'; +import { of as observableOf } from 'rxjs'; import { ItemSearchResultListElementComponent } from './item-search-result-list-element.component'; import { Item } from '../../../../../../core/shared/item.model'; import { TruncatePipe } from '../../../../../utils/truncate.pipe'; @@ -10,44 +10,10 @@ import { ItemSearchResult } from '../../../../../object-collection/shared/item-s import { DSONameService } from '../../../../../../core/breadcrumbs/dso-name.service'; import { DSONameServiceMock, UNDEFINED_NAME } from '../../../../../mocks/dso-name.service.mock'; import { APP_CONFIG } from '../../../../../../../config/app-config.interface'; -import { SupervisionOrderDataService } from '../../../../../../core/supervision-order/supervision-order-data.service'; -import { NotificationsService } from '../../../../../../shared/notifications/notifications.service'; -import { TranslateService } from '@ngx-translate/core'; -import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../../../../shared/remote-data.utils'; -import { PageInfo } from '../../../../../../core/shared/page-info.model'; -import { buildPaginatedList } from '../../../../../../core/data/paginated-list.model'; -import { GroupMock } from '../../../../../../shared/testing/group-mock'; -import { hot } from 'jasmine-marbles'; -import { AuthService } from '../../../../../../core/auth/auth.service'; -import { AuthorizationDataService } from '../../../../../../core/data/feature-authorization/authorization-data.service'; -import { EPersonDataService } from '../../../../../../core/eperson/eperson-data.service'; -import { ResourcePolicyDataService } from '../../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthServiceStub } from '../../../../../../shared/testing/auth-service.stub'; -import { EPersonMock } from '../../../../../../shared/testing/eperson.mock'; -import { EPerson } from 'src/app/core/eperson/models/eperson.model'; -import { createPaginatedList } from 'src/app/shared/testing/utils.test'; let publicationListElementComponent: ItemSearchResultListElementComponent; let fixture: ComponentFixture; const dcTitle = 'This is just another title'; -let authorizationService = jasmine.createSpyObj('authorizationService', { - isAuthorized: observableOf(true) -}); - -const authService: AuthServiceStub = Object.assign(new AuthServiceStub(), { - getAuthenticatedUserFromStore: () => { - return of(EPersonMock); - } -}); -const user = Object.assign(new EPerson(), { - id: 'userId', - groups: createSuccessfulRemoteDataObject$(createPaginatedList([])), - _links: { self: { href: 'test.com/uuid/1234567654321' } } -}); -const epersonService = jasmine.createSpyObj('epersonService', { - findById: createSuccessfulRemoteDataObject$(user), -}); - const mockItemWithMetadata: ItemSearchResult = Object.assign(new ItemSearchResult(), { hitHighlights: { 'dc.title': [{ @@ -218,65 +184,12 @@ const enviromentNoThumbs = { } }; -const supervisionOrderDataService: any = jasmine.createSpyObj('supervisionOrderDataService', { - searchByItem: jasmine.createSpy('searchByItem'), -}); - -const supervisionOrder: any = { - id: '1', - type: 'supervisionOrder', - uuid: 'supervision-order-1', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; -const anothersupervisionOrder: any = { - id: '2', - type: 'supervisionOrder', - uuid: 'supervision-order-2', - _links: { - item: { - href: 'https://rest.api/rest/api/eperson' - }, - group: { - href: 'https://rest.api/rest/api/group' - }, - self: { - href: 'https://rest.api/rest/api/supervisionorders/1' - }, - }, - item: observableOf(createSuccessfulRemoteDataObject({})), - group: observableOf(createSuccessfulRemoteDataObject(GroupMock)) -}; - -const pageInfo = new PageInfo(); -const array = [supervisionOrder, anothersupervisionOrder]; -const paginatedList = buildPaginatedList(pageInfo, array); -const paginatedListRD = createSuccessfulRemoteDataObject(paginatedList); - describe('ItemSearchResultListElementComponent', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [ItemSearchResultListElementComponent, TruncatePipe], providers: [ { provide: TruncatableService, useValue: {} }, - { provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - { provide: NotificationsService, useValue: {}}, - { provide: TranslateService, useValue: {}}, - { provide: ResourcePolicyDataService, useValue: {}}, - { provide: AuthService, useValue: authService}, - { provide: EPersonDataService, useValue: epersonService}, - { provide: AuthorizationDataService, useValue: authorizationService}, { provide: DSONameService, useClass: DSONameServiceMock }, { provide: APP_CONFIG, useValue: environmentUseThumbs } ], @@ -288,9 +201,6 @@ describe('ItemSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(ItemSearchResultListElementComponent); publicationListElementComponent = fixture.componentInstance; @@ -463,13 +373,6 @@ describe('ItemSearchResultListElementComponent', () => { declarations: [ItemSearchResultListElementComponent, TruncatePipe], providers: [ {provide: TruncatableService, useValue: {}}, - {provide: SupervisionOrderDataService, useValue: supervisionOrderDataService }, - {provide: NotificationsService, useValue: {}}, - {provide: TranslateService, useValue: {}}, - {provide: ResourcePolicyDataService, useValue: {}}, - {provide: AuthService, useValue: authService}, - {provide: EPersonDataService, useValue: epersonService}, - {provide: AuthorizationDataService, useValue: authorizationService}, {provide: DSONameService, useClass: DSONameServiceMock}, { provide: APP_CONFIG, useValue: enviromentNoThumbs } ], @@ -481,9 +384,6 @@ describe('ItemSearchResultListElementComponent', () => { })); beforeEach(waitForAsync(() => { - supervisionOrderDataService.searchByItem.and.returnValue(hot('a|', { - a: paginatedListRD - })); fixture = TestBed.createComponent(ItemSearchResultListElementComponent); publicationListElementComponent = fixture.componentInstance; })); diff --git a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts index 7ed96fdc68f..f84ae642ad2 100644 --- a/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts +++ b/src/app/shared/object-list/search-result-list-element/item-search-result/item-types/item/item-search-result-list-element.component.ts @@ -1,37 +1,10 @@ -import { Component, Inject } from '@angular/core'; -import { - listableObjectComponent -} from '../../../../../object-collection/shared/listable-object/listable-object.decorator'; +import { Component } from '@angular/core'; +import { listableObjectComponent } from '../../../../../object-collection/shared/listable-object/listable-object.decorator'; import { ViewMode } from '../../../../../../core/shared/view-mode.model'; import { ItemSearchResult } from '../../../../../object-collection/shared/item-search-result.model'; import { SearchResultListElementComponent } from '../../../search-result-list-element.component'; import { Item } from '../../../../../../core/shared/item.model'; import { getItemPageRoute } from '../../../../../../item-page/item-page-routing-paths'; -import { SupervisionOrderDataService } from '../../../../../../core/supervision-order/supervision-order-data.service'; -import { TruncatableService } from '../../../../../../shared/truncatable/truncatable.service'; -import { DSONameService } from '../../../../../../core/breadcrumbs/dso-name.service'; -import { APP_CONFIG, AppConfig } from '../../../../../../../config/app-config.interface'; -import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; -import { combineLatest, filter, map, Observable, switchMap, take } from 'rxjs'; -import { ConfirmationModalComponent } from '../../../../../../shared/confirmation-modal/confirmation-modal.component'; -import { hasValue } from '../../../../../../shared/empty.util'; -import { NotificationsService } from '../../../../../../shared/notifications/notifications.service'; -import { TranslateService } from '@ngx-translate/core'; -import { followLink } from '../../../../../../shared/utils/follow-link-config.model'; -import { - getAllSucceededRemoteData, - getAllSucceededRemoteListPayload, - getFirstSucceededRemoteDataPayload, - getRemoteDataPayload -} from '../../../../../../core/shared/operators'; -import { SupervisionOrder } from '../../../../../../core/supervision-order/models/supervision-order.model'; -import { Group } from '../../../../../../core/eperson/models/group.model'; -import { ResourcePolicyDataService } from '../../../../../../core/resource-policy/resource-policy-data.service'; -import { AuthService } from '../../../../../../core/auth/auth.service'; -import { EPerson } from '../../../../../../core/eperson/models/eperson.model'; -import { EPersonDataService } from '../../../../../../core/eperson/eperson-data.service'; -import { AuthorizationDataService } from '../../../../../../core/data/feature-authorization/authorization-data.service'; -import { FeatureID } from '../../../../../../core/data/feature-authorization/feature-id'; @listableObjectComponent('PublicationSearchResult', ViewMode.ListElement) @listableObjectComponent(ItemSearchResult, ViewMode.ListElement) @@ -44,8 +17,6 @@ import { FeatureID } from '../../../../../../core/data/feature-authorization/fea * The component for displaying a list element for an item search result of the type Publication */ export class ItemSearchResultListElementComponent extends SearchResultListElementComponent { - messagePrefix = 'item.search.result'; - /** * Route to the item's page */ @@ -56,112 +27,9 @@ export class ItemSearchResultListElementComponent extends SearchResultListElemen */ showThumbnails: boolean; - /** - * List of the supervision orders combined with the group - */ - supervisionOrder$: Observable<{ supervisionOrder: SupervisionOrder; group: Group; }[]>; - - /** - * The groups the user belongs to - */ - groups: Group[]; - - constructor( - protected truncatableService: TruncatableService, - protected dsoNameService: DSONameService, - @Inject(APP_CONFIG) protected appConfig: AppConfig, - protected supervisionOrderDataService: SupervisionOrderDataService, - protected modalService: NgbModal, - protected notificationsService: NotificationsService, - protected translateService: TranslateService, - protected resourcePolicyService: ResourcePolicyDataService, - protected authService: AuthService, - protected epersonService: EPersonDataService, - protected authorizationService: AuthorizationDataService - ) { super(truncatableService, dsoNameService, appConfig); } - ngOnInit(): void { super.ngOnInit(); this.showThumbnails = this.appConfig.browseBy.showThumbnails; - let isAdmin = false; - this.authorizationService.isAuthorized(FeatureID.AdministratorOf).subscribe(isadmin => { - isAdmin = isadmin; - }); - - this.authService.getAuthenticatedUserFromStore().pipe( - filter((user: EPerson) => hasValue(user.id)), - switchMap((user: EPerson) => this.epersonService.findById(user.id, true, true, followLink('groups'))), - getAllSucceededRemoteData(), - getRemoteDataPayload(), - switchMap((user: EPerson) => user.groups), - ).subscribe(groups => { - this.groups = groups?.payload?.page; - }); - this.itemPageRoute = getItemPageRoute(this.dso); - if (this.supervisionOrders) { - this.resourcePolicyService.searchByResource( - this.dso.uuid, null, false, true, - followLink('eperson'), followLink('group') - ).pipe( - getAllSucceededRemoteData(), - ).subscribe((result) => { - this.supervisionOrder$ = this.supervisionOrderDataService.searchByItem(this.dso.uuid, false, true, followLink('group')).pipe( - getAllSucceededRemoteListPayload(), - switchMap((supervisionOrders: SupervisionOrder[]) => { - const supervisionOrdersArray = supervisionOrders.map((supervisionOrder: SupervisionOrder) => { - return supervisionOrder.group.pipe( - getFirstSucceededRemoteDataPayload(), - map((group: Group) => { - let isAuthorized = false; - result.payload.page.forEach(resourcePolicy => { - resourcePolicy.group.subscribe(res => { - if (isAdmin || (res.payload && res.payload.uuid === group.uuid && this.groups.find(groups => groups.uuid === group.uuid))) { - isAuthorized = true; - } - }); - }); - return isAuthorized ? ({ supervisionOrder, group }) : null; - }), - ); - }); - return combineLatest(supervisionOrdersArray).pipe( - map(array => array.filter(hasValue)) - ); - })); - }); - } - } - - /** - * Deletes the Group from the Repository. The Group will be the only that this form is showing. - * It'll either show a success or error message depending on whether the delete was successful or not. - */ - deleteSupervisionOrder(supervisionOrder) { - const modalRef = this.modalService.open(ConfirmationModalComponent); - modalRef.componentInstance.dso = supervisionOrder.group; - modalRef.componentInstance.headerLabel = this.messagePrefix + '.delete-supervision.modal.header'; - modalRef.componentInstance.infoLabel = this.messagePrefix + '.delete-supervision.modal.info'; - modalRef.componentInstance.cancelLabel = this.messagePrefix + '.delete-supervision.modal.cancel'; - modalRef.componentInstance.confirmLabel = this.messagePrefix + '.delete-supervision.modal.confirm'; - modalRef.componentInstance.brandColor = 'danger'; - modalRef.componentInstance.confirmIcon = 'fas fa-trash'; - modalRef.componentInstance.response.pipe(take(1)).subscribe((confirm: boolean) => { - if (confirm) { - if (hasValue(supervisionOrder.supervisionOrder.id)) { - this.supervisionOrderDataService.delete(supervisionOrder.supervisionOrder.id) - .subscribe((rd: boolean) => { - if (rd) { - this.supervisionOrderDataService.searchByItem(this.dso.uuid, null, null, followLink('group')); - this.notificationsService.success(this.translateService.get(this.messagePrefix + '.notification.deleted.success', { name: supervisionOrder.group._name })); - } else { - this.notificationsService.error( - this.translateService.get(this.messagePrefix + '.notification.deleted.failure.title', { name: supervisionOrder.group._name }), - this.translateService.get(this.messagePrefix + '.notification.deleted.failure.content')); - } - }); - } - } - }); } } From e2668cdf972e22ee5142427d551e48956848e342 Mon Sep 17 00:00:00 2001 From: aroman-arvo Date: Mon, 13 Feb 2023 12:22:07 +0100 Subject: [PATCH 1467/2129] DS-8408 - lint errors --- .../dso-selector/dso-selector/dso-selector.component.ts | 2 +- src/config/default-app-config.ts | 4 ++-- src/config/discovery-sort.config.ts | 2 +- src/environments/environment.test.ts | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts index 52ca9224b1f..05fb512c9a8 100644 --- a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts +++ b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts @@ -228,7 +228,7 @@ export class DSOSelectorComponent implements OnInit, OnDestroy { */ search(query: string, page: number, useCache: boolean = true): Observable>>> { // default sort is only used when there is not query - var efectiveSort=query?null:this.sort; + var efectiveSort=query ? null : this.sort; return this.searchService.search( new PaginatedSearchOptions({ query: query, diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index 095a20a4e5f..89a627f4592 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -425,7 +425,7 @@ export class DefaultAppConfig implements AppConfig { // Configuration that determines the metadata sorting of community and collection edition and creation when there are not a search query. collectionSelectionSort: DiscoverySortConfig = { - sortMetadata:"dc.title", - sortDirection:"ASC", + sortMetadata:'dc.title', + sortDirection:'ASC', }; } diff --git a/src/config/discovery-sort.config.ts b/src/config/discovery-sort.config.ts index 02428f70a85..3f08b3fb17f 100644 --- a/src/config/discovery-sort.config.ts +++ b/src/config/discovery-sort.config.ts @@ -1,7 +1,7 @@ import { Config } from './config.interface'; /** - * Config that determines a metadata sorting config. + * Config that determines a metadata sorting config. * It's created mainly to sort by metadata community and collection edition and creation */ export class DiscoverySortConfig implements Config { diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index c352cdca928..8b132dab607 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -298,8 +298,8 @@ export const environment: BuildConfig = { mathjax: false, }, collectionSelectionSort: { - sortMetadata:"dc.title", - sortDirection:"ASC", + sortMetadata:'dc.title', + sortDirection:'ASC', }, vocabularies: [ From 0121e6d895de30c6c1054b8087fa6ecb1b7dd0bd Mon Sep 17 00:00:00 2001 From: aroman-arvo Date: Mon, 13 Feb 2023 12:34:13 +0100 Subject: [PATCH 1468/2129] DS-8408 - more lint problems --- .../shared/dso-selector/dso-selector/dso-selector.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts index 05fb512c9a8..fe64c0a41e7 100644 --- a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts +++ b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts @@ -228,7 +228,7 @@ export class DSOSelectorComponent implements OnInit, OnDestroy { */ search(query: string, page: number, useCache: boolean = true): Observable>>> { // default sort is only used when there is not query - var efectiveSort=query ? null : this.sort; + let efectiveSort = query ? null : this.sort; return this.searchService.search( new PaginatedSearchOptions({ query: query, From 078bdd287fbeca3912cc894f2356241925172081 Mon Sep 17 00:00:00 2001 From: Davide Negretti Date: Mon, 13 Feb 2023 15:45:56 +0100 Subject: [PATCH 1469/2129] [CST-7757] Fix delete message --- .../subscription-modal.component.html | 2 +- .../subscription-modal.component.ts | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/app/shared/subscriptions/subscription-modal/subscription-modal.component.html b/src/app/shared/subscriptions/subscription-modal/subscription-modal.component.html index 0e723a8140f..a71498f0021 100644 --- a/src/app/shared/subscriptions/subscription-modal/subscription-modal.component.html +++ b/src/app/shared/subscriptions/subscription-modal/subscription-modal.component.html @@ -27,7 +27,7 @@
-

{{'subscriptions.modal.delete-info' | translate}}

+

{{'subscriptions.modal.delete-info' | translate}}

- + \ No newline at end of file diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index fa6f2694fa1..3491c066a1a 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -4635,7 +4635,7 @@ "submission.workflow.generic.delete": "Delete", - "submission.workflow.generic.delete-help": "If you would to discard this item, select \"Delete\". You will then be asked to confirm it.", + "submission.workflow.generic.delete-help": "Select this option if you would to discard this item, select \"Delete\". You will then be asked to confirm it.", "submission.workflow.generic.edit": "Edit", From 0f25f9f18fb90967962217cdb80dd2dba251666b Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Tue, 14 Feb 2023 11:24:08 +0100 Subject: [PATCH 1475/2129] [CST-8914] Add flag to show/hide csv export button --- .../search-page/search-page.component.html | 2 +- .../search-results.component.html | 2 +- .../search-results.component.ts | 5 +++++ .../themed-search-results.component.ts | 4 +++- src/app/shared/search/search.component.html | 21 ++++++++++--------- src/app/shared/search/search.component.ts | 5 +++++ .../shared/search/themed-search.component.ts | 4 +++- 7 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/app/search-page/search-page.component.html b/src/app/search-page/search-page.component.html index 73a952332fd..36ba53a885e 100644 --- a/src/app/search-page/search-page.component.html +++ b/src/app/search-page/search-page.component.html @@ -1 +1 @@ - + diff --git a/src/app/shared/search/search-results/search-results.component.html b/src/app/shared/search/search-results/search-results.component.html index 44498c3cab8..1e8c81e4542 100644 --- a/src/app/shared/search/search-results/search-results.component.html +++ b/src/app/shared/search/search-results/search-results.component.html @@ -1,6 +1,6 @@

{{ (configuration ? configuration + '.search.results.head' : 'search.results.head') | translate }}

- +
{ - protected inAndOutputNames: (keyof SearchResultsComponent & keyof this)[] = ['linkType', 'searchResults', 'searchConfig', 'sortConfig', 'viewMode', 'configuration', 'disableHeader', 'selectable', 'context', 'hidePaginationDetail', 'selectionConfig', 'contentChange', 'deselectObject', 'selectObject']; + protected inAndOutputNames: (keyof SearchResultsComponent & keyof this)[] = ['linkType', 'searchResults', 'searchConfig', 'showCsvExport', 'sortConfig', 'viewMode', 'configuration', 'disableHeader', 'selectable', 'context', 'hidePaginationDetail', 'selectionConfig', 'contentChange', 'deselectObject', 'selectObject']; @Input() linkType: CollectionElementLinkType; @@ -29,6 +29,8 @@ export class ThemedSearchResultsComponent extends ThemedComponent
+ [searchConfig]="searchOptions$ | async" + [configuration]="(currentConfiguration$ | async)" + [disableHeader]="!searchEnabled" + [linkType]="linkType" + [context]="(currentContext$ | async)" + [selectable]="selectable" + [selectionConfig]="selectionConfig" + [showCsvExport]="showCsvExport" + (contentChange)="onContentChange($event)" + (deselectObject)="deselectObject.emit($event)" + (selectObject)="selectObject.emit($event)">
diff --git a/src/app/shared/search/search.component.ts b/src/app/shared/search/search.component.ts index c094e37ef23..b8426bc635c 100644 --- a/src/app/shared/search/search.component.ts +++ b/src/app/shared/search/search.component.ts @@ -117,6 +117,11 @@ export class SearchComponent implements OnInit { */ @Input() selectionConfig: SelectionConfig; + /** + * A boolean representing if show csv export button + */ + @Input() showCsvExport = false; + /** * A boolean representing if show search sidebar button */ diff --git a/src/app/shared/search/themed-search.component.ts b/src/app/shared/search/themed-search.component.ts index 64a2befeb2d..bdeb7247792 100644 --- a/src/app/shared/search/themed-search.component.ts +++ b/src/app/shared/search/themed-search.component.ts @@ -19,7 +19,7 @@ import { ListableObject } from '../object-collection/shared/listable-object.mode templateUrl: '../theme-support/themed.component.html', }) export class ThemedSearchComponent extends ThemedComponent { - protected inAndOutputNames: (keyof SearchComponent & keyof this)[] = ['configurationList', 'context', 'configuration', 'fixedFilterQuery', 'useCachedVersionIfAvailable', 'inPlaceSearch', 'linkType', 'paginationId', 'searchEnabled', 'sideBarWidth', 'searchFormPlaceholder', 'selectable', 'selectionConfig', 'showSidebar', 'showViewModes', 'useUniquePageId', 'viewModeList', 'showScopeSelector', 'resultFound', 'deselectObject', 'selectObject', 'trackStatistics']; + protected inAndOutputNames: (keyof SearchComponent & keyof this)[] = ['configurationList', 'context', 'configuration', 'fixedFilterQuery', 'useCachedVersionIfAvailable', 'inPlaceSearch', 'linkType', 'paginationId', 'searchEnabled', 'sideBarWidth', 'searchFormPlaceholder', 'selectable', 'selectionConfig', 'showCsvExport', 'showSidebar', 'showViewModes', 'useUniquePageId', 'viewModeList', 'showScopeSelector', 'resultFound', 'deselectObject', 'selectObject', 'trackStatistics']; @Input() configurationList: SearchConfigurationOption[] = []; @@ -47,6 +47,8 @@ export class ThemedSearchComponent extends ThemedComponent { @Input() selectionConfig: SelectionConfig; + @Input() showCsvExport = false; + @Input() showSidebar = true; @Input() showViewModes = true; From d810cbcc8fea2aea627223f46cd25c8a964c9390 Mon Sep 17 00:00:00 2001 From: Alan Orth Date: Wed, 15 Feb 2023 11:36:56 +0300 Subject: [PATCH 1476/2129] src/assets/i18n: Improve English strings for file upload Simple improvement to the wording in the file upload section of the item submission form. Also add a period at the end of the string. Fixes: #2096 --- src/assets/i18n/ar.json5 | 4 ++-- src/assets/i18n/bn.json5 | 2 +- src/assets/i18n/ca.json5 | 2 +- src/assets/i18n/cs.json5 | 4 ++-- src/assets/i18n/de.json5 | 2 +- src/assets/i18n/en.json5 | 2 +- src/assets/i18n/es.json5 | 2 +- src/assets/i18n/fi.json5 | 2 +- src/assets/i18n/fr.json5 | 2 +- src/assets/i18n/gd.json5 | 2 +- src/assets/i18n/hu.json5 | 2 +- src/assets/i18n/ja.json5 | 4 ++-- src/assets/i18n/kk.json5 | 2 +- src/assets/i18n/lv.json5 | 2 +- src/assets/i18n/nl.json5 | 2 +- src/assets/i18n/pt-BR.json5 | 2 +- src/assets/i18n/pt-PT.json5 | 2 +- src/assets/i18n/sv.json5 | 2 +- src/assets/i18n/sw.json5 | 4 ++-- src/assets/i18n/tr.json5 | 2 +- src/assets/i18n/uk.json5 | 2 +- 21 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/assets/i18n/ar.json5 b/src/assets/i18n/ar.json5 index 24e6e146034..1edbdf7981c 100644 --- a/src/assets/i18n/ar.json5 +++ b/src/assets/i18n/ar.json5 @@ -6459,9 +6459,9 @@ // TODO New key - Add a translation "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // TODO New key - Add a translation - "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // "submission.sections.upload.no-entry": "No", // TODO New key - Add a translation diff --git a/src/assets/i18n/bn.json5 b/src/assets/i18n/bn.json5 index 55ec1820dd3..8b903c4a65d 100644 --- a/src/assets/i18n/bn.json5 +++ b/src/assets/i18n/bn.json5 @@ -5803,7 +5803,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "অনুগ্রহ করে মনে রাখবেন যে {{collectionName}} সংগ্রহে আপলোড করা ফাইলগুলি অ্যাক্সেসযোগ্য হবে, একক ফাইলের জন্য স্পষ্টভাবে যা নির্ধারণ করা হয়েছে তা ছাড়াও, নিম্নলিখিত গ্রুপ(গুলি) সহ:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "এখানে আপনি বর্তমানে আইটেমটিতে সমস্ত ফাইল পাবেন। আপনি ফাইল মেটাডেটা এবং অ্যাক্সেস শর্তাদি আপডেট করতে পারেন অথবা অতিরিক্ত ফাইল আপলোড করুন - পৃষ্ঠাটিতে সর্বত্র ড্র্যাগ করুন এবং ড্রপ করুন ", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/ca.json5 b/src/assets/i18n/ca.json5 index 24698baac0d..246a92061cc 100644 --- a/src/assets/i18n/ca.json5 +++ b/src/assets/i18n/ca.json5 @@ -6353,7 +6353,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Tingueu en compte que els fitxers carregats a la col·lecció {{ collectionName }} seran accessibles, a més del que es decideixi explícitament per al fitxer, per als grups següents:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Aquí trobareu tots els fitxers que es troben actualment a l'ítem. Podeu actualitzar les metadades del fitxer i les condicions d'accés o incloure fitxers addicionals simplement arrossegant i deixant anar a qualsevol lloc de la pàgina", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5 index a04e89b2c3c..5ed1474384a 100644 --- a/src/assets/i18n/cs.json5 +++ b/src/assets/i18n/cs.json5 @@ -6327,9 +6327,9 @@ // TODO New key - Add a translation "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // TODO New key - Add a translation - "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // "submission.sections.upload.no-entry": "No", // TODO New key - Add a translation diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index c1979be6b6a..82d422621c3 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -5203,7 +5203,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Bitte beachten Sie, dass in diese Sammlung {{collectionName}} hochgeladene Dateien zugüglich zu dem, was für einzelne Dateien entschieden wurde, für folgende Gruppe(n) zugänglich sein:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Hier finden Sie alle Dateien, die aktuell zum Item gehören. Sie können ihre Metadaten und Zugriffsrechte bearbeiten oder weitere Dateien per Drag & Drop hinzufügen.", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 8fcac7d0409..fc4c6aa74d1 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -4581,7 +4581,7 @@ "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", - "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/es.json5 b/src/assets/i18n/es.json5 index ae41bfdcb5c..3184e4f22bf 100644 --- a/src/assets/i18n/es.json5 +++ b/src/assets/i18n/es.json5 @@ -6353,7 +6353,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Tenga en cuenta que los archivos cargados en la colección {{ collectionName }} serán accesibles, además de lo que se decida explícitamente para el fichero, para los siguientes grupos:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Aquí encontrará todos los archivos que se encuentran actualmente en el ítem. Puede actualizar los metadatos del fichero y las condiciones de acceso e incluir ficheros adicionales simplemente arrastrando-y-soltando en cualquier lugar de la página", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/fi.json5 b/src/assets/i18n/fi.json5 index 2a077006cc3..05ae06d46b5 100644 --- a/src/assets/i18n/fi.json5 +++ b/src/assets/i18n/fi.json5 @@ -4914,7 +4914,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Yksittäisten tiedostojen pääsyrajoitusten lisäksi {{collectionName}}-kokoelmaan ladatut tiedostot ovat seuraavien ryhmien saatavilla:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Tietueen kaikki tiedostot on lueteltu tässä. Voit päivittää tiedoston metadataa ja pääsyehtoja tai ladata lisää tiedostoja raahaamalla ne mihin hyvänsä sivun kohtaan", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/fr.json5 b/src/assets/i18n/fr.json5 index 381e13a743f..1e042c81fda 100644 --- a/src/assets/i18n/fr.json5 +++ b/src/assets/i18n/fr.json5 @@ -5670,7 +5670,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Veuillez noter que, en complément des accès spécifiquement accordés pour le fichier, les fichiers téléchargés dans la collection {{collectionName}} seront accessibles par défaut au(x) groupe(s) suivant(s) :", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Vous trouverez ici tous les fichiers actuellement associés à l'Item. Vous pouvez éditer les métadonnés et les niveaux d'accès de ce(s) fichier(s) ou télécharger des fichiers complémentaires simplement en les glissant n'importe où sur cette page", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/gd.json5 b/src/assets/i18n/gd.json5 index 083de54781e..45841454525 100644 --- a/src/assets/i18n/gd.json5 +++ b/src/assets/i18n/gd.json5 @@ -5801,7 +5801,7 @@ // TODO New key - Add a translation "submission.sections.upload.header.policy.default.withlist": "Thoir fa-near gum bi cothrom air faidhlichean a chaidh a luchdachadh gu cruinneachadh {{collectionName}}, cho math ris na chaidh a cho-dhùnadh airson an fhaidhle air leth, aig a' bhuidheann/na buidhnean a leanas:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "An seo gheibh thu na faidhlichean gu lèir san nì an-dràsta. Is urrainn dhut metadata an fhaidhle ùrachadh agus cothrom fhaighinn air cumhachan no faidhlichean eile a luchdachadh suas le bhith gan slaodadh agus gan leigeil às air feadh na duilleig", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/hu.json5 b/src/assets/i18n/hu.json5 index 0e73e9dbae2..bfa4a53ccf5 100644 --- a/src/assets/i18n/hu.json5 +++ b/src/assets/i18n/hu.json5 @@ -4924,7 +4924,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Kérjük, vegye figyelembe, hogy a {{collectionName}} gyűjteménybe feltöltött állományok elérhetők lesznek, azon kívül amit az egyedi állományokról kifejezetten eldöntött, a következő csoport(ok)ban:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Itt megtalálja a tárgyban lévő valamennyi állományt. Frissítheti az állomány metaadatait és hozzáférési feltételeit vagy feltölthet további állományokat azzal, hogy behúzza azokat bárhova az oldalra", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/ja.json5 b/src/assets/i18n/ja.json5 index 71b32cf70bf..83a755c9239 100644 --- a/src/assets/i18n/ja.json5 +++ b/src/assets/i18n/ja.json5 @@ -6459,9 +6459,9 @@ // TODO New key - Add a translation "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // TODO New key - Add a translation - "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // "submission.sections.upload.no-entry": "No", // TODO New key - Add a translation diff --git a/src/assets/i18n/kk.json5 b/src/assets/i18n/kk.json5 index b661ce21d35..0fd092df02c 100644 --- a/src/assets/i18n/kk.json5 +++ b/src/assets/i18n/kk.json5 @@ -6283,7 +6283,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "{{collectionName}} жинағына жүктелген файлдар жеке файл үшін нақты анықталғаннан басқа, келесі топпен (топтармен) қол жетімді болатындығын ескеріңіз:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Мұнда сіз осы элементтегі барлық файлдарды таба аласыз. Файл метадеректерін және кіру шарттарын жаңартуға немесе қосымша файлдарды олардыбетінде сүйреп апару арқылы жүктеуге болады.", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/lv.json5 b/src/assets/i18n/lv.json5 index e00ad3517b2..79ff8ce8555 100644 --- a/src/assets/i18n/lv.json5 +++ b/src/assets/i18n/lv.json5 @@ -5379,7 +5379,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Lūdzu, ņemiet vērā, ka augšupielādētie faili kolekcijā {{collectionName}} būs pieejami papildus tam, kas ir skaidri noteikts par atsevišķu failu, ar šādām grupām:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Šeit atradīsit visus failus, kas pašlaik atrodas materiālā. Varat atjaunināt failu metadatus un piekļuves nosacījumus vai augšupielādēt papildu failus, vienkārši ievelkot un atstājot tos visur lapā", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/nl.json5 b/src/assets/i18n/nl.json5 index b02e3a5276e..1ebdeaa5667 100644 --- a/src/assets/i18n/nl.json5 +++ b/src/assets/i18n/nl.json5 @@ -5752,7 +5752,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Let op: bestanden in de collectie {{collectionName}} zullen niet alleen toegankelijk zijn volgens de expliciet toegekende rechten per bestand, maar ook volgens de volgende groep(en):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Hier vindt u alle bestanden van het item. U kunt de metadata en toegangsrechten bewerken of meer bestanden toevoegen door ze naar deze pagina te slepen.", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/pt-BR.json5 b/src/assets/i18n/pt-BR.json5 index f68436d00bc..7dca26aa4e0 100644 --- a/src/assets/i18n/pt-BR.json5 +++ b/src/assets/i18n/pt-BR.json5 @@ -6066,7 +6066,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Por favor note que arquivos enviados a coleção {{collectionName}} serão acessíveis, de acordo com o que está explicitamente definido no arquivo, no(s) seguinte(s) grupo(s):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Aqui vocẽ encontra todos os arquivos que estão atualmente no item. Você pode atualizar os metadados do arquivo e condições de acesso ou enviar arquivos adicionais apenas arrastando os arquivos em qualquer lugar da página", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/pt-PT.json5 b/src/assets/i18n/pt-PT.json5 index b277e866c08..62e7c53e36c 100644 --- a/src/assets/i18n/pt-PT.json5 +++ b/src/assets/i18n/pt-PT.json5 @@ -5117,7 +5117,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Por favor note que os ficheiros enviados à coleção {{collectionName}} serão acessíveis, de acordo com o que está explicitamente definido no ficheiro, no(s) seguinte(s) grupo(s):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Aqui encontra todos os ficheiros que estão atualmente no item. Pode atualizar os metadados do ficheiro e condições de acesso ou carregar ficheiros adicionais arrastando os ficheiros em qualquer lugar desta página", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/sv.json5 b/src/assets/i18n/sv.json5 index d04b95e1444..4c9db83b167 100644 --- a/src/assets/i18n/sv.json5 +++ b/src/assets/i18n/sv.json5 @@ -5954,7 +5954,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Notera att uppladdade filer i samlingen {{collectionName}} också kommer att vara åtkompliga för följande grupp(er):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Här visas samtliga filer som ingår i posten. Du kan uppdatera filernas metadata och villkor för åtkomst, samt ladda upp nya filer genom att dra och släppa dem här", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/sw.json5 b/src/assets/i18n/sw.json5 index 5e00b545999..4f686550190 100644 --- a/src/assets/i18n/sw.json5 +++ b/src/assets/i18n/sw.json5 @@ -6459,9 +6459,9 @@ // TODO New key - Add a translation "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // TODO New key - Add a translation - "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", // "submission.sections.upload.no-entry": "No", // TODO New key - Add a translation diff --git a/src/assets/i18n/tr.json5 b/src/assets/i18n/tr.json5 index fff02c59672..92e0c5b6e29 100644 --- a/src/assets/i18n/tr.json5 +++ b/src/assets/i18n/tr.json5 @@ -4905,7 +4905,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "{{collectionName}} koleksiyonuna yüklenen dosyalara, tek dosya için açıkça karar verilenlere ek olarak aşağıdaki gruplarla erişilebilir olacağını lütfen unutmayın:", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Burada, o anda öğede bulunan tüm dosyaları bulacaksınız. Dosya metadatalarını güncelleyebilir ve koşullara erişebilir veya sayfanın her yerine sürükleyip bırakarak ek dosyalar yükleyebilirsiniz", // "submission.sections.upload.no-entry": "No", diff --git a/src/assets/i18n/uk.json5 b/src/assets/i18n/uk.json5 index 0ba5b0109ad..6ee2bd9f1c6 100644 --- a/src/assets/i18n/uk.json5 +++ b/src/assets/i18n/uk.json5 @@ -5225,7 +5225,7 @@ // "submission.sections.upload.header.policy.default.withlist": "Please note that uploaded files in the {{collectionName}} collection will be accessible, in addition to what is explicitly decided for the single file, with the following group(s):", "submission.sections.upload.header.policy.default.withlist": "Зверніть увагу, що завантажені файли в {{collectionName}} зібрання будуть доступні, для користувачів, що входять у групу(и):", - // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files just dragging & dropping them everywhere in the page", + // "submission.sections.upload.info": "Here you will find all the files currently in the item. You can update the file metadata and access conditions or upload additional files by dragging & dropping them anywhere on the page.", "submission.sections.upload.info": "Тут ви знайдете всі файли, які зараз містяться в документі. Ви можете оновити метадані файлу та умови доступу або завантажити додаткові файли, просто перетягнувши їх сюди на сторінці", // "submission.sections.upload.no-entry": "No", From b676c1ab7967234392381d4362ac0137f2b3bb4c Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Wed, 15 Feb 2023 18:43:49 +0100 Subject: [PATCH 1477/2129] [CST-8935] Fix issue with missing matcher providers --- src/app/app.module.ts | 4 ++++ src/app/shared/form/form.module.ts | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 750d63beda1..89e361821ba 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -9,6 +9,8 @@ import { RouterStateSerializer, StoreRouterConnectingModule } from '@ngrx/router import { MetaReducer, StoreModule, USER_PROVIDED_META_REDUCERS } from '@ngrx/store'; import { TranslateModule } from '@ngx-translate/core'; import { ScrollToModule } from '@nicky-lenaers/ngx-scroll-to'; +import { DYNAMIC_MATCHER_PROVIDERS } from '@ng-dynamic-forms/core'; + import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { appEffects } from './app.effects'; @@ -101,6 +103,8 @@ const PROVIDERS = [ useClass: LogInterceptor, multi: true }, + // register the dynamic matcher used by form. MUST be provided by the app module + ...DYNAMIC_MATCHER_PROVIDERS, ]; const DECLARATIONS = [ diff --git a/src/app/shared/form/form.module.ts b/src/app/shared/form/form.module.ts index 61fc7e3c390..51ebaee1b8a 100644 --- a/src/app/shared/form/form.module.ts +++ b/src/app/shared/form/form.module.ts @@ -21,7 +21,7 @@ import { DsDynamicLookupRelationExternalSourceTabComponent } from './builder/ds- import { SharedModule } from '../shared.module'; import { TranslateModule } from '@ngx-translate/core'; import { SearchModule } from '../search/search.module'; -import { DYNAMIC_FORM_CONTROL_MAP_FN, DYNAMIC_MATCHER_PROVIDERS, DynamicFormLayoutService, DynamicFormsCoreModule, DynamicFormService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; +import { DYNAMIC_FORM_CONTROL_MAP_FN, DynamicFormLayoutService, DynamicFormsCoreModule, DynamicFormService, DynamicFormValidationService } from '@ng-dynamic-forms/core'; import { ExistingMetadataListElementComponent } from './builder/ds-dynamic-form-ui/existing-metadata-list-element/existing-metadata-list-element.component'; import { ExistingRelationListElementComponent } from './builder/ds-dynamic-form-ui/existing-relation-list-element/existing-relation-list-element.component'; import { ExternalSourceEntryImportModalComponent } from './builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component'; @@ -101,7 +101,6 @@ const DIRECTIVES = [ provide: DYNAMIC_FORM_CONTROL_MAP_FN, useValue: dsDynamicFormControlMapFn }, - ...DYNAMIC_MATCHER_PROVIDERS, VocabularyTreeviewService, DynamicFormLayoutService, DynamicFormService, From 938bf33ad24bc8d0545c8fc936bfc6bcaadf93d0 Mon Sep 17 00:00:00 2001 From: aroman-arvo Date: Wed, 15 Feb 2023 19:20:20 +0100 Subject: [PATCH 1478/2129] DS-8404 - fix config param name --- config/config.example.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/config.example.yml b/config/config.example.yml index 7c784b4a8e9..f1e6be76aa8 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -372,5 +372,5 @@ vocabularies: # Default collection/community sorting order at Advanced search, Create/update community and collection when there are not a query. comcolSelectionSort: - sortMetadata: 'dc.title' + sortField: 'dc.title' sortDirection: 'ASC' \ No newline at end of file From 028d4192bb7e4f0f69f60b02b7912d5982b49de7 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 15 Feb 2023 11:37:37 +0100 Subject: [PATCH 1479/2129] translation fixes in security form --- src/assets/i18n/de.json5 | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index 82d422621c3..6c8eb4bc8f6 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -3838,17 +3838,17 @@ // "profile.security.form.error.matching-passwords": "The passwords do not match.", "profile.security.form.error.matching-passwords": "Die Passwörter stimmen nicht überein.", - // "profile.security.form.error.password-length": "The password should be at least 6 characters long.", - "profile.security.form.error.password-length": "Das Passwort sollte mindestens 6 Zeichen lang sein.", - // "profile.security.form.info": "Optionally, you can enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", - "profile.security.form.info": "Optional können Sie ein neues Passwort in das Feld darunter eingeben und es durch erneute Eingabe in das zweite Feld bestätigen. Es sollte mindestens sechs Zeichen lang sein.", + "profile.security.form.info": "Im nachfolgenden Feld können Sie bei Bedarf ein neues Passwort eingeben und es durch erneute Eingabe in das zweite Feld bestätigen. Es sollte mindestens sechs Zeichen lang sein.", // "profile.security.form.label.password": "Password", "profile.security.form.label.password": "Passwort", // "profile.security.form.label.passwordrepeat": "Retype to confirm", - "profile.security.form.label.passwordrepeat": "Zum Bestätigen erneut eingeben", + "profile.security.form.label.passwordrepeat": "Zum Bestätigen das Passwort erneut eingeben", + + // "profile.security.form.label.current-password": "Current password" + "profile.security.form.label.current-password": "Ihr aktuelles Passwort" // "profile.security.form.notifications.success.content": "Your changes to the password were saved.", "profile.security.form.notifications.success.content": "Ihr geändertes Passwort wurde gespeichert.", @@ -3862,8 +3862,14 @@ // "profile.security.form.notifications.error.not-long-enough": "The password has to be at least 6 characters long.", "profile.security.form.notifications.error.not-long-enough": "Das Passwort sollte mindestens 6 Zeichen lang sein.", + // "profile.security.form.notifications.error.change-failed": "An error occurred while trying to change the password. Please check if the current password is correct.", + "profile.security.form.notifications.error.change-failed": "Es ist ein Fehler beim Ändern des Passworts aufgetreten. Bitte überprüfen Sie, ob Ihr aktuelles Passwort korrekt eingegeben wurde.", + // "profile.security.form.notifications.error.not-same": "The provided passwords are not the same.", "profile.security.form.notifications.error.not-same": "Die angegebenen Passwörter sind nicht identisch.", + + // "profile.security.form.notifications.error.general": "Please fill required fields of security form.", + "profile.security.form.notifications.error.general": "Bitte füllen Sie alle Pflichtfelder im Formular aus.", // "profile.title": "Update Profile", "profile.title": "Profil aktualisieren", From 3ed9ae2d3ea343767c362e223c4579cbc7bda419 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 15 Feb 2023 12:14:42 +0100 Subject: [PATCH 1480/2129] remove minimum passwort length value from translated messages --- src/assets/i18n/de.json5 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index 6c8eb4bc8f6..e5d074d7f58 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -1982,8 +1982,8 @@ // "forgot-password.form.head": "Forgot Password", "forgot-password.form.head": "Passwort vergessen", - // "forgot-password.form.info": "Enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", - "forgot-password.form.info": "Bitte geben Sie ein neues Passwort (mindestens sechs Zeichen) ein und bestätigen Sie es erneut.", + // "forgot-password.form.info": "Enter a new password in the box below, and confirm it by typing it again into the second box.", + "forgot-password.form.info": "Bitte geben Sie ein neues Passwort ein und bestätigen Sie es erneut.", // "forgot-password.form.card.security": "Security", "forgot-password.form.card.security": "Sicherheit", @@ -3838,8 +3838,8 @@ // "profile.security.form.error.matching-passwords": "The passwords do not match.", "profile.security.form.error.matching-passwords": "Die Passwörter stimmen nicht überein.", - // "profile.security.form.info": "Optionally, you can enter a new password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", - "profile.security.form.info": "Im nachfolgenden Feld können Sie bei Bedarf ein neues Passwort eingeben und es durch erneute Eingabe in das zweite Feld bestätigen. Es sollte mindestens sechs Zeichen lang sein.", + // "profile.security.form.info": "Optionally, you can enter a new password in the box below, and confirm it by typing it again into the second box.", + "profile.security.form.info": "Im nachfolgenden Feld können Sie bei Bedarf ein neues Passwort eingeben und es durch erneute Eingabe in das zweite Feld bestätigen.", // "profile.security.form.label.password": "Password", "profile.security.form.label.password": "Passwort", @@ -3975,8 +3975,8 @@ // "register-page.create-profile.security.header": "Security", "register-page.create-profile.security.header": "Sicherheit", - // "register-page.create-profile.security.info": "Please enter a password in the box below, and confirm it by typing it again into the second box. It should be at least six characters long.", - "register-page.create-profile.security.info": "Bitte geben Sie ein Passwort in das unten stehende Feld ein und bestätigen Sie es, indem Sie es in das zweite Feld erneut eingeben. Es sollte mindestens sechs Zeichen lang sein.", + // "register-page.create-profile.security.info": "Please enter a password in the box below, and confirm it by typing it again into the second box.", + "register-page.create-profile.security.info": "Bitte geben Sie ein Passwort in das unten stehende Feld ein und bestätigen Sie es, indem Sie es in das zweite Feld erneut eingeben.", // "register-page.create-profile.security.label.password": "Password *", "register-page.create-profile.security.label.password": "Passwort *", From 26705a5cf75b4301991f1edbfa4994b4c55e3800 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 15 Feb 2023 18:32:54 +0100 Subject: [PATCH 1481/2129] fixed missing comma --- src/assets/i18n/de.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index e5d074d7f58..9dbd7032554 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -3848,7 +3848,7 @@ "profile.security.form.label.passwordrepeat": "Zum Bestätigen das Passwort erneut eingeben", // "profile.security.form.label.current-password": "Current password" - "profile.security.form.label.current-password": "Ihr aktuelles Passwort" + "profile.security.form.label.current-password": "Ihr aktuelles Passwort", // "profile.security.form.notifications.success.content": "Your changes to the password were saved.", "profile.security.form.notifications.success.content": "Ihr geändertes Passwort wurde gespeichert.", From e5e6639d214adc7d5e52003577618a2cbf0d40c0 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 15 Feb 2023 18:34:02 +0100 Subject: [PATCH 1482/2129] added comma to default translation --- src/assets/i18n/de.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/i18n/de.json5 b/src/assets/i18n/de.json5 index 9dbd7032554..df4c2cb4ee5 100644 --- a/src/assets/i18n/de.json5 +++ b/src/assets/i18n/de.json5 @@ -3847,7 +3847,7 @@ // "profile.security.form.label.passwordrepeat": "Retype to confirm", "profile.security.form.label.passwordrepeat": "Zum Bestätigen das Passwort erneut eingeben", - // "profile.security.form.label.current-password": "Current password" + // "profile.security.form.label.current-password": "Current password", "profile.security.form.label.current-password": "Ihr aktuelles Passwort", // "profile.security.form.notifications.success.content": "Your changes to the password were saved.", From bf22eb5582e7ff76483a9d6d95b1061af1b2a41a Mon Sep 17 00:00:00 2001 From: cris Date: Wed, 15 Feb 2023 22:14:31 +0000 Subject: [PATCH 1483/2129] suggestionOption.name displayed --- .../dso-input-suggestions/dso-input-suggestions.component.html | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.html b/src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.html index 7515b830b94..64c88bbd786 100644 --- a/src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.html +++ b/src/app/shared/input-suggestions/dso-input-suggestions/dso-input-suggestions.component.html @@ -14,6 +14,7 @@ diff --git a/src/app/home-page/home-page.module.ts b/src/app/home-page/home-page.module.ts index d304c786966..1ab7d751b03 100644 --- a/src/app/home-page/home-page.module.ts +++ b/src/app/home-page/home-page.module.ts @@ -9,11 +9,13 @@ import { TopLevelCommunityListComponent } from './top-level-community-list/top-l import { StatisticsModule } from '../statistics/statistics.module'; import { ThemedHomeNewsComponent } from './home-news/themed-home-news.component'; import { ThemedHomePageComponent } from './themed-home-page.component'; +import { ThemedTopLevelCommunityListComponent } from './top-level-community-list/themed-top-level-community-list.component'; const DECLARATIONS = [ HomePageComponent, ThemedHomePageComponent, TopLevelCommunityListComponent, + ThemedTopLevelCommunityListComponent, ThemedHomeNewsComponent, HomeNewsComponent, ]; diff --git a/src/app/home-page/top-level-community-list/themed-top-level-community-list.component.ts b/src/app/home-page/top-level-community-list/themed-top-level-community-list.component.ts new file mode 100644 index 00000000000..6eb74cc0a92 --- /dev/null +++ b/src/app/home-page/top-level-community-list/themed-top-level-community-list.component.ts @@ -0,0 +1,25 @@ +import { Component } from '@angular/core'; +import { TopLevelCommunityListComponent } from './top-level-community-list.component'; +import { ThemedComponent } from '../../shared/theme-support/themed.component'; + +@Component({ + selector: 'ds-themed-top-level-community-list', + styleUrls: [], + templateUrl: '../../shared/theme-support/themed.component.html', +}) +export class ThemedTopLevelCommunityListComponent extends ThemedComponent { + protected inAndOutputNames: (keyof TopLevelCommunityListComponent & keyof this)[]; + + protected getComponentName(): string { + return 'TopLevelCommunityListComponent'; + } + + protected importThemedComponent(themeName: string): Promise { + return import(`../../../themes/${themeName}/app/home-page/top-level-community-list/top-level-community-list.component`); + } + + protected importUnthemedComponent(): Promise { + return import(`./top-level-community-list.component`); + } + +} diff --git a/src/themes/custom/app/home-page/top-level-community-list/top-level-community-list.component.html b/src/themes/custom/app/home-page/top-level-community-list/top-level-community-list.component.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/themes/custom/app/home-page/top-level-community-list/top-level-community-list.component.scss b/src/themes/custom/app/home-page/top-level-community-list/top-level-community-list.component.scss new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/themes/custom/app/home-page/top-level-community-list/top-level-community-list.component.ts b/src/themes/custom/app/home-page/top-level-community-list/top-level-community-list.component.ts new file mode 100644 index 00000000000..b52cb1439cd --- /dev/null +++ b/src/themes/custom/app/home-page/top-level-community-list/top-level-community-list.component.ts @@ -0,0 +1,13 @@ +import { Component } from '@angular/core'; +import { TopLevelCommunityListComponent as BaseComponent } from '../../../../../app/home-page/top-level-community-list/top-level-community-list.component'; + +@Component({ + selector: 'ds-top-level-community-list', + // styleUrls: ['./top-level-community-list.component.scss'], + styleUrls: ['../../../../../app/home-page/top-level-community-list/top-level-community-list.component.scss'], + // templateUrl: './top-level-community-list.component.html' + templateUrl: '../../../../../app/home-page/top-level-community-list/top-level-community-list.component.html' +}) + +export class TopLevelCommunityListComponent extends BaseComponent {} + diff --git a/src/themes/custom/theme.module.ts b/src/themes/custom/theme.module.ts index e2e97b90873..db3bf197a61 100644 --- a/src/themes/custom/theme.module.ts +++ b/src/themes/custom/theme.module.ts @@ -84,6 +84,7 @@ import { SearchModule } from '../../app/shared/search/search.module'; import { ResourcePoliciesModule } from '../../app/shared/resource-policies/resource-policies.module'; import { ComcolModule } from '../../app/shared/comcol/comcol.module'; import { FeedbackComponent } from './app/info/feedback/feedback.component'; +import { TopLevelCommunityListComponent } from './app/home-page/top-level-community-list/top-level-community-list.component'; const DECLARATIONS = [ FileSectionComponent, @@ -126,7 +127,8 @@ const DECLARATIONS = [ NavbarComponent, HeaderNavbarWrapperComponent, BreadcrumbsComponent, - FeedbackComponent + FeedbackComponent, + TopLevelCommunityListComponent, ]; @NgModule({ From efe1d1085a1f5bcddce4c1489033edda4ca46b1c Mon Sep 17 00:00:00 2001 From: lotte Date: Wed, 22 Feb 2023 16:12:40 +0100 Subject: [PATCH 1501/2129] Moved TopLevelCommunityComponent to Eager module --- src/themes/custom/eager-theme.module.ts | 3 +- src/themes/custom/lazy-theme.module.ts | 37 ++++++------------------- 2 files changed, 11 insertions(+), 29 deletions(-) diff --git a/src/themes/custom/eager-theme.module.ts b/src/themes/custom/eager-theme.module.ts index 4e3c6f8b464..ad9f4b70642 100644 --- a/src/themes/custom/eager-theme.module.ts +++ b/src/themes/custom/eager-theme.module.ts @@ -43,6 +43,7 @@ import { import { CommunityListElementComponent } from './app/shared/object-list/community-list-element/community-list-element.component'; import { CollectionListElementComponent} from './app/shared/object-list/collection-list-element/collection-list-element.component'; +import { TopLevelCommunityListComponent } from './app/home-page/top-level-community-list/top-level-community-list.component'; /** @@ -55,9 +56,9 @@ const ENTRY_COMPONENTS = [ JournalVolumeComponent, PublicationComponent, UntypedItemComponent, - CommunityListElementComponent, CollectionListElementComponent, + TopLevelCommunityListComponent, ]; const DECLARATIONS = [ diff --git a/src/themes/custom/lazy-theme.module.ts b/src/themes/custom/lazy-theme.module.ts index 6050afef722..1623132d03d 100644 --- a/src/themes/custom/lazy-theme.module.ts +++ b/src/themes/custom/lazy-theme.module.ts @@ -55,12 +55,8 @@ import { PageNotFoundComponent } from './app/pagenotfound/pagenotfound.component import { ObjectNotFoundComponent } from './app/lookup-by-id/objectnotfound/objectnotfound.component'; import { ForbiddenComponent } from './app/forbidden/forbidden.component'; import { PrivacyComponent } from './app/info/privacy/privacy.component'; -import { - CollectionStatisticsPageComponent -} from './app/statistics-page/collection-statistics-page/collection-statistics-page.component'; -import { - CommunityStatisticsPageComponent -} from './app/statistics-page/community-statistics-page/community-statistics-page.component'; +import { CollectionStatisticsPageComponent } from './app/statistics-page/collection-statistics-page/collection-statistics-page.component'; +import { CommunityStatisticsPageComponent } from './app/statistics-page/community-statistics-page/community-statistics-page.component'; import { ItemStatisticsPageComponent } from './app/statistics-page/item-statistics-page/item-statistics-page.component'; import { SiteStatisticsPageComponent } from './app/statistics-page/site-statistics-page/site-statistics-page.component'; import { CommunityPageComponent } from './app/community-page/community-page.component'; @@ -76,45 +72,31 @@ import { ProfilePageComponent } from './app/profile-page/profile-page.component' import { RegisterEmailComponent } from './app/register-page/register-email/register-email.component'; import { MyDSpacePageComponent } from './app/my-dspace-page/my-dspace-page.component'; import { SubmissionEditComponent } from './app/submission/edit/submission-edit.component'; -import { - SubmissionImportExternalComponent -} from './app/submission/import-external/submission-import-external.component'; +import { SubmissionImportExternalComponent } from './app/submission/import-external/submission-import-external.component'; import { SubmissionSubmitComponent } from './app/submission/submit/submission-submit.component'; -import { WorkflowItemDeleteComponent -} from './app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component'; -import { - WorkflowItemSendBackComponent -} from './app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component'; +import { WorkflowItemDeleteComponent } from './app/workflowitems-edit-page/workflow-item-delete/workflow-item-delete.component'; +import { WorkflowItemSendBackComponent } from './app/workflowitems-edit-page/workflow-item-send-back/workflow-item-send-back.component'; import { BreadcrumbsComponent } from './app/breadcrumbs/breadcrumbs.component'; import { FeedbackComponent } from './app/info/feedback/feedback.component'; import { CommunityListComponent } from './app/community-list-page/community-list/community-list.component'; import { ComcolPageHandleComponent } from './app/shared/comcol-page-handle/comcol-page-handle.component'; import { AuthNavMenuComponent } from './app/shared/auth-nav-menu/auth-nav-menu.component'; -import { - ExpandableNavbarSectionComponent -} from './app/navbar/expandable-navbar-section/expandable-navbar-section.component'; +import { ExpandableNavbarSectionComponent } from './app/navbar/expandable-navbar-section/expandable-navbar-section.component'; import { ItemMetadataComponent } from './app/item-page/edit-item-page/item-metadata/item-metadata.component'; -import { - EditItemTemplatePageComponent -} from './app/collection-page/edit-item-template-page/edit-item-template-page.component'; +import { EditItemTemplatePageComponent } from './app/collection-page/edit-item-template-page/edit-item-template-page.component'; import { LoadingComponent } from './app/shared/loading/loading.component'; import { SearchResultsComponent } from './app/shared/search/search-results/search-results.component'; import { AdminSidebarComponent } from './app/admin/admin-sidebar/admin-sidebar.component'; import { ComcolPageBrowseByComponent } from './app/shared/comcol-page-browse-by/comcol-page-browse-by.component'; import { SearchSettingsComponent } from './app/shared/search/search-settings/search-settings.component'; -import { - CommunityPageSubCommunityListComponent -} from './app/community-page/sub-community-list/community-page-sub-community-list.component'; -import { - CommunityPageSubCollectionListComponent -} from './app/community-page/sub-collection-list/community-page-sub-collection-list.component'; +import { CommunityPageSubCommunityListComponent } from './app/community-page/sub-community-list/community-page-sub-community-list.component'; +import { CommunityPageSubCollectionListComponent } from './app/community-page/sub-collection-list/community-page-sub-collection-list.component'; import { ObjectListComponent } from './app/shared/object-list/object-list.component'; import { BrowseByMetadataPageComponent } from './app/browse-by/browse-by-metadata-page/browse-by-metadata-page.component'; import { BrowseByDatePageComponent } from './app/browse-by/browse-by-date-page/browse-by-date-page.component'; import { BrowseByTitlePageComponent } from './app/browse-by/browse-by-title-page/browse-by-title-page.component'; -import { TopLevelCommunityListComponent } from './app/home-page/top-level-community-list/top-level-community-list.component'; const DECLARATIONS = [ FileSectionComponent, @@ -169,7 +151,6 @@ const DECLARATIONS = [ BrowseByMetadataPageComponent, BrowseByDatePageComponent, BrowseByTitlePageComponent, - TopLevelCommunityListComponent, ]; @NgModule({ From feb2d09d5a026cd6098db827c3d2b7b4714d86a4 Mon Sep 17 00:00:00 2001 From: Lucky Date: Thu, 23 Feb 2023 13:59:05 +0530 Subject: [PATCH 1502/2129] CSS changed for login-container #1952 --- src/app/shared/log-in/log-in.component.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/shared/log-in/log-in.component.scss b/src/app/shared/log-in/log-in.component.scss index caaeef3dc76..3bd4023500c 100644 --- a/src/app/shared/log-in/log-in.component.scss +++ b/src/app/shared/log-in/log-in.component.scss @@ -1,3 +1,3 @@ .login-container { - max-width: 350px; + max-width: 450px; } From ab78df2e6835a4720acf7d2b0f15045cd3c8d563 Mon Sep 17 00:00:00 2001 From: lotte Date: Thu, 23 Feb 2023 11:08:23 +0100 Subject: [PATCH 1503/2129] Fixes after merge --- .../dso-edit-metadata-value.component.html | 2 +- ...-declined-task-search-result-list-element.component.html | 1 - ...ed-declined-task-search-result-list-element.component.ts | 6 ------ .../claimed-search-result-list-element.component.html | 3 +-- .../pool-search-result-list-element.component.html | 3 +-- src/app/shared/shared.module.ts | 1 - .../subscription-modal/subscription-modal.component.html | 2 +- .../subscription-view/subscription-view.component.html | 2 +- 8 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html index f54dde4971c..525b42610b4 100644 --- a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html +++ b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html @@ -7,7 +7,7 @@ [dsDebounce]="300" (onDebounce)="confirm.emit(false)">
diff --git a/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-declined-task-search-result/claimed-declined-task-search-result-list-element.component.html b/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-declined-task-search-result/claimed-declined-task-search-result-list-element.component.html index a8ec21fa6ca..50e8870fd8c 100644 --- a/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-declined-task-search-result/claimed-declined-task-search-result-list-element.component.html +++ b/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-declined-task-search-result/claimed-declined-task-search-result-list-element.component.html @@ -4,7 +4,6 @@

{{ 'claimed-declined-task-search-result-list-elem

diff --git a/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-declined-task-search-result/claimed-declined-task-search-result-list-element.component.ts b/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-declined-task-search-result/claimed-declined-task-search-result-list-element.component.ts index 131f4b67302..620513fe6a3 100644 --- a/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-declined-task-search-result/claimed-declined-task-search-result-list-element.component.ts +++ b/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-declined-task-search-result/claimed-declined-task-search-result-list-element.component.ts @@ -4,7 +4,6 @@ import { ClaimedDeclinedTaskTaskSearchResult } from 'src/app/shared/object-colle import { ViewMode } from '../../../../../core/shared/view-mode.model'; import { LinkService } from '../../../../../core/cache/builders/link.service'; import { TruncatableService } from '../../../../truncatable/truncatable.service'; -import { MyDspaceItemStatusType } from '../../../../object-collection/shared/mydspace-item-status/my-dspace-item-status-type'; import { Observable } from 'rxjs'; import { RemoteData } from '../../../../../core/data/remote-data'; import { WorkflowItem } from '../../../../../core/submission/models/workflowitem.model'; @@ -31,11 +30,6 @@ export class ClaimedDeclinedTaskSearchResultListElementComponent extends SearchR */ public showSubmitter = true; - /** - * Represent item's status - */ - public status = MyDspaceItemStatusType.DECLINED_TASk; - /** * The workflowitem object that belonging to the result object */ diff --git a/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-search-result-list-element.component.html b/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-search-result-list-element.component.html index d3bcfc20dc7..99d1bca1356 100644 --- a/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-search-result-list-element.component.html +++ b/src/app/shared/object-list/my-dspace-result-list-element/claimed-search-result/claimed-search-result-list-element.component.html @@ -3,8 +3,7 @@ [object]="object" [showSubmitter]="showSubmitter" [context]="childContext" - [workflowItem]="workflowitem$.value" - [status]="status"> + [workflowItem]="workflowitem$.value">
diff --git a/src/app/shared/object-list/my-dspace-result-list-element/pool-search-result/pool-search-result-list-element.component.html b/src/app/shared/object-list/my-dspace-result-list-element/pool-search-result/pool-search-result-list-element.component.html index 9ee1e022f33..d27c8a11c50 100644 --- a/src/app/shared/object-list/my-dspace-result-list-element/pool-search-result/pool-search-result-list-element.component.html +++ b/src/app/shared/object-list/my-dspace-result-list-element/pool-search-result/pool-search-result-list-element.component.html @@ -3,8 +3,7 @@ [object]="object" [showSubmitter]="showSubmitter" [context]="childContext" - [workflowItem]="workflowitem$.value" - [status]="status"> + [workflowItem]="workflowitem$.value">
{{'subscriptions.modal.title' | translate}}

diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.ts b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.ts index 8e4a7008afe..1925099418a 100644 --- a/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.ts +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-expandable-menu-section/dso-edit-menu-expandable-section.component.ts @@ -13,7 +13,6 @@ import { hasValue } from '../../../empty.util'; * Represents an expandable section in the dso edit menus */ @Component({ - /* tslint:disable:component-selector */ selector: 'ds-dso-edit-menu-expandable-section', templateUrl: './dso-edit-menu-expandable-section.component.html', styleUrls: ['./dso-edit-menu-expandable-section.component.scss'], diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.ts b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.ts index af3381ef716..060049ef5fc 100644 --- a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.ts +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.ts @@ -10,7 +10,6 @@ import { MenuSection } from '../../../menu/menu-section.model'; * Represents a non-expandable section in the dso edit menus */ @Component({ - /* tslint:disable:component-selector */ selector: 'ds-dso-edit-menu-section', templateUrl: './dso-edit-menu-section.component.html', styleUrls: ['./dso-edit-menu-section.component.scss'] diff --git a/src/themes/dspace/app/navbar/navbar.component.html b/src/themes/dspace/app/navbar/navbar.component.html index d9631aad182..c14671cf683 100644 --- a/src/themes/dspace/app/navbar/navbar.component.html +++ b/src/themes/dspace/app/navbar/navbar.component.html @@ -10,9 +10,9 @@
  • - +
  • - +
  • - diff --git a/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts index 804ae634913..d5a5dee1f5e 100644 --- a/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts +++ b/src/app/shared/form/vocabulary-treeview/vocabulary-treeview.component.ts @@ -293,6 +293,15 @@ export class VocabularyTreeviewComponent implements OnDestroy, OnInit, OnChanges } } + add() { + const userVocabularyEntry = { + value: this.searchText, + display: this.searchText, + } as VocabularyEntryDetail; + this.select.emit(userVocabularyEntry); + } + + /** * Unsubscribe from all subscriptions */ diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5 index 3b3578fac5d..741ff0ffc9c 100644 --- a/src/assets/i18n/en.json5 +++ b/src/assets/i18n/en.json5 @@ -5240,4 +5240,6 @@ "access-control-option-end-date-note": "Select the date until which the related access condition is applied", + "vocabulary-treeview.search.form.add": "Add", + } From e815b1d938066b06ec4ec887e1866327affaea7b Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Wed, 8 Nov 2023 12:00:46 +0100 Subject: [PATCH 2090/2129] 108055: add user input to tag list (cherry picked from commit aac58e612d7fb01f87dc7a6a46b92c9c4c2fe685) --- .../models/tag/dynamic-tag.component.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts index 4abb68a53be..7805dad1f32 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/models/tag/dynamic-tag.component.ts @@ -89,6 +89,18 @@ export class DsDynamicTagComponent extends DsDynamicVocabularyComponent implemen } }), map((list: PaginatedList) => list.page), + // Add user input as last item of the list + map((list: VocabularyEntry[]) => { + if (list && list.length > 0) { + if (isNotEmpty(this.currentValue)) { + let vocEntry = new VocabularyEntry(); + vocEntry.display = this.currentValue; + vocEntry.value = this.currentValue; + list.push(vocEntry); + } + } + return list; + }), tap(() => this.changeSearchingStatus(false)), merge(this.hideSearchingWhenUnsubscribed)); From bc21085398cfa976893de3b097a6fc3100240784 Mon Sep 17 00:00:00 2001 From: Andreas Mahnke Date: Wed, 25 Oct 2023 16:10:05 +0200 Subject: [PATCH 2091/2129] Support type-bind of elements based on repeatable list type-bound element (CHECKBOX_GROUP) (cherry picked from commit 09aaa46875146081cf812ed6f904178740ae8d30) --- .../ds-dynamic-type-bind-relation.service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts index d5e735ed1a9..5f7e2e3e228 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-type-bind-relation.service.ts @@ -183,7 +183,8 @@ export class DsDynamicTypeBindRelationService { const initValue = (hasNoValue(relatedModel.value) || typeof relatedModel.value === 'string') ? relatedModel.value : (Array.isArray(relatedModel.value) ? relatedModel.value : relatedModel.value.value); - const valueChanges = relatedModel.valueChanges.pipe( + const updateSubject = (relatedModel.type === 'CHECKBOX_GROUP' ? relatedModel.valueUpdates : relatedModel.valueChanges); + const valueChanges = updateSubject.pipe( startWith(initValue) ); From 0d0c2dac17ecd9af8217e9231288af9bed865a50 Mon Sep 17 00:00:00 2001 From: Davide Negretti Date: Mon, 30 Oct 2023 18:27:00 +0100 Subject: [PATCH 2092/2129] [DURACOM-195] Simplify vertical spacing in header and breadcrumbs (cherry picked from commit a3e6d9b09a2d6e529dc28f7d1a1924b2830077e6) --- src/app/breadcrumbs/breadcrumbs.component.html | 2 +- src/app/breadcrumbs/breadcrumbs.component.scss | 5 ++--- src/app/home-page/home-news/home-news.component.html | 2 +- src/app/home-page/home-news/home-news.component.scss | 2 -- src/app/root/root.component.html | 4 ++-- src/styles/_custom_variables.scss | 2 +- src/styles/_global-styles.scss | 10 ++++++++-- .../app/home-page/home-news/home-news.component.html | 2 +- .../app/home-page/home-news/home-news.component.scss | 1 - 9 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/app/breadcrumbs/breadcrumbs.component.html b/src/app/breadcrumbs/breadcrumbs.component.html index bff792eeff4..3bba89622ff 100644 --- a/src/app/breadcrumbs/breadcrumbs.component.html +++ b/src/app/breadcrumbs/breadcrumbs.component.html @@ -1,6 +1,6 @@