diff --git a/dbrepo-ui/components/search/AdvancedSearch.vue b/dbrepo-ui/components/search/AdvancedSearch.vue index 0054eaaea6cc55130058d32efd84ecc42612ba1e..c07d472756b7dc5d6c2b16a0bf791fcbaa7284da 100644 --- a/dbrepo-ui/components/search/AdvancedSearch.vue +++ b/dbrepo-ui/components/search/AdvancedSearch.vue @@ -91,7 +91,7 @@ <v-autocomplete v-if="field.attr_name === 'licenses'" v-model="advancedSearchData[field.attr_name]" - :items="fetchLicenses" + :items="licenses" :variant="inputVariant" :label="field.attr_friendly_name" clearable @@ -216,6 +216,7 @@ export default { showAdvancedSearch: false, concepts: [], units: [], + licenses: [], yearFrom: null, yearFromItems: [ { name: `Since ${new Date().getFullYear()}`, value: new Date().getFullYear() }, @@ -236,14 +237,14 @@ export default { unit: ['tables.columns.unit.uri'] }, fieldItems: [ - { name: 'Database', value: 'database' }, - { name: 'Table', value: 'table' }, - { name: 'Column', value: 'column' }, - { name: 'User', value: 'user' }, - { name: 'Identifier', value: 'identifier' }, - { name: 'Concept', value: 'concept' }, - { name: 'Unit', value: 'unit' }, - { name: 'View', value: 'view' } + { name: this.$t('pages.search.types.database'), value: 'database' }, + { name: this.$t('pages.search.types.table'), value: 'table' }, + { name: this.$t('pages.search.types.column'), value: 'column' }, + { name: this.$t('pages.search.types.user'), value: 'user' }, + { name: this.$t('pages.search.types.identifier'), value: 'identifier' }, + { name: this.$t('pages.search.types.concept'), value: 'concept' }, + { name: this.$t('pages.search.types.unit'), value: 'unit' }, + { name: this.$t('pages.search.types.view'), value: 'view' } ], booleanItems: [ { name: 'True', value: true }, @@ -319,6 +320,7 @@ export default { this.initFieldsFromRoute() this.initSearch(this.searchType) this.advancedSearch() + this.fetchLicenses() const conceptService = useConceptService() conceptService.findAll() .then((response) => { @@ -383,12 +385,10 @@ export default { } return shouldBeRendered }, - fetchLicenses () { - // Licenses is a nested object in the backend, but without any values. - // Instead, we define our custom license generator with a controlled vocabulary. - return [ - 'Apache-2.0', 'BSD-3-Clause', 'BSD-4-Clause', 'CC-BY-4.0', 'CC0-1.0', 'GPL-3.0-only', 'MIT' - ] + async fetchLicenses () { + const licenseService = useLicenseService() + const licenses = await licenseService.findAll() + this.licenses = licenses.map(l => l.identifier) }, initSearch (searchType) { this.resetAdvancedSearchFields() diff --git a/dbrepo-ui/composables/concept-service.ts b/dbrepo-ui/composables/concept-service.ts index 239589aa65930cdfad83c4d7c89807435e522072..6b33e281a8b228419ebe75dbbb454594aded7ded 100644 --- a/dbrepo-ui/composables/concept-service.ts +++ b/dbrepo-ui/composables/concept-service.ts @@ -2,13 +2,13 @@ export const useConceptService = (): any => { async function findAll () { const axios = useAxiosInstance() return new Promise((resolve, reject) => { - axios.get('/api/semantic/concept', { headers: { Accept: 'application/json' } }) + axios.get('/api/semantic/concept') .then((response) => { - const concepts = response.data - console.debug('response concepts', concepts) - resolve(concepts) + console.info('Found concept(s)') + resolve(response.data) }) .catch((error) => { + console.error('Failed to find concepts', error) reject(error) }) }) diff --git a/dbrepo-ui/composables/container-service.ts b/dbrepo-ui/composables/container-service.ts index 1e48cf8caf0baac11f508698b88e004ace3f96d1..e9715c98247d6ac5b511df772a1fc8c8b68ce61a 100644 --- a/dbrepo-ui/composables/container-service.ts +++ b/dbrepo-ui/composables/container-service.ts @@ -5,7 +5,7 @@ export const useContainerService = (): any => { return new Promise<ContainerBriefDto[]>((resolve, reject) => { axios.get<ContainerBriefDto[]>('/api/container') .then((response) => { - console.info('Found container(s)') + console.info(`Found ${response.data.length} container(s)`) resolve(response.data) }) .catch((error) => { diff --git a/dbrepo-ui/composables/database-service.ts b/dbrepo-ui/composables/database-service.ts index 575945458de8638c985420b07eda62adb208e484..0e6299502c37b67b3b647db083be9292c895b522 100644 --- a/dbrepo-ui/composables/database-service.ts +++ b/dbrepo-ui/composables/database-service.ts @@ -5,7 +5,7 @@ export const useDatabaseService = (): any => { return new Promise((resolve, reject) => { axios.get<DatabaseBriefDto[]>('/api/database') .then((response) => { - console.info('Found database(s)'); + console.info(`Found ${response.data.length} database(s)`); resolve(response.data); }) .catch((error) => { diff --git a/dbrepo-ui/composables/identifier-service.ts b/dbrepo-ui/composables/identifier-service.ts index 5e411c874d6a6fc1807c5b9793b8696942e7188e..268dc8d3f74bd1ed9cb78f24a3edf768fba43236 100644 --- a/dbrepo-ui/composables/identifier-service.ts +++ b/dbrepo-ui/composables/identifier-service.ts @@ -28,7 +28,7 @@ export const useIdentifierService = (): any => { return new Promise<IdentifierDto>((resolve, reject) => { axios.post<IdentifierDto>('/api/identifier', data) .then((response) => { - console.info('Created identifier') + console.info('Created identifier with id', response.data.id) resolve(response.data) }) .catch((error) => { diff --git a/dbrepo-ui/composables/license-service.ts b/dbrepo-ui/composables/license-service.ts index ef6cc03d2c780a6b620fced13b0ed23a3d3af61b..fcbdf05f700896c373b7b1bbba8daa2508ad5e89 100644 --- a/dbrepo-ui/composables/license-service.ts +++ b/dbrepo-ui/composables/license-service.ts @@ -1,15 +1,18 @@ export const useLicenseService = (): any => { async function findAll(): Promise<LicenseDto[]> { const axios = useAxiosInstance() - try { - console.debug('find licenses') - const {data} = await axios.get<LicenseDto[]>('/api/database/license') - console.info('Found license(s)') - return data - } catch (error) { - console.error('Failed to find licenses', error) - return [] - } + console.debug('find licenses') + return new Promise<LicenseDto[]>((resolve, reject) => { + axios.get<LicenseDto[]>('/api/database/license') + .then((response) => { + console.info('Found license(s)') + resolve(response.data) + }) + .catch((error) => { + console.error('Failed to find licenses') + reject(error) + }) + }) } return {findAll} diff --git a/dbrepo-ui/composables/ontology-service.ts b/dbrepo-ui/composables/ontology-service.ts index c37244323147c7a0ae2638ea36d3e79422df62cc..56a38d7e6beb81a9c1c3b4e53d2f9c4f0089c22b 100644 --- a/dbrepo-ui/composables/ontology-service.ts +++ b/dbrepo-ui/composables/ontology-service.ts @@ -5,7 +5,7 @@ export const useOntologyService = (): any => { return new Promise<OntologyDto[]>((resolve, reject) => { axios.get<OntologyDto[]>('/api/semantic/ontology') .then((response) => { - console.info('Found ontologie(s)') + console.info(`Found ${response.data.length} ontology(s)`) resolve(response.data) }) .catch((error) => { @@ -37,7 +37,7 @@ export const useOntologyService = (): any => { return new Promise<OntologyDto>((resolve, reject) => { axios.post<OntologyDto>('/api/semantic/ontology', data) .then((response) => { - console.info('Created ontology') + console.info('Created ontology with id', response.data.id) resolve(response.data) }) .catch((error) => { diff --git a/dbrepo-ui/composables/query-service.ts b/dbrepo-ui/composables/query-service.ts index 6741dfeabc7e3fa5417d905655b838a2f2785759..0c3c058b9a5cf6a3711e8b4add09cf1c223bf5d2 100644 --- a/dbrepo-ui/composables/query-service.ts +++ b/dbrepo-ui/composables/query-service.ts @@ -8,7 +8,7 @@ export const useQueryService = (): any => { return new Promise<QueryDto[]>((resolve, reject) => { axios.get<QueryDto[]>(`/api/database/${databaseId}/query`, {params: (persisted && { persisted })}) .then((response) => { - console.info('Found query(s)') + console.info(`Found ${response.data.length} query(s)`) resolve(response.data) }) .catch((error) => { @@ -78,7 +78,7 @@ export const useQueryService = (): any => { return new Promise<QueryResultDto>((resolve, reject) => { axios.post<QueryResultDto>(`/api/database/${databaseId}/query`, data, {params: (page && size && { page, size })}) .then((response) => { - console.info('Executed query in database with id', databaseId) + console.info('Executed query with id', response.data.id, ' in database with id', databaseId) resolve(response.data) }) .catch((error) => { diff --git a/dbrepo-ui/composables/table-service.ts b/dbrepo-ui/composables/table-service.ts index 2af4d3b64c9f6f4dc2db01ac9910382df7194320..ead0169f177659c6874c260992993b7e5faf5982 100644 --- a/dbrepo-ui/composables/table-service.ts +++ b/dbrepo-ui/composables/table-service.ts @@ -101,13 +101,15 @@ export const useTableService = (): any => { async function exportData(databaseId: number, tableId: number, timestamp: Date): Promise<QueryResultDto> { const axios = useAxiosInstance() const config: AxiosRequestConfig = { - params: {timestamp}, + params: (timestamp && { timestamp }), responseType: 'blob', - headers: {Accept: 'text/csv'} + headers: { + Accept: 'text/csv' + } } console.debug('export data for table with id', tableId, 'in database with id', databaseId); return new Promise<QueryResultDto>((resolve, reject) => { - axios.get<QueryResultDto>(`/api/database/${databaseId}/table/${tableId}/export`) + axios.get<QueryResultDto>(`/api/database/${databaseId}/table/${tableId}/export`, config) .then((response) => { console.info('Exported data for table with id', tableId, 'in database with id', databaseId) resolve(response.data) diff --git a/dbrepo-ui/dto/index.ts b/dbrepo-ui/dto/index.ts index f677474f2fa4043cde51ff5c80383497f02063ca..008de9b2c2bccf3131431853295c08caf19b54e2 100644 --- a/dbrepo-ui/dto/index.ts +++ b/dbrepo-ui/dto/index.ts @@ -543,9 +543,6 @@ interface ImportCsv { interface QueryResultDto { result: any; headers: any; - /** - * @deprecated Will be removed with v2 - */ id: number; /** * @deprecated Will be removed with v2 diff --git a/dbrepo-ui/layouts/default.vue b/dbrepo-ui/layouts/default.vue index 3d4e562694c1f47d5ed7adcde1191891fe9d060d..ca8544ba138966809f17fc8d0bfafaadb7659613 100644 --- a/dbrepo-ui/layouts/default.vue +++ b/dbrepo-ui/layouts/default.vue @@ -48,13 +48,22 @@ </v-alert> <div class="d-flex pa-2"> <v-spacer /> + <v-btn + variant="plain" + text="DE" + size="x-small" + @click="setLocale('de')" /> + <v-btn + variant="plain" + text="EN" + size="x-small" + @click="setLocale('en')" /> <v-btn variant="plain" prepend-icon="mdi-tag" :href="`https://www.ifs.tuwien.ac.at/infrastructures/dbrepo/${version}`" :text="version" - size="x-small" - /> + size="x-small" /> </div> </template> </v-navigation-drawer> @@ -161,7 +170,7 @@ export default { return this.userStore.getUser }, locale () { - return null + return this.userStore.getLocale }, messages () { return this.cacheStore.getMessages @@ -248,9 +257,10 @@ export default { this.$router.push({ path: '/search', query: { q: this.search } }) }, initEnvironment () { - if (this.locale) { - this.$i18n.locale = this.locale + if (!this.locale) { + this.userStore.setLocale('en') } + this.$i18n.locale = this.locale }, setTheme () { switch (this.user.attributes.theme) { @@ -267,6 +277,10 @@ export default { this.$vuetify.theme.global.name = 'tuwThemeDarkContrast' break } + }, + setLocale (code) { + this.userStore.setLocale(code) + this.$i18n.locale = this.locale } } } diff --git a/dbrepo-ui/locales/de-AT.json b/dbrepo-ui/locales/de-AT.json new file mode 100644 index 0000000000000000000000000000000000000000..481043d49d31dfa1dd43826c270a869f22b9375f --- /dev/null +++ b/dbrepo-ui/locales/de-AT.json @@ -0,0 +1,1242 @@ +{ + "navigation": { + "information": "Information", + "search": "Suchen", + "ontologies": "Ontologien", + "my-databases": "Meine Datenbanken", + "logout": "Ausloggen", + "login": "Anmeldung", + "signup": "Registrierung", + "databases": "Datenbanken", + "tables": "Tabellen", + "subsets": "Teilmengen", + "info": "Info", + "data": "Daten", + "continue": "Weiter", + "assign": "Zuordnen", + "back": "Zurück", + "schema": "Schema", + "persist": "Persistieren", + "cancel": "Abbrechen", + "user": "Benutzer", + "import": "Importieren", + "delete": "Löschen", + "recommend": "Empfehlen", + "now": "Jetzt", + "settings": "Einstellungen", + "views": "Ansichten", + "create": "Erstellen", + "semantics": "Semantik" + }, + "pages": { + "identifier": { + "title": "Bezeichner", + "pid": { + "title": "Persistenter Bezeichner" + }, + "titles": { + "title": "Titel" + }, + "creators": { + "title": "Schöpfer" + }, + "language": { + "title": "Sprache" + }, + "publication-date": { + "title": "Veröffentlichungsdatum" + }, + "related-identifiers": { + "title": "Verwandte Bezeichner" + }, + "funders": { + "title": "Geldgeber" + }, + "licenses": { + "title": "Lizenzen" + }, + "citation": { + "title": "Zitierempfehlung" + }, + "descriptions": { + "title": "Beschreibungen" + }, + "publisher": { + "title": "Herausgeber" + }, + "remove": { + "text": "Entfernen" + }, + "subpages": { + "create": { + "publication-day": { + "label": "Tag der Veröffentlichung", + "hint": "" + }, + "publication-month": { + "label": "Veröffentlichungsmonat", + "hint": "" + }, + "publication-year": { + "label": "Erscheinungsjahr", + "hint": "Erforderlich." + }, + "titles": { + "title": { + "label": "Titel", + "hint": "Erforderlich." + }, + "type": { + "label": "Typ", + "hint": "" + }, + "language": { + "label": "Sprache", + "hint": "" + }, + "subtitle": "Ein Name oder Titel, unter dem eine Ressource bekannt ist. ", + "remove": { + "text": "Entfernen" + }, + "add": { + "text": "Hinzufügen" + } + }, + "descriptions": { + "description": { + "label": "Beschreibung", + "hint": "Erforderlich." + }, + "type": { + "label": "Typ", + "hint": "" + }, + "language": { + "label": "Sprache", + "hint": "" + }, + "subtitle": "Alle weiteren Informationen. ", + "remove": { + "text": "Entfernen" + }, + "add": { + "text": "Hinzufügen" + } + }, + "publisher": { + "title": "Veröffentlichungsinformationen", + "subtitle": "Der Name der Entität, die die Ressource hält, archiviert, veröffentlicht, druckt, verteilt, freigibt, herausgibt oder produziert. ", + "label": "Herausgeber", + "hint": "Erforderlich." + }, + "related-identifiers": { + "title": "Zugehöriger Bezeichner", + "subtitle": "Bezeichner verwandter Ressourcen. ", + "identifier": { + "label": "Kennung", + "hint": "Erforderlich." + }, + "type": { + "label": "Typ", + "hint": "" + }, + "relation": { + "label": "Beziehung", + "hint": "" + }, + "remove": { + "text": "Entfernen" + }, + "add": { + "text": "Hinzufügen" + } + }, + "licenses": { + "title": "Lizenz", + "subtitle": "Bezeichner verwandter Ressourcen. ", + "license": { + "label": "Lizenz" + } + }, + "language": { + "title": "Sprache", + "subtitle": "Die primäre Sprache des Datensatzes.", + "language": { + "label": "Sprache", + "hint": "" + } + }, + "funders": { + "title": "Finanzierungsreferenz", + "subtitle": "Informationen zur finanziellen Unterstützung (Finanzierung) für den zu registrierenden Datensatz.", + "identifier": { + "label": "Kennung des Geldgebers", + "hint": "Verwenden Sie eine Namenskennung, ausgedrückt als URL von ORCID*, ROR*, DOI*, ISNI, GND (Schemata mit * unterstützen den automatischen Metadatenabruf)." + }, + "name": { + "label": "Name des Geldgebers", + "hint": "Erforderlich." + }, + "award-number": { + "label": "Auszeichnungsnummer", + "hint": "" + }, + "award-title": { + "label": "Auszeichnungstitel", + "hint": "" + }, + "remove": { + "text": "Entfernen" + }, + "add": { + "text": "Hinzufügen" + } + }, + "creators": { + "subtitle": "Die wichtigsten Forscher, die an der Erstellung der Daten beteiligt waren, in der Reihenfolge ihrer Priorität.", + "identifier": { + "label": "Namensbezeichner", + "hint": "Verwenden Sie eine Namenskennung, ausgedrückt als URL von ORCID*, ROR*, DOI*, ISNI, GND (Schemata mit * unterstützen den automatischen Metadatenabruf)." + }, + "insert": { + "text": "Füge mich ein" + }, + "remove": { + "text": "Entfernen" + }, + "person": { + "label": "Person" + }, + "organization": { + "label": "Organisation" + }, + "given-name": { + "label": "Vorname", + "hint": "" + }, + "family-name": { + "label": "Familienname", + "hint": "" + }, + "name": { + "label": "Name", + "hint": "Erforderlich." + }, + "affiliation-identifier": { + "label": "Zugehörigkeitskennung", + "hint": "Verwenden Sie eine Zugehörigkeitskennung, ausgedrückt als URL von ORCID*, ROR*, DOI*, ISNI, GND (Schemata mit * unterstützen den automatischen Metadatenabruf)." + }, + "affiliation": { + "label": "Zugehörigkeitsname", + "hint": "" + }, + "add": "Hinzufügen" + }, + "summary": { + "title": "Zusammenfassung", + "subtitle": "Details zur Kennung, die zur Identifizierung dieses Datensatzes erstellt wird.", + "record": "Der Bezeichner beschreibt", + "publisher": "Herausgeber", + "license": "Lizenz", + "no-license": "Ohne Lizenz zur Wiederverwendung", + "doi": "Für diesen Identifikator wird ein DOI erstellt", + "no-doi": "Dieser Kennung wird ein URI zugeordnet", + "creators": "Ersteller" + } + } + } + }, + "table": { + "title": "Tisch", + "id": { + "title": "ID" + }, + "broker": { + "title": "Makler" + }, + "exchange": { + "title": "Austausch" + }, + "queue": { + "title": "Warteschlange" + }, + "routing-key": { + "title": "Routing-Schlüssel" + }, + "connection": { + "title": "Verbindungsdetails", + "secure": "sicher", + "insecure": "unsicher", + "permissions": { + "write": "Sie können in diese Tabelle schreiben.", + "read": "Sie können den gesamten Inhalt dieser Tabelle lesen." + } + }, + "protocol": { + "title": "Protokoll", + "name": "AMQP" + }, + "size": { + "title": "Größe" + }, + "result-rows": { + "title": "Reihen" + }, + "description": { + "title": "Beschreibung", + "empty": "(Keine Beschreibung)" + }, + "owner": { + "title": "Eigentümer" + }, + "creation": { + "title": "Schaffung" + }, + "import": { + "title": "Datensatz importieren in" + }, + "subpages": { + "import": { + "title": "Erstellen Sie eine Tabelle aus einem CSV-/TSV-Datensatz", + "metadata": { + "title": "Tabellenmetadaten" + }, + "dataset": { + "title": "Datensatzstruktur", + "warn": "Das Datensatzschema stimmt nicht mit dem Zieltabellenschema überein. " + }, + "name": { + "label": "Name", + "hint": "Erforderlich. " + }, + "generated": { + "label": "Generierter Name", + "hint": "" + }, + "description": { + "label": "Beschreibung", + "hint": "Optional. " + }, + "separator": { + "label": "Spaltentrennzeichen", + "hint": "Optional. ", + "warn": { + "prefix": "Wir haben Ihren .csv/.tsv-Datensatz analysiert und festgestellt, dass das von Ihnen angegebene Trennzeichen das ist", + "middle": "ist nicht korrekt, das Trennzeichen", + "suffix": "ist wahrscheinlicher, dass es richtig ist. " + } + }, + "skip": { + "label": "Zeilen überspringen", + "hint": "Optional. " + }, + "quote": { + "label": "Angebotskodierung", + "hint": "Optional. " + }, + "terminator": { + "label": "Kodierung des Leitungsabschlusses", + "hint": "Optional. ", + "warn": { + "prefix": "Wir haben Ihren .csv/.tsv-Datensatz analysiert und festgestellt, dass die von Ihnen angegebene Leitungsabschlusscodierung vorliegt", + "middle": "ist nicht korrekt, die Leitungsabschlusskodierung", + "suffix": "ist wahrscheinlicher, dass es richtig ist. " + } + }, + "null": { + "label": "Nullkodierung", + "hint": "Optional. " + }, + "true": { + "label": "Echte Kodierung", + "hint": "Optional. " + }, + "false": { + "label": "Falsche Kodierung", + "hint": "Optional. " + }, + "file": { + "title": "Datensatz-Upload", + "label": "Datensatzdatei", + "hint": "Erforderlich. " + }, + "preview": { + "title": "Vorschau" + }, + "summary": { + "title": "Zusammenfassung", + "prefix": "Importiert", + "suffix": "Zeilen aus dem Datensatz." + }, + "analyse": { + "text": "Hochladen" + } + }, + "create": { + "title": "Tabellenschema erstellen", + "information": { + "title": "Information" + }, + "name": { + "label": "Tabellenname", + "hint": "Erforderlich." + }, + "description": { + "label": "Tabellenbeschreibung", + "hint": "" + }, + "summary": { + "prefix": "Tabelle mit Namen erstellt", + "middle": "und importiert", + "suffix": "Zeilen aus dem Datensatz." + } + }, + "drop": { + "title": "Drop-Tisch", + "warning": { + "prefix": "Diese Aktion kann nicht rückgängig gemacht werden! ", + "suffix": "unten, wenn Sie es wirklich mit allen gespeicherten Daten löschen möchten." + }, + "name": { + "label": "Tabellenname", + "hint": "Erforderlich." + } + }, + "schema": { + "title": "Struktur", + "bullet": "●", + "assign": "Zuordnen", + "remove": { + "text": "Entfernen" + }, + "internal-name": { + "title": "Interner Name" + }, + "column-type": { + "title": "Spaltentyp" + }, + "extra": { + "title": "Zusatzinformation" + }, + "concept": { + "title": "Konzept" + }, + "unit": { + "title": "Maßeinheit" + }, + "nullable": { + "title": "Nullbar" + }, + "sequence": { + "title": "Reihenfolge" + }, + "name": { + "label": "Name", + "hint": "Erforderlich." + }, + "add": { + "text": "Spalte hinzufügen" + }, + "type": { + "label": "Typ", + "hint": "Erforderlich." + }, + "size": { + "label": "Größe" + }, + "d": { + "label": "D" + }, + "primary-key": { + "label": "Primärschlüssel" + }, + "foreign-key": { + "label": "Unbekannter Schlüssel" + }, + "references": { + "label": "Ausländische Referenzen" + }, + "null": { + "label": "Nullbar" + }, + "unique": { + "label": "Einzigartig" + }, + "fsp": { + "label": "fsp" + }, + "set": { + "label": "Werte festlegen", + "hint": "Trennen Sie die Werte durch ," + }, + "enum": { + "label": "Aufzählungswerte", + "hint": "Trennen Sie die Werte durch ," + }, + "summary": { + "title": "Zusammenfassung", + "text": "Tabelle mit internem Namen erfolgreich erstellt:" + } + }, + "semantics": { + "title": "Semantische Instanz für Tabellenspalte zuweisen:", + "subtitle": "Semantische Instanzen helfen Maschinen dabei, den richtigen Kontext Ihres Datensatzes zu ermitteln.", + "recommended": "Empfohlene semantische Instanzen", + "bullet": "●", + "info": "Die folgenden Ontologien fragen automatisch die Felder rdfs:label ab und speichern sie für diese Spalte. ", + "uri": { + "label": "Semantischer Instanz-URI", + "hint": "Dieser URI kann automatisch aufgelöst werden." + } + }, + "versioning": { + "title": "Versionierung", + "subtitle": "Wählen Sie einen Zeitstempel aus, um die Daten für diese bestimmte Tageszeit anzuzeigen.", + "timestamp": { + "label": "Zeitstempel", + "hint": "Erforderlich. ", + "placeholder": "z.B. ", + "suffix": "koordinierte Weltzeit" + } + }, + "data": { + "auto": { + "hint": "Der Wert wird automatisch durch eine Sequenz generiert." + }, + "primary-key": { + "hint": "Der Wert ist ein Primärschlüssel." + }, + "format": { + "hint": "Der Wert muss folgendes Format haben:" + }, + "required": { + "hint": "Erforderlich. " + }, + "float": { + "max": "max.", + "min": "Mindest.", + "before": "Ziffer(n) vor dem Punkt.", + "after": "Ziffer(n) nach dem Punkt." + } + } + } + }, + "database": { + "title": "Datenbank", + "image": { + "title": "Teaser-Bild", + "alt": "Datenbanklogo/Standardbild" + }, + "name": { + "title": "Name" + }, + "internal-name": { + "title": "Interner Name" + }, + "visibility": { + "title": "Sichtweite" + }, + "size": { + "title": "Größe" + }, + "owner": { + "title": "Eigentümer" + }, + "created": { + "title": "Erstellt" + }, + "connection": { + "title": "Verbindung", + "username": "Nutzername", + "password": "Passwort" + }, + "contact": { + "title": "Kontakt" + }, + "subpages": { + "access": { + "title": "Datenbankzugriff", + "subtitle": "Übersicht über Benutzer mit ihrem Zugriff auf die Datenbank.", + "read": "Sie können alle Inhalte lesen", + "write-own": "Sie können eigene Tabellen schreiben und alle Inhalte lesen", + "write-all": "Sie können eigene Tabellen schreiben und alle Inhalte lesen", + "revoke": "Widerrufen", + "action": "Aktion", + "username": { + "label": "Nutzername", + "hint": "Erforderlich" + }, + "type": { + "label": "Zugangsart", + "hint": "Erforderlich" + }, + "submit": { + "text": "Ändern" + } + }, + "create": { + "title": "Datenbank erstellen", + "subtitle": "Wählen Sie einen aussagekräftigen Datenbanknamen und eine Datenbank-Engine.", + "name": { + "label": "Name", + "hint": "Erforderlich. ", + "placeholder": "z.B. " + }, + "engine": { + "label": "Motor", + "hint": "Erforderlich." + }, + "submit": { + "text": "Erstellen" + } + }, + "tables": { + "empty": "(keine Tabellen)" + }, + "tuple": { + "create": { + "text": "Erstellen" + }, + "update": { + "text": "Aktualisieren" + } + }, + "subsets": { + "empty": "(keine Teilmengen)", + "http": "(Datenbank nicht erreichbar, versuchen Sie es später erneut)" + }, + "views": { + "empty": "(keine Ansichten)" + }, + "settings": { + "title": "Einstellungen", + "subtitle": "Das Bild wird in einem Feld mit den maximalen Abmessungen 200x200 Pixel angezeigt.", + "image": { + "label": "Teaser-Bild", + "hint": "max. " + }, + "submit": { + "text": "Bild ändern" + }, + "image-remove": { + "text": "Entferne Bild" + }, + "ownership": { + "title": "Eigentum", + "subtitle": "Benutzer, der Eigentümer dieser Datenbank ist.", + "label": "Datenbankbesitzer", + "hint": "Erforderlich.", + "submit": { + "text": "Überweisen" + } + }, + "visibility": { + "title": "Sichtweite", + "subtitle": "Private Datenbanken verbergen die Daten, während Metadaten weiterhin sichtbar sind. ", + "visibility": { + "label": "Datenbanksichtbarkeit", + "hint": "Erforderlich." + }, + "submit": { + "text": "Ändern" + } + } + } + } + }, + "signup": { + "name": "Melden Sie sich an", + "email": { + "label": "E-Mail-Adresse", + "hint": "Erforderlich." + }, + "username": { + "label": "Nutzername", + "hint": "Erforderlich." + }, + "password": { + "label": "Passwort", + "hint": "Erforderlich." + }, + "confirm": { + "label": "Bestätige das Passwort", + "hint": "Erforderlich." + }, + "submit": { + "label": "Absenden" + } + }, + "login": { + "name": "Anmeldung", + "username": { + "label": "Nutzername", + "hint": "Erforderlich." + }, + "password": { + "label": "Passwort", + "hint": "Erforderlich." + }, + "submit": { + "label": "Absenden" + } + }, + "user": { + "qualified-name": { + "label": "Qualifizierter Name" + }, + "subpages": { + "info": { + "title": "Information", + "subtitle": "Allgemeine Benutzermetadaten.", + "id": { + "label": "ID" + }, + "username": { + "label": "Nutzername" + }, + "firstname": { + "label": "Vorname", + "hint": "" + }, + "lastname": { + "label": "Familienname", + "hint": "" + }, + "affiliation": { + "label": "Zugehörigkeitskennung", + "hint": "ROR-Identifikator, z.B. " + }, + "orcid": { + "label": "Persönliche Kennung", + "hint": "ORCID-Kennung, z.B. " + }, + "submit": { + "text": "Aktualisieren" + } + }, + "theme": { + "title": "Thema", + "subtitle": "Aktualisieren Sie das Benutzerdesign, wenn Sie angemeldet sind.", + "label": "Thema", + "dark": "Dunkel", + "dark-contrast": "Dunkel – hoher Kontrast", + "light": "Licht", + "light-contrast": "Hell – hoher Kontrast", + "submit": { + "text": "Aktualisieren" + } + } + } + }, + "settings": { + "subpages": { + "authentication": { + "title": "Benutzer-Passwort", + "subtitle": "Aktualisieren Sie das Benutzerkennwort, das für die Basisauthentifizierung bei allen Schnittstellen verwendet wird.", + "password": { + "label": "Passwort", + "hint": "Erforderlich." + }, + "confirm": { + "label": "Bestätige das Passwort", + "hint": "Erforderlich." + }, + "submit": { + "text": "Aktualisieren" + } + }, + "developer": { + "token": { + "title": "Token-Informationen", + "subtitle": "Sehen Sie sich Ihre Token-Geheimnisse zu Debugging-Zwecken an.", + "expiry": "Läuft ab", + "access": { + "label": "Zugangstoken" + }, + "refresh": { + "label": "Aktualisierungstoken" + } + }, + "maintenance": { + "title": "Mitteilungen", + "active": "Aktiv", + "type": "Typ", + "message": "Text", + "action": "Aktion", + "create": { + "title": "Wartungsmeldung", + "type": { + "label": "Typ", + "hint": "Erforderlich." + }, + "message": { + "label": "Nachricht", + "hint": "Erforderlich." + }, + "start": { + "label": "Zeitstempel starten" + }, + "end": { + "label": "Endzeitstempel" + }, + "submit": { + "text": "Absenden" + }, + "delete": { + "text": "Löschen" + } + }, + "modify": { + "text": "Ändern" + }, + "add": { + "text": "Hinzufügen" + } + } + } + } + }, + "view": { + "title": "Sicht", + "tabs": { + "info": "Info", + "data": "Daten" + }, + "query": { + "title": "Abfrage" + }, + "creator": { + "title": "Schöpfer" + }, + "creation": { + "title": "Schaffung" + }, + "visibility": { + "title": "Sichtweite" + }, + "subpages": { + "create": { + "title": "Ansicht erstellen", + "name": { + "label": "Name", + "hint": "Erforderlich." + }, + "table": { + "label": "Datentabelle", + "hint": "Erforderlich." + }, + "columns": { + "label": "Datenspalten", + "hint": "Erforderlich." + }, + "visibility": { + "warn": "Die Ansichtsmetadaten, d. h. Ansichtsname, Abfrage, bleiben weiterhin öffentlich. " + } + } + } + }, + "subset": { + "title": "Teilmenge", + "visibility": { + "title": "Sichtweite" + }, + "creator": { + "title": "Schöpfer" + }, + "query": { + "title": "Abfrage" + }, + "query-hash": { + "prefix": "sha256:", + "title": "Abfrage-Hash" + }, + "executed": { + "title": "Erstellt" + }, + "result-hash": { + "title": "Ergebnis-Hash" + }, + "result-rows": { + "title": "Ergebniszeilen" + }, + "tabs": { + "info": "Info", + "data": "Daten" + }, + "subpages": { + "create": { + "title": "Teilmenge erstellen", + "generated": "Die folgende Abfrage wird ausgeführt (schreibgeschützt):", + "subtitle": "Die folgende Abfrage wird ausgeführt:", + "simple": { + "text": "Einfach" + }, + "expert": { + "text": "Experte", + "warn": "Von der Verwendung von Kommentaren, Aggregationsfunktionen und den folgenden Vorgängen wird abgeraten:" + }, + "name": { + "label": "" + }, + "filter": { + "text": "Filter hinzufügen", + "column": { + "label": "Spalte", + "hint": "Erforderlich." + }, + "operator": { + "label": "Operator", + "hint": "Erforderlich." + }, + "value": { + "label": "Wert", + "hint": "Erforderlich." + }, + "remove": { + "text": "Entfernen" + }, + "and": { + "text": "Fügen Sie den „AND“-Filter hinzu" + }, + "or": { + "text": "Fügen Sie den „ODER“-Filter hinzu" + } + } + } + } + }, + "search": { + "types": { + "database": "Datenbank", + "table": "Tabelle", + "column": "Spalte", + "user": "Benutzer", + "identifier": "Bezeichner", + "concept": "Konzept", + "unit": "Einheit", + "view": "Ansicht" + }, + "type": { + "label": "Typ", + "hint": "" + }, + "id": { + "label": "ID", + "hint": "" + }, + "name": { + "label": "Name", + "hint": "" + }, + "internal-name": { + "label": "Interner Name", + "hint": "" + }, + "publication-range": { + "hint": "Geben Sie Ihren benutzerdefinierten Veröffentlichungsjahresbereich an." + }, + "start-year": { + "label": "Startjahr", + "hint": "" + }, + "end-year": { + "label": "Jahresende", + "hint": "" + }, + "concept-unit": { + "hint": "Wenn Sie ein KONZEPT und eine EINHEIT auswählen, können Sie unabhängig von der Maßeinheit spaltenübergreifend suchen." + }, + "concept": { + "label": "Konzept", + "hint": "" + }, + "unit": { + "label": "Einheit", + "hint": "" + }, + "start": { + "label": "Startwert", + "hint": "" + }, + "end": { + "label": "Endwert", + "hint": "" + } + }, + "container": { + "title": "Container", + "name": { + "title": "Name" + }, + "internal-name": { + "title": "Interner Name" + }, + "image-name": { + "title": "Abbild" + }, + "image-tag": { + "title": "Ausführung" + } + }, + "semantics": { + "title": "Semantik", + "usages": { + "text": "Verwendungen" + } + } + }, + "error": { + "import": { + "dataset": "Der Datensatz konnte nicht importiert werden." + }, + "upload": { + "dataset": "Der Datensatz konnte nicht hochgeladen werden." + }, + "schema": { + "id": "Die Spalte „id“ muss ein Primärschlüssel sein." + }, + "user": { + "credentials": "Ungültige Benutzername und Passwort Kombination.", + "email-exists": "Das Konto mit dieser E-Mail-Adresse existiert bereits." + }, + "query": { + "viewmalformed": "Die Ansicht ist fehlerhaft:", + "type": { + "exists": "Abfrage konnte nicht erstellt werden: kein solcher Spaltentyp:", + "build": "Abfrage konnte nicht erstellt werden: Derzeit gibt es keine Abfrageerstellungsunterstützung für den Spaltentyp:" + }, + "column": { + "exists": "Abfrage konnte nicht erstellt werden: In den Datenspalten fehlt die Spalte mit dem Namen:" + } + }, + "semantics": { + "timeout": "Semantikvorschlag fehlgeschlagen: Zeitüberschreitung bei der Anfrage" + }, + "database": { + "querystore": "Die Abfrage konnte nicht in den Abfragespeicher eingefügt werden" + }, + "table": { + "tablemalformed": "Eintrag konnte nicht eingefügt werden:", + "create": "Tabelle konnte nicht erstellt werden:", + "connection": "Das Laden der Tabellendaten ist fehlgeschlagen, da die Datenbank nicht erreichbar ist." + }, + "view": { + "create": "Ansicht konnte nicht erstellt werden:" + }, + "data": { + "value": "Spaltenwert konnte nicht festgelegt werden:" + }, + "transfer": "Der Datenbankeigentümer konnte nicht übertragen werden." + }, + "success": { + "signup": "Konto erfolgreich erstellt.", + "query": { + "build": "Abfrage konnte nicht erstellt werden: Spalte nicht gefunden", + "fatal": "Abfragen mit diesem Schema können derzeit nicht über die Benutzeroberfläche erstellt werden" + }, + "import": { + "dataset": "Datensatz erfolgreich importiert." + }, + "upload": { + "dataset": "Datensatz erfolgreich hochgeladen.", + "blob": "Datei erfolgreich hochgeladen." + }, + "analyse": { + "dataset": "Datensatz erfolgreich analysiert." + }, + "access": { + "created": "Zugriff erfolgreich bereitgestellt.", + "modified": "Zugriff erfolgreich geändert.", + "revoked": "Zugriff erfolgreich widerrufen." + }, + "data": { + "add": "Dateneingabe erfolgreich hinzugefügt.", + "update": "Dateneingabe erfolgreich aktualisiert." + }, + "table": { + "created": "Tabelle erfolgreich erstellt.", + "semantics": "Semantische Instanz erfolgreich zugewiesen." + }, + "database": { + "upload": "Datenbankbild erfolgreich hochgeladen.", + "transfer": "Der Datenbankeigentümer wurde erfolgreich übertragen.", + "image": { + "update": "Datenbankbild erfolgreich aktualisiert.", + "remove": "Datenbankbild erfolgreich entfernt." + } + }, + "pid": { + "created": "Erfolgreich persistierter Bezeichner.", + "updated": "Kennung erfolgreich aktualisiert." + }, + "user": { + "info": "Benutzerinformationen erfolgreich aktualisiert.", + "theme": "Benutzerthema erfolgreich aktualisiert." + }, + "view": { + "create": "Ansicht erfolgreich erstellt.", + "delete": "Ansicht erfolgreich gelöscht." + }, + "subset": { + "create": "Teilmenge erfolgreich erstellt." + } + }, + "toolbars": { + "user": { + "info": "Info", + "authentication": "Authentifizierung", + "developer": "Entwickler" + }, + "semantic": { + "register": { + "title": "Registrieren Sie die Ontologie", + "subtitle": "Registrieren Sie einen neuen Ontologie-Endpunkt." + }, + "ontologies": { + "title": "Ontologien", + "text": "Ontologien", + "units": "Einheiten", + "concepts": "Konzepte" + }, + "ontology": { + "text": "Ontologie" + } + }, + "database": { + "recent": "Aktuelle Datenbanken", + "links": "Wichtige Links", + "public": "Öffentlich", + "private": "Privat", + "current": "Aktuelle Daten", + "history": "Historische Daten", + "create": { + "text": "Datenbank" + }, + "import-csv": { + "permanent": "Importieren", + "xl": "CSV" + }, + "create-subset": { + "permanent": "Teilmenge", + "xl": "Erstellen" + }, + "create-view": { + "permanent": "Sicht", + "xl": "Erstellen" + }, + "create-table": { + "permanent": "Tisch", + "xl": "Erstellen" + }, + "create-pid": { + "permanent": "PID", + "xl": "Erhalten" + }, + "info": { + "tab": "Info" + }, + "tables": { + "tab": "Tabellen" + }, + "subsets": { + "tab": "Teilmengen" + }, + "views": { + "tab": "Ansichten" + }, + "settings": { + "tab": "Einstellungen" + } + }, + "identifier": { + "create": { + "xl": "Erhalten", + "permanent": "PID" + }, + "update": { + "xl": "Aktualisieren", + "permanent": "PID" + } + }, + "search": { + "fuzzy": { + "placeholder": "Suchen ..." + }, + "result": "Ergebnis", + "results": "Ergebnisse" + }, + "subset": { + "save": { + "permanent": "Speichern" + }, + "export": { + "data": { + "xl": "Ergebnis", + "permanent": "Daten" + }, + "metadata": { + "xl": "Ergebnis", + "permanent": "Metadaten" + } + }, + "pid": { + "xl": "Erhalten", + "permanent": "PID" + }, + "unsave": { + "permanent": "Nicht speichern" + } + }, + "view": { + "pid": { + "xl": "Erhalten", + "permanent": "PID" + } + }, + "table": { + "data": { + "refresh": "Aktualisierung", + "add": "Hinzufügen", + "edit": "Aktualisieren", + "delete": "Löschen", + "tuple": "Eintrag", + "download": "Herunterladen", + "version": "Geschichte", + "subtitle": "Stellen Sie Daten bereit, die direkt in den Datensatz eingefügt werden sollen." + } + } + }, + "validation": { + "required": "Pflichtfeld", + "integer": "Größer oder gleich Null", + "max-length": "Die maximale Länge beträgt: ", + "day": "Ungültiger Tag", + "month": "Ungültiger Monat", + "schema": { + "id": "Die Spalte muss als Primärschlüssel deklariert werden", + "primary-key": "Wir erstellen eine Spalte mit dem Namen „id“ mit einer automatisch ansteigenden Sequenz, die bei 1 beginnt. Bitte geben Sie eine Spalte mit Primärschlüssel an, wenn Sie dieses Verhalten nicht wünschen." + }, + "uri": { + "pattern": "Ungültiger URI", + "exists": "URI existiert" + }, + "user": { + "pattern": "Nur Kleinbuchstaben, min. ", + "exists": "Dieser Benutzername ist bereits vergeben" + }, + "view": { + "exists": "Der Ansichtsname existiert bereits" + }, + "table": { + "exists": "Tabellenname existiert bereits" + }, + "prefix": { + "pattern": "Ungültiges Präfixmuster", + "length": "Ungültige Länge: min. ", + "exists": "Präfix existiert" + }, + "pattern": { + "timestamp": "Muss im Format jjjj-MM-tt HH:mm:ss vorliegen" + } + } +} diff --git a/dbrepo-ui/locales/en-US.json b/dbrepo-ui/locales/en-US.json index c25df9414422f9f74859968c3f4ff6e4b964f1d8..077c5d079e73870356674c3862ab3ccfd3ad62eb 100644 --- a/dbrepo-ui/locales/en-US.json +++ b/dbrepo-ui/locales/en-US.json @@ -906,6 +906,16 @@ } }, "search": { + "types": { + "database": "Database", + "table": "Table", + "column": "Column", + "user": "User", + "identifier": "Identifier", + "concept": "Concept", + "unit": "Unit", + "view": "View" + }, "type": { "label": "Type", "hint": "" diff --git a/dbrepo-ui/nuxt.config.ts b/dbrepo-ui/nuxt.config.ts index 74ca97eef79543f0cfc4e20c5427483fed71a8ab..75e31703115b68f8b7e7c07e9c0dfb41176d4d7a 100644 --- a/dbrepo-ui/nuxt.config.ts +++ b/dbrepo-ui/nuxt.config.ts @@ -26,6 +26,9 @@ export default defineNuxtConfig({ head: { charset: 'utf-8', viewport: 'width=device-width, initial-scale=1', + meta: [ + { 'http-equiv': 'Content-Security-Policy', content: 'upgrade-insecure-requests' } + ], htmlAttrs: { lang: 'en-US' } @@ -129,14 +132,20 @@ export default defineNuxtConfig({ i18n: { lazy: true, langDir: 'locales', - strategy: 'prefix_except_default', - defaultLocale: 'en', + strategy: 'no_prefix', + defaultLocale: 'de', locales: [ { "code": "en", "file": "en-US.json", "name": "English (US)", "iso": "en-US" + }, + { + "code": "de", + "file": "de-AT.json", + "name": "German (AT)", + "iso": "de-AT" } ] diff --git a/dbrepo-ui/pages/signup.vue b/dbrepo-ui/pages/signup.vue index d6d294052de2a8f605aba336015232deba0b945b..d660474aa2a678a3292fa735b50db1acedbc087e 100644 --- a/dbrepo-ui/pages/signup.vue +++ b/dbrepo-ui/pages/signup.vue @@ -7,7 +7,9 @@ ref="form" v-model="valid" @submit.prevent="submit"> - <v-card variant="flat"> + <v-card + variant="flat" + rounded="0"> <v-card-text> <v-row dense> <v-col sm="6"> diff --git a/dbrepo-ui/stores/cache.js b/dbrepo-ui/stores/cache.js index ff738eb14d30142c7a50572e85c0b11d267d0788..cb0e47fd13ee20272d2986535543d5f54c87ec52 100644 --- a/dbrepo-ui/stores/cache.js +++ b/dbrepo-ui/stores/cache.js @@ -7,7 +7,7 @@ export const useCacheStore = defineStore('cache', { database: null, table: null, ontologies: [], - messages: [] + messages: [], } }, getters: { diff --git a/dbrepo-ui/stores/user.js b/dbrepo-ui/stores/user.js index cbae4b6f1903a38c952561fcf9cd56412ec76535..22087145bac948a90418436caa5717cca71a5577 100644 --- a/dbrepo-ui/stores/user.js +++ b/dbrepo-ui/stores/user.js @@ -10,7 +10,8 @@ export const useUserStore = defineStore('user', { refreshToken: null, roles: [], user: null, - access: null + access: null, + locale: null } }, getters: { @@ -19,6 +20,7 @@ export const useUserStore = defineStore('user', { getRoles: (state) => state.roles, getUser: (state) => state.user, getAccess: (state) => state.access, + getLocale: (state) => state.locale }, actions: { setToken(token) { @@ -36,6 +38,9 @@ export const useUserStore = defineStore('user', { setAccess(access) { this.access = access }, + setLocale (locale) { + this.locale = locale + }, logout() { this.token = null this.refreshToken = null