From 5710137e8b02de3cb61a8b72770b521ec73e1c28 Mon Sep 17 00:00:00 2001 From: Chris Hubbard Date: Wed, 18 Oct 2023 08:51:50 -0400 Subject: [PATCH] Initial UI * locale * navbar --- .../SIL.AppBuilder.Portal/package-lock.json | 655 ++++++++++++++++++ source/SIL.AppBuilder.Portal/package.json | 2 + .../SIL.AppBuilder.Portal/src/hooks.server.ts | 11 + .../src/lib/components/Dropdown.svelte | 26 + .../lib/components/LanguageSelector.svelte | 50 ++ source/SIL.AppBuilder.Portal/src/lib/i18n.js | 11 + .../src/lib/icons/ArrowBackIcon.svelte | 12 + .../src/lib/icons/HamburgerIcon.svelte | 12 + .../src/lib/icons/LanguageIcon.svelte | 20 + .../src/lib/icons/index.js | 9 + .../src/lib/locales/en-us.json | 601 ++++++++++++++++ .../src/lib/locales/es-419.json | 601 ++++++++++++++++ .../src/lib/locales/fr-FR.json | 601 ++++++++++++++++ .../src/routes/+layout.svelte | 21 + .../src/routes/+layout.ts | 12 + .../src/routes/+page.svelte | 9 +- 16 files changed, 2651 insertions(+), 2 deletions(-) create mode 100644 source/SIL.AppBuilder.Portal/src/hooks.server.ts create mode 100644 source/SIL.AppBuilder.Portal/src/lib/components/Dropdown.svelte create mode 100644 source/SIL.AppBuilder.Portal/src/lib/components/LanguageSelector.svelte create mode 100644 source/SIL.AppBuilder.Portal/src/lib/i18n.js create mode 100644 source/SIL.AppBuilder.Portal/src/lib/icons/ArrowBackIcon.svelte create mode 100644 source/SIL.AppBuilder.Portal/src/lib/icons/HamburgerIcon.svelte create mode 100644 source/SIL.AppBuilder.Portal/src/lib/icons/LanguageIcon.svelte create mode 100644 source/SIL.AppBuilder.Portal/src/lib/icons/index.js create mode 100644 source/SIL.AppBuilder.Portal/src/lib/locales/en-us.json create mode 100644 source/SIL.AppBuilder.Portal/src/lib/locales/es-419.json create mode 100644 source/SIL.AppBuilder.Portal/src/lib/locales/fr-FR.json create mode 100644 source/SIL.AppBuilder.Portal/src/routes/+layout.ts diff --git a/source/SIL.AppBuilder.Portal/package-lock.json b/source/SIL.AppBuilder.Portal/package-lock.json index 452921e40..e17ca52ec 100644 --- a/source/SIL.AppBuilder.Portal/package-lock.json +++ b/source/SIL.AppBuilder.Portal/package-lock.json @@ -8,6 +8,7 @@ "name": "sil.appbuilder.portal", "version": "0.0.1", "devDependencies": { + "@iconify/svelte": "^3.1.4", "@playwright/test": "^1.28.1", "@prisma/client": "^5.4.2", "@sveltejs/adapter-auto": "^2.0.0", @@ -28,6 +29,7 @@ "prisma": "^5.4.2", "svelte": "^4.0.5", "svelte-check": "^3.4.3", + "svelte-i18n": "^4.0.0", "tailwindcss": "^3.3.3", "ts-node": "^10.9.1", "tslib": "^2.4.1", @@ -509,6 +511,55 @@ "node": ">=14" } }, + "node_modules/@formatjs/ecma402-abstract": { + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.2.tgz", + "integrity": "sha512-k2mTh0m+IV1HRdU0xXM617tSQTi53tVR2muvYOsBeYcUgEAyxV1FOC7Qj279th3fBVQ+Dj6muvNJZcHSPNdbKg==", + "dev": true, + "dependencies": { + "@formatjs/intl-localematcher": "0.4.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/fast-memoize": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz", + "integrity": "sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==", + "dev": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.0.tgz", + "integrity": "sha512-7uqC4C2RqOaBQtcjqXsSpGRYVn+ckjhNga5T/otFh6MgxRrCJQqvjfbrGLpX1Lcbxdm5WH3Z2WZqt1+Tm/cn/Q==", + "dev": true, + "dependencies": { + "@formatjs/ecma402-abstract": "1.17.2", + "@formatjs/icu-skeleton-parser": "1.6.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.6.2.tgz", + "integrity": "sha512-VtB9Slo4ZL6QgtDFJ8Injvscf0xiDd4bIV93SOJTBjUF4xe2nAWOoSjLEtqIG+hlIs1sNrVKAaFo3nuTI4r5ZA==", + "dev": true, + "dependencies": { + "@formatjs/ecma402-abstract": "1.17.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/intl-localematcher": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.4.2.tgz", + "integrity": "sha512-BGdtJFmaNJy5An/Zan4OId/yR9Ih1OojFjcduX/xOvq798OgWSyDtd6Qd5jqJXwJs1ipe4Fxu9+cshic5Ox2tA==", + "dev": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.11", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", @@ -542,6 +593,27 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@iconify/svelte": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@iconify/svelte/-/svelte-3.1.4.tgz", + "integrity": "sha512-YDwQlN46ka8KPRayDb7TivmkAPizfTXi6BSRNqa1IV0+byA907n8JcgQafA7FD//pW5XCuuAhVx6uRbKTo+CfA==", + "dev": true, + "dependencies": { + "@iconify/types": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/cyberalien" + }, + "peerDependencies": { + "svelte": "*" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "dev": true + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -1533,6 +1605,22 @@ "node": ">= 6" } }, + "node_modules/cli-color": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz", + "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.61", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/code-red": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", @@ -1649,6 +1737,16 @@ "node": ">=4" } }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "node_modules/daisyui": { "version": "3.9.3", "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-3.9.3.tgz", @@ -1797,12 +1895,60 @@ "integrity": "sha512-6x0zsxyMXpnMJnHrondrD3SuAeKcwij9S+83j2qHAQPXbGTDDfgImzzwgGlzrIcXbHQ42tkG4qA6U860cImNhw==", "dev": true }, + "node_modules/es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, "node_modules/es6-promise": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", "dev": true }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, "node_modules/esbuild": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", @@ -2063,6 +2209,31 @@ "node": ">=0.10.0" } }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2395,6 +2566,18 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/intl-messageformat": { + "version": "10.5.4", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.4.tgz", + "integrity": "sha512-z+hrFdiJ/heRYlzegrdFYqU1m/KOMOVMqNilIArj+PbsuU8TNE7v4TWdQgSoxlxbT4AcZH3Op3/Fu15QTp+W1w==", + "dev": true, + "dependencies": { + "@formatjs/ecma402-abstract": "1.17.2", + "@formatjs/fast-memoize": "2.2.0", + "@formatjs/icu-messageformat-parser": "2.7.0", + "tslib": "^2.4.0" + } + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -2458,6 +2641,12 @@ "node": ">=8" } }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true + }, "node_modules/is-reference": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", @@ -2630,6 +2819,15 @@ "node": ">=10" } }, + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dev": true, + "dependencies": { + "es5-ext": "~0.10.2" + } + }, "node_modules/magic-string": { "version": "0.30.4", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.4.tgz", @@ -2654,6 +2852,22 @@ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "dev": true }, + "node_modules/memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -2801,6 +3015,12 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, "node_modules/node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -3818,6 +4038,425 @@ "svelte": "^3.19.0 || ^4.0.0" } }, + "node_modules/svelte-i18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/svelte-i18n/-/svelte-i18n-4.0.0.tgz", + "integrity": "sha512-4vivjKZADUMRIhTs38JuBNy3unbnh9AFRxWFLxq62P4NHic+/BaIZZlAsvqsCdnp7IdJf5EoSiH6TNdItcjA6g==", + "dev": true, + "dependencies": { + "cli-color": "^2.0.3", + "deepmerge": "^4.2.2", + "esbuild": "^0.19.2", + "estree-walker": "^2", + "intl-messageformat": "^10.5.3", + "sade": "^1.8.1", + "tiny-glob": "^0.2.9" + }, + "bin": { + "svelte-i18n": "dist/cli.js" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "svelte": "^3 || ^4" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/android-arm": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.5.tgz", + "integrity": "sha512-bhvbzWFF3CwMs5tbjf3ObfGqbl/17ict2/uwOSfr3wmxDE6VdS2GqY/FuzIPe0q0bdhj65zQsvqfArI9MY6+AA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/android-arm64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.5.tgz", + "integrity": "sha512-5d1OkoJxnYQfmC+Zd8NBFjkhyCNYwM4n9ODrycTFY6Jk1IGiZ+tjVJDDSwDt77nK+tfpGP4T50iMtVi4dEGzhQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/android-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.5.tgz", + "integrity": "sha512-9t+28jHGL7uBdkBjL90QFxe7DVA+KGqWlHCF8ChTKyaKO//VLuoBricQCgwhOjA1/qOczsw843Fy4cbs4H3DVA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/darwin-arm64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.5.tgz", + "integrity": "sha512-mvXGcKqqIqyKoxq26qEDPHJuBYUA5KizJncKOAf9eJQez+L9O+KfvNFu6nl7SCZ/gFb2QPaRqqmG0doSWlgkqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/darwin-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.5.tgz", + "integrity": "sha512-Ly8cn6fGLNet19s0X4unjcniX24I0RqjPv+kurpXabZYSXGM4Pwpmf85WHJN3lAgB8GSth7s5A0r856S+4DyiA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.5.tgz", + "integrity": "sha512-GGDNnPWTmWE+DMchq1W8Sd0mUkL+APvJg3b11klSGUDvRXh70JqLAO56tubmq1s2cgpVCSKYywEiKBfju8JztQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/freebsd-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.5.tgz", + "integrity": "sha512-1CCwDHnSSoA0HNwdfoNY0jLfJpd7ygaLAp5EHFos3VWJCRX9DMwWODf96s9TSse39Br7oOTLryRVmBoFwXbuuQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/linux-arm": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.5.tgz", + "integrity": "sha512-lrWXLY/vJBzCPC51QN0HM71uWgIEpGSjSZZADQhq7DKhPcI6NH1IdzjfHkDQws2oNpJKpR13kv7/pFHBbDQDwQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/linux-arm64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.5.tgz", + "integrity": "sha512-o3vYippBmSrjjQUCEEiTZ2l+4yC0pVJD/Dl57WfPwwlvFkrxoSO7rmBZFii6kQB3Wrn/6GwJUPLU5t52eq2meA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/linux-ia32": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.5.tgz", + "integrity": "sha512-MkjHXS03AXAkNp1KKkhSKPOCYztRtK+KXDNkBa6P78F8Bw0ynknCSClO/ztGszILZtyO/lVKpa7MolbBZ6oJtQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/linux-loong64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.5.tgz", + "integrity": "sha512-42GwZMm5oYOD/JHqHska3Jg0r+XFb/fdZRX+WjADm3nLWLcIsN27YKtqxzQmGNJgu0AyXg4HtcSK9HuOk3v1Dw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/linux-mips64el": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.5.tgz", + "integrity": "sha512-kcjndCSMitUuPJobWCnwQ9lLjiLZUR3QLQmlgaBfMX23UEa7ZOrtufnRds+6WZtIS9HdTXqND4yH8NLoVVIkcg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/linux-ppc64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.5.tgz", + "integrity": "sha512-yJAxJfHVm0ZbsiljbtFFP1BQKLc8kUF6+17tjQ78QjqjAQDnhULWiTA6u0FCDmYT1oOKS9PzZ2z0aBI+Mcyj7Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/linux-riscv64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.5.tgz", + "integrity": "sha512-5u8cIR/t3gaD6ad3wNt1MNRstAZO+aNyBxu2We8X31bA8XUNyamTVQwLDA1SLoPCUehNCymhBhK3Qim1433Zag==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/linux-s390x": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.5.tgz", + "integrity": "sha512-Z6JrMyEw/EmZBD/OFEFpb+gao9xJ59ATsoTNlj39jVBbXqoZm4Xntu6wVmGPB/OATi1uk/DB+yeDPv2E8PqZGw==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/linux-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.5.tgz", + "integrity": "sha512-psagl+2RlK1z8zWZOmVdImisMtrUxvwereIdyJTmtmHahJTKb64pAcqoPlx6CewPdvGvUKe2Jw+0Z/0qhSbG1A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/netbsd-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.5.tgz", + "integrity": "sha512-kL2l+xScnAy/E/3119OggX8SrWyBEcqAh8aOY1gr4gPvw76la2GlD4Ymf832UCVbmuWeTf2adkZDK+h0Z/fB4g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/openbsd-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.5.tgz", + "integrity": "sha512-sPOfhtzFufQfTBgRnE1DIJjzsXukKSvZxloZbkJDG383q0awVAq600pc1nfqBcl0ice/WN9p4qLc39WhBShRTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/sunos-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.5.tgz", + "integrity": "sha512-dGZkBXaafuKLpDSjKcB0ax0FL36YXCvJNnztjKV+6CO82tTYVDSH2lifitJ29jxRMoUhgkg9a+VA/B03WK5lcg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/win32-arm64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.5.tgz", + "integrity": "sha512-dWVjD9y03ilhdRQ6Xig1NWNgfLtf2o/STKTS+eZuF90fI2BhbwD6WlaiCGKptlqXlURVB5AUOxUj09LuwKGDTg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/win32-ia32": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.5.tgz", + "integrity": "sha512-4liggWIA4oDgUxqpZwrDhmEfAH4d0iljanDOK7AnVU89T6CzHon/ony8C5LeOdfgx60x5cnQJFZwEydVlYx4iw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/@esbuild/win32-x64": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.5.tgz", + "integrity": "sha512-czTrygUsB/jlM8qEW5MD8bgYU2Xg14lo6kBDXW6HdxKjh8M5PzETGiSHaz9MtbXBYDloHNUAUW2tMiKW4KM9Mw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/svelte-i18n/node_modules/esbuild": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.5.tgz", + "integrity": "sha512-bUxalY7b1g8vNhQKdB24QDmHeY4V4tw/s6Ak5z+jJX9laP5MoQseTOMemAr0gxssjNcH0MCViG8ONI2kksvfFQ==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.19.5", + "@esbuild/android-arm64": "0.19.5", + "@esbuild/android-x64": "0.19.5", + "@esbuild/darwin-arm64": "0.19.5", + "@esbuild/darwin-x64": "0.19.5", + "@esbuild/freebsd-arm64": "0.19.5", + "@esbuild/freebsd-x64": "0.19.5", + "@esbuild/linux-arm": "0.19.5", + "@esbuild/linux-arm64": "0.19.5", + "@esbuild/linux-ia32": "0.19.5", + "@esbuild/linux-loong64": "0.19.5", + "@esbuild/linux-mips64el": "0.19.5", + "@esbuild/linux-ppc64": "0.19.5", + "@esbuild/linux-riscv64": "0.19.5", + "@esbuild/linux-s390x": "0.19.5", + "@esbuild/linux-x64": "0.19.5", + "@esbuild/netbsd-x64": "0.19.5", + "@esbuild/openbsd-x64": "0.19.5", + "@esbuild/sunos-x64": "0.19.5", + "@esbuild/win32-arm64": "0.19.5", + "@esbuild/win32-ia32": "0.19.5", + "@esbuild/win32-x64": "0.19.5" + } + }, + "node_modules/svelte-i18n/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, "node_modules/svelte-preprocess": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.0.4.tgz", @@ -4000,6 +4639,16 @@ "node": ">=0.8" } }, + "node_modules/timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dev": true, + "dependencies": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, "node_modules/tiny-glob": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", @@ -4122,6 +4771,12 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/source/SIL.AppBuilder.Portal/package.json b/source/SIL.AppBuilder.Portal/package.json index 628d959f9..0e9dc1f07 100644 --- a/source/SIL.AppBuilder.Portal/package.json +++ b/source/SIL.AppBuilder.Portal/package.json @@ -18,6 +18,7 @@ "seed": "ts-node --esm prisma/seed.ts" }, "devDependencies": { + "@iconify/svelte": "^3.1.4", "@playwright/test": "^1.28.1", "@prisma/client": "^5.4.2", "@sveltejs/adapter-auto": "^2.0.0", @@ -38,6 +39,7 @@ "prisma": "^5.4.2", "svelte": "^4.0.5", "svelte-check": "^3.4.3", + "svelte-i18n": "^4.0.0", "tailwindcss": "^3.3.3", "ts-node": "^10.9.1", "tslib": "^2.4.1", diff --git a/source/SIL.AppBuilder.Portal/src/hooks.server.ts b/source/SIL.AppBuilder.Portal/src/hooks.server.ts new file mode 100644 index 000000000..344b13b6c --- /dev/null +++ b/source/SIL.AppBuilder.Portal/src/hooks.server.ts @@ -0,0 +1,11 @@ +// hooks.server.ts +import type { Handle } from '@sveltejs/kit'; +import { locale } from 'svelte-i18n'; + +export const handle: Handle = async ({ event, resolve }) => { + const lang = event.request.headers.get('accept-language')?.split(',')[0]; + if (lang) { + locale.set(lang); + } + return resolve(event); +}; diff --git a/source/SIL.AppBuilder.Portal/src/lib/components/Dropdown.svelte b/source/SIL.AppBuilder.Portal/src/lib/components/Dropdown.svelte new file mode 100644 index 000000000..967f7af5c --- /dev/null +++ b/source/SIL.AppBuilder.Portal/src/lib/components/Dropdown.svelte @@ -0,0 +1,26 @@ + + + +
+ + + +
dispatch('nav-end')} + > + +
+
diff --git a/source/SIL.AppBuilder.Portal/src/lib/components/LanguageSelector.svelte b/source/SIL.AppBuilder.Portal/src/lib/components/LanguageSelector.svelte new file mode 100644 index 000000000..9cfa25ce7 --- /dev/null +++ b/source/SIL.AppBuilder.Portal/src/lib/components/LanguageSelector.svelte @@ -0,0 +1,50 @@ + + +{#key $_('lang')} + +{/key} diff --git a/source/SIL.AppBuilder.Portal/src/lib/i18n.js b/source/SIL.AppBuilder.Portal/src/lib/i18n.js new file mode 100644 index 000000000..51bec8c1e --- /dev/null +++ b/source/SIL.AppBuilder.Portal/src/lib/i18n.js @@ -0,0 +1,11 @@ +import { register, init, getLocaleFromNavigator } from 'svelte-i18n'; + +let fallback = 'en'; + +register('en', () => import('./locales/en-us.json')); +register('es', () => import('./locales/es-419.json')); +register('fr', () => import('./locales/fr-FR.json')); +init({ + initialLocale: getLocaleFromNavigator(), + fallbackLocale: fallback +}); diff --git a/source/SIL.AppBuilder.Portal/src/lib/icons/ArrowBackIcon.svelte b/source/SIL.AppBuilder.Portal/src/lib/icons/ArrowBackIcon.svelte new file mode 100644 index 000000000..7b198ba00 --- /dev/null +++ b/source/SIL.AppBuilder.Portal/src/lib/icons/ArrowBackIcon.svelte @@ -0,0 +1,12 @@ + + + diff --git a/source/SIL.AppBuilder.Portal/src/lib/icons/HamburgerIcon.svelte b/source/SIL.AppBuilder.Portal/src/lib/icons/HamburgerIcon.svelte new file mode 100644 index 000000000..6554b3e35 --- /dev/null +++ b/source/SIL.AppBuilder.Portal/src/lib/icons/HamburgerIcon.svelte @@ -0,0 +1,12 @@ + + + diff --git a/source/SIL.AppBuilder.Portal/src/lib/icons/LanguageIcon.svelte b/source/SIL.AppBuilder.Portal/src/lib/icons/LanguageIcon.svelte new file mode 100644 index 000000000..a937832c6 --- /dev/null +++ b/source/SIL.AppBuilder.Portal/src/lib/icons/LanguageIcon.svelte @@ -0,0 +1,20 @@ + + + diff --git a/source/SIL.AppBuilder.Portal/src/lib/icons/index.js b/source/SIL.AppBuilder.Portal/src/lib/icons/index.js new file mode 100644 index 000000000..f6a00bb6e --- /dev/null +++ b/source/SIL.AppBuilder.Portal/src/lib/icons/index.js @@ -0,0 +1,9 @@ +import ArrowBackIcon from './ArrowBackIcon.svelte'; +import HamburgerIcon from './HamburgerIcon.svelte'; +import LanguageIcon from './LanguageIcon.svelte'; + +export { + ArrowBackIcon, + HamburgerIcon, + LanguageIcon +} \ No newline at end of file diff --git a/source/SIL.AppBuilder.Portal/src/lib/locales/en-us.json b/source/SIL.AppBuilder.Portal/src/lib/locales/en-us.json new file mode 100644 index 000000000..1572bb48d --- /dev/null +++ b/source/SIL.AppBuilder.Portal/src/lib/locales/en-us.json @@ -0,0 +1,601 @@ +{ + "appName": "Scriptoria", + "welcome": "Welcome to Scriptoria", + "search": "Search", + "contactUs": "Contact Us", + "exampleForm": "Example Form", + "updated": "Updated!", + "opensource": "Open Source", + "home": "Home", + "tabAppName": "{count, plural, =0 {} other {({ count })}} Scriptoria", + "locale-picker": { + "code": "Code", + "country": "Country", + "other": "Other Names", + "label": "Language", + "placeholder": "Search by Language...", + "region": "{num, plural, one {Region} other {Regions}}", + "name": "{num, plural, one {Name} other {Names}}", + "tag": "{num, plural, one {Tag} other {Tags}}", + "variant": "{num, plural, one {Variant} other {Variants}}", + "regionName": "Region Name" + }, + "attributions": { + "title": "Open Source Project used in Scriptoria", + "subtitle": "Libraries used by License" + }, + "notifications": { + "buildComplete": "The build for {projectName} has completed!", + "buildServerConnectionLost": "Connection to the build server has been lost!" + }, + "common": { + "search": "Search", + "noResults": "No Results...", + "change": "Change", + "cancel": "Cancel", + "save": "Save", + "add": "Add", + "name": "Name", + "clickToEdit": "Click to edit", + "none": "None", + "abbreviation": "Abbreviation", + "general": "General Information", + "notAvailable": "Not Available", + "archive": "Archive", + "reactivate": "Reactivate", + "build": "Build / Rebuild", + "rebuild": "Rebuild / Republish", + "updated": "Updated", + "continue": "Continue", + "error": "Error", + "workflow": "Workflow", + "default": "Default" + }, + "models": { + "add": "Add {name}", + "edit": "Edit {name}", + "save": "Save {name}", + "createSuccess": "{name} was successfully created!", + "updateSuccess": "{name} was successfully updated!" + }, + "auth": { + "title": "Scriptoria", + "signup": "Sign Up", + "login": "Log In" + }, + "directory": { + "title": "Project Directory {numProjects, plural, =0 {} other {({ numProjects })}}", + "search-help": "This allows you to search over:
• Project Name
• Project Language
• Owner Name
• Organization Name
• Group Name", + "filters": { + "dateRange": "Project Updated Date Between" + } + }, + "header": { + "myProfile": "My Profile", + "community": "Community", + "help": "Help", + "signOut": "Sign out", + "clearAll": "Clear All", + "emptyNotifications": "You have no notifications." + }, + "sidebar": { + "myTasks": "My Tasks {count, plural, =0 {} other {({ count })}}", + "myProjects": "My Projects", + "activeProjects": "Active Projects", + "organizationProjects": "Organization Projects", + "users": "Users", + "organizationSettings": "Organization Settings", + "adminSettings": "Admin", + "projectDirectory": "Project Directory", + "addProject": "Add Project", + "importProjects": "Import Projects" + }, + "invitations": { + "orgPrompt": "Like to sign up your organization?", + "missingTokenTitle": "Your invitation token is missing", + "missingTokenPrompt": "Please check the link and try again", + "orgInviteTitle": "You have been invited to create an organization!", + "orgName": "Organization Name", + "orgUrl": "Organization Website URL", + "orgSubmit": "Add Organization" + }, + "newOrganization": { + "title": "Add organization" + }, + "org": { + "allOrganizations": "All Organizations", + "createSuccess": "Organization created successfully!", + "settingsTitle": "Organization Settings", + "logoUrl": "Logo URL", + "noteLogUrl": "Note: For optimal quality use a square image", + "productsTitle": "Products and Publishing", + "makePrivateTitle": "Make Projects Public by Default", + "makePrivateDescription": "\n When a new project is created, it will be defaulted to Public.\n (Private projects cannot be viewed by anyone outside of your organization)", + "productSelectTitle": "Select all the products you would like to make available to your organization", + "noproducts": "No products available", + "storesTitle": "Stores", + "storeSelectTitle": "Select all the stores you would like to make available to your organization", + "nostores": "No stores available", + "navBasic": "Basic Info", + "navProducts": "Products & Publishing", + "navStores": "Stores", + "navGroups": "Groups", + "nameError": "Name cannot be empty", + "abbreviationError": "Abbreviation cannot be empty", + "groupCreated": "Group created", + "groupEdited": "Group edited", + "groupDeleted": "Group deleted", + "navInfrastructure": "Infrastructure", + "infrastructureTitle": "Infrastructure", + "useDefaultBuildEngineTitle": "Use Default Build Engine", + "groupsTitle": "Groups", + "noGroups": "Your organization has no groups", + "addGroupButton": "Add Group", + "basicTitle": "Basic Info", + "orgName": "Organization Name", + "save": "Save", + "buildEngineUrl": "Build Engine URL", + "buildEngineApiAccessToken": "Build Engine API Access Token" + }, + "products": { + "definition": "Useful files that result from a series of steps.", + "storeSelect": "Select a store for {name}", + "noStoresAvailable": "There are no stores available for the selected product. Please contact your organization administrator.", + "actions": { + "executed": "{actionName} was successfully executed.", + "cancelled": "{actionName} was successfully cancelled.", + "rebuild": "Rebuild", + "republish": "Republish", + "cancel": "Cancel", + "noneAvailable": "No actions are currently available for this product.", + "bulkNotAllAllowed": "Not all of the selected projects' products can have the {action} action(s) applied.", + "dispatched": "The {action} action has been dispatched.", + "properties": "Properties" + }, + "files": { + "title": "Product Files" + } + }, + "profile": { + "title": "Profile", + "pictureTitle": "Profile Picture", + "general": "General", + "generalInformation": "General Information", + "updated": "Profile updated successfully!", + "updatePicture": "Update your picture at Gravatar.com", + "uploadPicture": "Upload new picture", + "firstName": "First name", + "lastName": "Last name", + "name": "Display Name", + "email": "Email", + "phone": "Phone", + "location": "Location", + "timezone": "Timezone", + "locale": "Locale", + "timezonePlaceholder": "Select your timezone...", + "notificationSettingsTitle": "Notification Settings", + "optOutOfEmailOption": "I want to receive email notifications", + "sshSettingsTitle": "Manage Personal SSH Keys", + "sshKeyLabel": "Publishing SSH Key", + "visibleProfile": "Profile visibility", + "noPhone": "no phone added", + "noTimezone": "(GMT-0)", + "visibility": { + "visible": "My profile information is publicly viewable", + "restricted": "My profile information is restricted from the public" + } + }, + "errors": { + "generic": "An error occurred! {errorMessage}", + "requiredField": "The {field} is required, but has no value", + "notAuthorized": "You must login. This could be due to a prior login expiring.", + "notFoundTitle": "Not Found!", + "notFoundDescription": "Something went wrong and the page or resource could not be found!", + "groupRequired": "You must be a member of at least one group.", + "userForbidden": "An error occurred: Forbidden. Please contact your organization administrator.", + "friendlyForbidden": "You are not allowed to do that. Please contact your organization administrator", + "forbiddenForAllOrgs": "You are not allowed to do that. Please select an organization", + "notAMemberOfOrg": "You are not a member of that organization", + "notactiveUser": "User is not Active", + "notactiveUserText": "\n This user is currently set to not active.\n

\n Please contact your organization administrator to discuss the reason for the status change.\n ", + "orgMembershipRequired": "Organization Membership is Required", + "orgMembershipRequiredText": "\n In order to use Scriptoria, you must be a member of at least one organization.\n

\n Please contact your organization administrator to discuss receiving an invite to\n an organization on Scriptoria.\n ", + "orgMembershipChanged": "Organization Membership has Changed", + "orgMembershipChangedText": "\n Your organization membership has changed.\n

\n This can take a few moments to process. Please sign out, wait a minute, and then sign in again for the change to take effect.\n ", + "orgMustBeSelected": "An organization must be selected to view this page", + "verifyEmailTitle": "Please verify your email address", + "verifyEmailDescription": "\n In order to use Scriptoria, we need you to verify your email address.\n

\n Please log into your email and clik the verification link. ", + "invalidProjectSelection": "No valid products available for selected project(s)" + }, + "tasks": { + "title": "My Tasks", + "project": "Project", + "product": "Product", + "assignedTo": "Assigned To", + "status": "Status", + "waitTime": "Wait Time", + "unclaimed": "[unclaimed]", + "noTasksTitle": "No tasks are assigned to you.", + "noTasksDescription": "Tasks that require your attention will appear here.", + "reassign": "Reassign", + "waiting": "Waiting {waitTime}", + "forNames": "for {allowedNames} to {activityName}", + "scriptoria": "Scriptoria" + }, + "projects": { + "noBuilds": "No Builds Yet", + "latestBuild": "Latest Build ({version})", + "buildPending": "Build Pending", + "buildFailed": "Build Failed", + "switcher": { + "myProjects": "My Projects ({numProjects})", + "archived": "Archived ({numProjects})", + "dropdown": { + "orgProjects": "Organization Projects", + "myProjects": "My Projects", + "activeProjects": "Active Projects", + "archived": "Archived Projects", + "all": "All Projects" + } + }, + "bulk": { + "buildModal": { + "title": "Perform Bulk Rebuild/Republish" + } + } + }, + "productDefinitions": { + "filterAllProjects": "All projects that contain..." + }, + "projectImport": { + "importFile": "Import JSON File", + "createSuccess": "Project Import successfully created. You will receive an email when the import is completed." + }, + "project": { + "title": "Project", + "organizationContact": "Organization Contact: ", + "projectOwner": "Project Owner: ", + "claimOwnership": "Claim Ownership", + "claimSuccess": "Succesfully Claimed", + "editProject": "Edit Project", + "newProject": "New Project", + "importProjects": "Import Projects", + "importProjectsHelp": "Import Projects Help", + "projectName": "Project Name", + "noAvailableGroups": "There are no available groups for the selected organization", + "projectDescription": "Description", + "projectGroup": "Project Group", + "languageCode": "Language Code", + "type": "Type", + "public": "Public", + "private": "Private", + "visibilityLabel": "Public", + "visibilityDescription": "If you make your project Private, it will not be visible in the directory or accessible by other organizations", + "createdOn": "Created", + "overview": "Overview", + "productFiles": "Product files", + "dropdown": { + "transfer": "Transfer Ownership", + "archive": "Archive", + "reactivate": "Reactivate", + "build": "Build" + }, + "details": { + "title": "Details", + "language": "Language", + "type": "Project Type" + }, + "products": { + "title": "Products", + "empty": "You have no products for this project.", + "addRemove": "Add or Remove Products", + "add": "Add Products", + "remove": "Remove Products", + "popup": { + "addTitle": "Select Product to Add", + "removeTitle": "Select Product to Remove", + "done": "Done", + "empty": "No products available", + "details": "Details", + "properties": "Publishing Properties" + }, + "publications": { + "channel": "Channel", + "status": "Status", + "date": "Publish Date", + "url": "Publish Url", + "succeeded": "Success", + "failed": "Failure", + "console": "Console Text" + }, + "options": { + "update": "update", + "publish": "publish" + }, + "transitions": { + "productDetails": "Product Details", + "storeName": "Store Name", + "state": "State", + "user": "User", + "command": "Command", + "comment": "Comment", + "date": "Date", + "transitionTypes": { + "1": "Activity", + "2": "{workflowType} Workflow Started", + "3": "{workflowType} Workflow Completed", + "4": "{workflowType} Workflow Cancelled", + "5": "{workflowType} Project Access" + } + }, + "properties": { + "computeType": "Compute Type", + "selectComputeType": "Select compute type", + "small": "Small", + "medium": "Medium", + "title": "Product Publishing Properties" + }, + "updated": "Updated", + "size": "Size", + "filename": "Filename", + "published": "Published", + "unpublished": "Unpublished", + "numArtifacts": "{amount, plural, =0 {No Product Files} other {{ amount } Product Files}}", + "noArtifacts": "No Product Files", + "rebuild": "rebuild", + "creationInProgress": "Pending: You cannot add a product until the project setup has been completed." + }, + "settings": { + "title": "Settings", + "automaticRebuild": { + "title": "Automatic Rebuilds", + "description": "When automatic rebuilds are on, Scriptoria will automatically rebuild your products when the input source is updated" + }, + "organizationDownloads": { + "title": "Allow Other Organizations to download", + "description": "When this setting is on, any Scriptoria User that is able to view your project in the Directory will be able to download the Product Files (the outputs of the products)." + }, + "visibility": { + "title": "Public Visibility", + "description": "Public Projects allow any Scriptoria User to view your project in the Directory" + } + }, + "side": { + "repositoryLocation": "Repository Location", + "organization": "Organization", + "projectOwner": "Project Owner", + "projectGroup": "Project Group", + "authors": { + "title": "Authors", + "add": "add author", + "close": "close", + "form": { + "user": "user", + "userError": "User cannot be empty", + "submit": "Add Author" + } + }, + "reviewers": { + "title": "Reviewers", + "add": "add reviewer", + "close": "close", + "form": { + "name": "name", + "nameError": "Name cannot be empty", + "email": "email", + "emptyEmailError": "Email cannot be empty", + "invalidEmailError": "Invalid email address", + "submit": "Add Reviewer" + } + } + }, + "operations": { + "archive": { + "success": "Project archived", + "error": "There was an error trying to archive the project" + }, + "reactivate": { + "success": "Project reactivated", + "error": "There was an error trying to reactivate the project" + }, + "automaticBuilds": { + "on": "Automatic builds is ON", + "off": "Automatic builds is OFF", + "error": "Error: We could not change automatic build status" + }, + "allowDownloads": { + "on": "Allow project download is ON", + "off": "Allow project download is OFF", + "error": "Error: We could not change Allow Download status" + }, + "isPublic": { + "on": "Project visibility is set to Public", + "off": "Project visibility is set to Private", + "error": "Error: We could not change Project visibility" + } + } + }, + "projectTable": { + "columns": { + "project": "Project", + "owner": "Owner", + "organization": "Organization", + "language": "Language", + "group": "Group", + "buildVersion": "Build Version", + "buildDate": "Build Date", + "createdOn": "Created On", + "updatedOn": "Updated On", + "activeSince": "Active Since" + }, + "empty": "No projects found", + "products": "Products", + "noProducts": "This project has no configured products" + }, + "users": { + "settingsTitle": "User Settings", + "userProfile": "User Profile", + "userGroups": "Group Memberships", + "userRoles": "Organization Roles", + "noneFound": "No users matching the selected criteria were found.", + "noRoles": "No roles assigned", + "title": "Manage Users", + "addUser": { + "placeholder": "Enter an email", + "button": "Add User to {organization}", + "modalTitle": "Add User to {organization}", + "modalAddButton": "Add", + "error": "No user was found with that email address. Please ask them to create an account." + }, + "table": { + "columns": { + "name": "Name", + "role": "Role", + "groups": "Groups", + "active": "Active" + } + }, + "operations": { + "lock": { + "success": "User is locked. A locked user will not be able to log in to Scriptoria.", + "error": "There was an error locking the user" + }, + "unlock": { + "success": "User is active. The user will now be able to log in to Scriptoria.", + "error": "there was an error activating the user" + } + } + }, + "stores": { + "name": "Store", + "listTitle": "Stores", + "attributes": { + "name": "Name", + "description": "Description" + } + }, + "storeTypes": { + "name": "Store Type", + "listTitle": "Store Types" + }, + "admin": { + "settings": { + "title": "Admin settings", + "navigation": { + "organizations": "Organizations", + "workflowdefinitions": "Workflow Definitions", + "productDefinitions": "Product Definitions", + "storeTypes": "Store Types", + "stores": "Stores", + "buildEngines": "Build Engine Statuses" + }, + "organizations": { + "title": "Organizations", + "name": "Organization Name", + "owner": "Owner", + "emptyOwner": "Need to select an owner for this organization", + "add": "Add Organization", + "addSuccess": "Organization added", + "edit": "Edit Organization", + "editSuccess": "Organization updated", + "websiteURL": "Website URL", + "buildEngineURL": "Build Engine URL", + "accessToken": "Build Engine API Access Token", + "logoURL": "Logo URL", + "publicByDefault": "Public By Default", + "publicByDefaultDescription": "Projects created under this organization are set to public by default" + }, + "workflowDefinitions": { + "title": "Workflow Definitions", + "name": "Workflow Definition Name", + "description": "Description", + "workflowScheme": "Workflow Scheme", + "workflowBusinessFlow": "Workflow Business Flow", + "properties": "Properties", + "add": "Add Workflow Definition", + "edit": "Edit Workflow Definition", + "storeType": "Store Type", + "enabled": "Enabled", + "enabledDescription": "Workflow definitions may not be used until enabled.", + "workflowAdded": "Workflow Definition added", + "workflowUpdated": "Workflow Definition updated", + "emptyStoreType": "Need to select a store type for this workflow definition", + "emptyWorkflowType": "Need to select a workflow type for this workflow definition", + "workflowType": "Workflow Type", + "workflowTypes": { + "1": "Startup", + "2": "Rebuild", + "3": "Republish" + } + }, + "productDefinitions": { + "title": "Product Definitions", + "name": "Product definition Name", + "add": "Add Product Definition", + "edit": "Edit Product Definition", + "description": "Description", + "properties": "Properties", + "type": "Application Type", + "workflow": "Workflow", + "republishWorkflow": "Republish Workflow", + "rebuildWorkflow": "Rebuild Workflow", + "addSuccess": "Product Definition added", + "editSuccess": "Product Definition updated", + "emptyName": "Name cannot be empty", + "emptyType": "Need to select an Application Type", + "emptyWorkflow": "Need to select a Workflow definition", + "noWorkflow": "No Workflow Required" + }, + "storeTypes": { + "title": "Store Types", + "name": "Store Type Name", + "add": "Add Store Type", + "edit": "Edit Store Type", + "description": "Description", + "type": "Application Type", + "workflow": "Workflow", + "addSuccess": "Store Type added", + "editSuccess": "Store Type updated", + "emptyName": "Name cannot be empty", + "emptyType": "Need to select an Application Type", + "emptyWorkflow": "Need to select a Workflow definition" + }, + "buildEngines": { + "title": "Build Engine Statuses", + "accessToken": "Build Engine API Access Token", + "websiteURL": "Website URL", + "connected": "Connected", + "disconnected": "Disconnected", + "status": "Status", + "lastUpdated": "Last update" + } + } + }, + "organization-membership": { + "invite": { + "error": { + "expired": "Invitation has expired", + "redeemed": "Invitation has already been redeemed", + "not-found": "Invitation was not found", + "unexpected": "Unexpected error occured: {response}", + "invalid-response": "We've received an invalid response... please refresh the page to try again." + }, + "create": { + "success": "Invite sent to {email}.", + "error": "Error occured while trying to invite user.", + "invite-user-button-title": "Invite User", + "invite-user-modal-title": "Invite User", + "email-input-placeholder": "Enter email address", + "send-invite-button": "Send Invite" + }, + "redemptionTitle": "Looking up invitation..." + } + }, + "system": { + "build-failed": "Build failed", + "publish-failed": "Publish failed" + }, + "downloads": { + "title": "Downloads" + } +} diff --git a/source/SIL.AppBuilder.Portal/src/lib/locales/es-419.json b/source/SIL.AppBuilder.Portal/src/lib/locales/es-419.json new file mode 100644 index 000000000..d7553d123 --- /dev/null +++ b/source/SIL.AppBuilder.Portal/src/lib/locales/es-419.json @@ -0,0 +1,601 @@ +{ + "appName": "Scriptoria", + "welcome": "Bienvenidos a Scriptoria", + "search": "Buscar", + "contactUs": "Contáctanos", + "exampleForm": "Formulario de ejemplo", + "updated": "¡Actualizado!", + "opensource": "Código abierto", + "home": "Inicio", + "tabAppName": "{count, plural, =0 {} other {({ count })}} Scriptoria", + "locale-picker": { + "code": "Código", + "country": "País", + "other": "Otros nombres", + "label": "Lenguaje", + "placeholder": "Buscar por idioma...", + "region": "{num, plural,one {Region}other {Region}}", + "name": "{num, plural, one {Name} other {Names}}", + "tag": "{num, plural, one {Tag} other {Tags}}", + "variant": "{num, plural, one {Variant} other {Variants}}", + "regionName": "Nombre de región" + }, + "attributions": { + "title": "Proyecto de código abierto usado en Scriptoria", + "subtitle": "Librerías usadas por la licencia" + }, + "notifications": { + "buildComplete": "¡La construcción para {projectName} se ha completado!", + "buildServerConnectionLost": "¡Se ha perdido la conexión con el servidor de compilación!" + }, + "common": { + "search": "Buscar", + "noResults": "Sin resultados...", + "change": "Cambiar", + "cancel": "Cancelar", + "save": "Guardar", + "add": "Añadir", + "name": "Nombre", + "clickToEdit": "Haga clic para editar", + "none": "Ninguno", + "abbreviation": "Abreviatura", + "general": "Información general", + "notAvailable": "No disponible", + "archive": "Archivar", + "reactivate": "Reactivar", + "build": "Construir / Reconstruir", + "rebuild": "Reconstruir/Volver a publicar", + "updated": "Actualizado", + "continue": "Continuar", + "error": "Error", + "workflow": "Flujo trabajo", + "default": "Default" + }, + "models": { + "add": "Añadir {name}", + "edit": "Editar {name}", + "save": "Guardar {name}", + "createSuccess": "¡{name} fue creado con éxito!", + "updateSuccess": "¡{name} fue actualizado con éxito!" + }, + "auth": { + "title": "Scriptoria", + "signup": "Registrarse", + "login": "Ingresar" + }, + "directory": { + "title": "Directorio de proyectos ({ numProjects })", + "search-help": "This allows you to search over:
• Project Name
• Project Language
• Owner Name
• Organization Name
• Group Name", + "filters": { + "dateRange": "Rango de Fechas" + } + }, + "header": { + "myProfile": "Mi perfil", + "community": "Community", + "help": "Ayuda", + "signOut": "Salir", + "clearAll": "Limpiar todo", + "emptyNotifications": "No tienes notificaciones." + }, + "sidebar": { + "myTasks": "¡Mis tareas {count, plural, one {} =0 {} other {({ count })}}", + "myProjects": "Mis Proyectos", + "activeProjects": "Proyectos activos", + "organizationProjects": "Proyectos de organización", + "users": "Usuarios", + "organizationSettings": "Configuración de organización", + "adminSettings": "Administrador", + "projectDirectory": "Directorio de proyectos", + "addProject": "Agregar proyectos", + "importProjects": "Import Projects" + }, + "invitations": { + "orgPrompt": "¿Te gustaría registrar a tu organización?", + "missingTokenTitle": "El token de invitación no existe", + "missingTokenPrompt": "Por favor revise el enlace y vuelva a intentarlo", + "orgInviteTitle": "¡Ud. ha sido invitado a crear una organización!", + "orgName": "Nombre de organización", + "orgUrl": "Dirección Web de la organización", + "orgSubmit": "Agregar organización" + }, + "newOrganization": { + "title": "Agregar organización" + }, + "org": { + "allOrganizations": "Todas las organizaciones", + "createSuccess": "¡Organización creada exitosamente!", + "settingsTitle": "Configuración de organización", + "logoUrl": "Seleccionar logo", + "noteLogUrl": "Nota: Para una calidad óptima, use una imagen cuadrada", + "productsTitle": "Productos y Publicaciones", + "makePrivateTitle": "Hacer Proyectos públicos por defecto", + "makePrivateDescription": "\n Cuando un proyecto es creado, será Público por defecto.\n (Los proyectos privados no pueden ser visto por nadie fuera de su organización)", + "productSelectTitle": "Selecciona todos los productos que quisieras estén disponibles para su organización", + "noproducts": "No hay productos disponibles", + "storesTitle": "Tiendas", + "storeSelectTitle": "Seleccione todas las tiendas que desea poner a disposición de su organización", + "nostores": "No hay tiendas disponibles", + "navBasic": "Información básica", + "navProducts": "Productos", + "navStores": "Tiendas", + "navGroups": "Grupos", + "nameError": "El nombre no puede estar vacío", + "abbreviationError": "La abreviatura no puede estar vacía", + "groupCreated": "Grupo creado", + "groupEdited": "Grupo editado", + "groupDeleted": "Grupo eliminado", + "navInfrastructure": "Infraestructura", + "infrastructureTitle": "Infraestructura", + "useDefaultBuildEngineTitle": "Usar el motor de compilación predeterminado", + "groupsTitle": "Grupos", + "noGroups": "Su organización no tiene grupos", + "addGroupButton": "Agregar grupo", + "basicTitle": "Información básica", + "orgName": "Nombre de organización", + "save": "Guardar", + "buildEngineUrl": "URL del motor de compilación", + "buildEngineApiAccessToken": "Token de acceso del motor de construcción" + }, + "products": { + "definition": "Archivos útiles que resultan de una serie de pasos.", + "storeSelect": "Seleccione una tienda para {name}", + "noStoresAvailable": "No hay tiendas disponibles para el producto seleccionado. Por favor, contacte con el administrador de su organización.", + "actions": { + "executed": "{actionName} fue ejecutado con éxito.", + "cancelled": "{actionName} fue cancelado con éxito.", + "rebuild": "Reconstruir", + "republish": "Publicar nuevamente", + "cancel": "Cancelar", + "noneAvailable": "No hay acciones disponibles actualmente para este producto.", + "bulkNotAllAllowed": "No todos los productos de los proyectos seleccionados pueden tener la acción {action} aplicada.", + "dispatched": "La acción {action} ha sido enviada.", + "properties": "Properties" + }, + "files": { + "title": "Product Files" + } + }, + "profile": { + "title": "Perfil", + "pictureTitle": "Imagen de perfil", + "general": "General", + "generalInformation": "Información general", + "updated": "¡Perfil actualizado con éxito!", + "updatePicture": "Actualize su imagen en Gravatar.com", + "uploadPicture": "Cargar una nueva imagen", + "firstName": "Nombre", + "lastName": "Apellido", + "name": "Display Name", + "email": "Correo electrónico", + "phone": "Teléfono", + "location": "Ubicación", + "timezone": "Zona horaria", + "locale": "Idioma", + "timezonePlaceholder": "Seleccione su zona horaria...", + "notificationSettingsTitle": "Configuración de notificaciones", + "optOutOfEmailOption": "Deseo recibir notificaciones por correo electrónico", + "sshSettingsTitle": "Administrar claves personales SSH", + "sshKeyLabel": "Publicando clave SSH", + "visibleProfile": "Visibilidad del perfil", + "noPhone": "Sin teléfono", + "noTimezone": "(GMT-0)", + "visibility": { + "visible": "La información de mi perfil es pública", + "restricted": "Mi información de perfil es restringida al público" + } + }, + "errors": { + "generic": "¡Ha ocurrido un error! {errorMessage}", + "requiredField": "El {field} es requerido, pero no tiene ningún valor", + "notAuthorized": "Usted debe iniciar sesión. Esto podría ser debido a que expiró un inicio de sesión previo.", + "notFoundTitle": "\n¡No encontrado!", + "notFoundDescription": "¡Algo salió mal y la página o recursos no se pudo encontrar!", + "groupRequired": "Debe ser un miembro de al menos un grupo.", + "userForbidden": "Ocurrió un error: Prohibido. Por favor, contacte al administrador de su organización.", + "friendlyForbidden": "No se le permite hacer eso. Póngase en contacto con el administrador de su organización", + "forbiddenForAllOrgs": "No se le permite hacer eso. Por favor, seleccione una organización", + "notAMemberOfOrg": "No es un miembro de esa organización", + "notactiveUser": "El usuario no está activo", + "notactiveUserText": "\n Este usuario actualmente no está activo.\n

\n Póngase en contacto con el administrador de su organización para discutir el motivo del cambio de estado.\n ", + "orgMembershipRequired": "Se requiere ser miembro de la organización", + "orgMembershipRequiredText": "\n Para utilizar Scriptoria, debe ser miembro de por lo menos una organización.\n

\n Por favor, contacte con el administrador de su organización para solicitar una invitación a\n una organización de Scriptoria.\n ", + "orgMembershipChanged": "Organization Membership has Changed", + "orgMembershipChangedText": "\n Your organization membership has changed.\n

\n This can take a few moments to process. Please sign out, wait a minute, and then sign in again for the change to take effect.\n ", + "orgMustBeSelected": "Debe seleccionar una organización para visualizar esta página", + "verifyEmailTitle": "Por favor, verifique su dirección de correo electrónico", + "verifyEmailDescription": "\nPara poder usar Scriptoria, necesitamos que verifiques tu dirección de correo electrónico.\n

\n Por favor, ingrese a su correo electrónico y haga clic en el enlace de verificación. ", + "invalidProjectSelection": "Productos no válidos disponibles para el/los proyecto(s) seleccionados" + }, + "tasks": { + "title": "Mis tareas", + "project": "Proyecto", + "product": "Producto", + "assignedTo": "Asignado a", + "status": "Estado", + "waitTime": "Tiempo de espera", + "unclaimed": "[sin asignar]", + "noTasksTitle": "No tiene tareas asignadas.", + "noTasksDescription": "Las tareas que requieren su atención aparecerán aquí.", + "reassign": "Reasignar", + "waiting": "Esperando {waitTime}", + "forNames": "para {allowedNames} a {activityName}", + "scriptoria": "Scriptoria" + }, + "projects": { + "noBuilds": "No Builds Yet", + "latestBuild": "Última compilación ({version})", + "buildPending": "Build Pending", + "buildFailed": "Build Failed", + "switcher": { + "myProjects": "Mis proyectos ({numProjects})", + "archived": "Archivados ({numProjects})", + "dropdown": { + "orgProjects": "Proyectos de organización", + "myProjects": "Mis Proyectos", + "activeProjects": "Proyectos activos", + "archived": "Proyectos archivados", + "all": "Todos los proyectos" + } + }, + "bulk": { + "buildModal": { + "title": "Perform Bulk Rebuild/Republish" + } + } + }, + "productDefinitions": { + "filterAllProjects": "Todos los proyectos que contienen..." + }, + "projectImport": { + "importFile": "Import JSON File", + "createSuccess": "Project Import successfully created. You will receive an email when the import is completed." + }, + "project": { + "title": "Proyecto", + "organizationContact": "Contacto de la organización: ", + "projectOwner": "Propietario del proyecto: ", + "claimOwnership": "Claim Ownership", + "claimSuccess": "Succesfully Claimed", + "editProject": "Edit Project", + "newProject": "Nuevo proyecto", + "importProjects": "Import Projects", + "importProjectsHelp": "Import Projects Help", + "projectName": "Nombre de proyecto", + "noAvailableGroups": "No hay grupos disponibles para la organización seleccionada", + "projectDescription": "Descripción", + "projectGroup": "Grupo de proyecto", + "languageCode": "Código de lenguaje", + "type": "Tipo", + "public": "Público", + "private": "Privado", + "visibilityLabel": "Público", + "visibilityDescription": "Si usted hace su proyecto privado, no será visible en el directorio o accesible por otras organizaciones", + "createdOn": "Creado", + "overview": "Información", + "productFiles": "Archivos de producto", + "dropdown": { + "transfer": "Transferir propiedad", + "archive": "Archivar", + "reactivate": "Reactivar", + "build": "Compilar" + }, + "details": { + "title": "Detalles", + "language": "Lenguaje", + "type": "Tipo de proyecto" + }, + "products": { + "title": "Productos", + "empty": "No tiene productos para este proyecto.", + "addRemove": "Añadir o quitar productos", + "add": "Add Products", + "remove": "Remove Products", + "popup": { + "addTitle": "Select Product to Add", + "removeTitle": "Select Product to Remove", + "done": "Hecho", + "empty": "No hay productos disponibles", + "details": "Detalles", + "properties": "Publishing Properties" + }, + "publications": { + "channel": "Channel", + "status": "Estado", + "date": "Publish Date", + "url": "Publish Url", + "succeeded": "Success", + "failed": "Failure", + "console": "Console Text" + }, + "options": { + "update": "actualizar", + "publish": "publicar" + }, + "transitions": { + "productDetails": "Product Details", + "storeName": "Store Name", + "state": "State", + "user": "Usuario", + "command": "Comando", + "comment": "Comentario", + "date": "Fecha", + "transitionTypes": { + "1": "Actividad", + "2": "{workflowType} Workflow Started", + "3": "{workflowType} Workflow Completed", + "4": "{workflowType} Workflow Cancelled", + "5": "{workflowType} Project Access" + } + }, + "properties": { + "computeType": "Compute Type", + "selectComputeType": "Select compute type", + "small": "Small", + "medium": "Medium", + "title": "Product Publishing Properties" + }, + "updated": "Actualizado", + "size": "Tamaño", + "filename": "Nombre de archivo", + "published": "Publicado", + "unpublished": "Sin publicar", + "numArtifacts": "{amount, plural, =0 {No Product Files} other {{ amount } Product Files}}", + "noArtifacts": "No hay archivos de producto", + "rebuild": "reconstruir", + "creationInProgress": "Pendiente: No puede añadir un producto hasta que la configuración del proyecto se haya completado." + }, + "settings": { + "title": "Configuración", + "automaticRebuild": { + "title": "Recompilaciones automáticas", + "description": "Cuando las recompilaciones automáticas están activadas, Scriptoria reconstruirá sus productos automáticamente cuando el código fuente se actualice" + }, + "organizationDownloads": { + "title": "Permitir descargar a otras organizaciones", + "description": "When this setting is on, any Scriptoria User that is able to view your project in the Directory will be able to download the Product Files (the outputs of the products)." + }, + "visibility": { + "title": "Visibilidad pública", + "description": "Los proyectos públicos permiten a cualquier usuario de Scriptoria ver su proyecto en el Directorio" + } + }, + "side": { + "repositoryLocation": "Ubicación del repositorio", + "organization": "Organización", + "projectOwner": "Propietario del proyecto", + "projectGroup": "Grupo de proyecto", + "authors": { + "title": "Authors", + "add": "add author", + "close": "cerrar", + "form": { + "user": "user", + "userError": "User cannot be empty", + "submit": "Add Author" + } + }, + "reviewers": { + "title": "Revisores", + "add": "Agregar revisor", + "close": "cerrar", + "form": { + "name": "nombre", + "nameError": "Nombre no puede estar vacío", + "email": "correo electrónico", + "emptyEmailError": "Correo electrónico no puede estar vacío", + "invalidEmailError": "Dirección de correo electrónico no válida", + "submit": "Agregar revisor" + } + } + }, + "operations": { + "archive": { + "success": "Proyecto archivado", + "error": "Ocurrió un error al intentar archivar el proyecto" + }, + "reactivate": { + "success": "Proyecto reactivado", + "error": "Ocurrió un error al intentar reactivar el proyecto" + }, + "automaticBuilds": { + "on": "Compilaciones automáticas está activada", + "off": "Compilaciones automáticas está desactivada", + "error": "Error: No pudimos cambiar el estado de \"compilación automática\"" + }, + "allowDownloads": { + "on": "Permitir descarga de proyecto está activada", + "off": "Permitir descarga de proyecto está desactivada", + "error": "Error: No pudimos cambiar el estado de \"permitir descargas\"" + }, + "isPublic": { + "on": "La visibilidad del proyecto está establecida como Público", + "off": "La visibilidad del proyecto está establecida como Privado", + "error": "Error: No se ha podido cambiar la visibilidad del proyecto" + } + } + }, + "projectTable": { + "columns": { + "project": "Proyecto", + "owner": "Propietario", + "organization": "Organización", + "language": "Idioma", + "group": "Grupo", + "buildVersion": "Versión de compilación", + "buildDate": "Fecha de compilación", + "createdOn": "Fecha de creación", + "updatedOn": "Fecha de actualización", + "activeSince": "Activo desde" + }, + "empty": "No se encontraron proyectos", + "products": "Productos", + "noProducts": "Este proyecto no tiene productos configurados" + }, + "users": { + "settingsTitle": "Configuración de usuario", + "userProfile": "Perfil de usuario", + "userGroups": "Membresías de grupo", + "userRoles": "Roles de la organización", + "noneFound": "No se encontraron usuarios con esos criterios de búsqueda.", + "noRoles": "No hay roles asignados", + "title": "Administrar usuarios", + "addUser": { + "placeholder": "Ingrese un correo electrónico", + "button": "Añadir usuario a {organization}", + "modalTitle": "Añadir usuario a {organization}", + "modalAddButton": "Añadir", + "error": "No se ha encontrado ningún usuario con esa dirección de correo electrónico. Por favor, pídeles que cree una cuenta." + }, + "table": { + "columns": { + "name": "Nombre", + "role": "Rol", + "groups": "Grupos", + "active": "Activo" + } + }, + "operations": { + "lock": { + "success": "Usuario bloqueado. Un usuario bloqueado no podrá iniciar sesión en Scriptoria.", + "error": "Ocurrió un error al bloquear el usuario" + }, + "unlock": { + "success": "Usuario activo. El usuario ahora podrá iniciar sesión en Scriptoria.", + "error": "ocurrió un error al activar el usuario" + } + } + }, + "stores": { + "name": "Tienda", + "listTitle": "Tiendas", + "attributes": { + "name": "Nombre", + "description": "Descripción" + } + }, + "storeTypes": { + "name": "Tipo de tienda", + "listTitle": "Tipos de tienda" + }, + "admin": { + "settings": { + "title": "Configuración del administrador", + "navigation": { + "organizations": "Organizaciones", + "workflowdefinitions": "Definiciones de flujo de trabajo", + "productDefinitions": "Definiciones de producto", + "storeTypes": "Tipos de tienda", + "stores": "Tiendas", + "buildEngines": "Build Engine Statuses" + }, + "organizations": { + "title": "Organizaciones", + "name": "Nombre de la organización", + "owner": "Propietario", + "emptyOwner": "Necesita seleccionar un propietario para esta organización", + "add": "Añadir organización", + "addSuccess": "Organización añadida", + "edit": "Editar organización", + "editSuccess": "Organización actualizada", + "websiteURL": "URL del sitio web", + "buildEngineURL": "Build Engine URL", + "accessToken": "Build Engine API Access Token", + "logoURL": "URL del logotipo", + "publicByDefault": "Público por defecto", + "publicByDefaultDescription": "Los proyectos creados bajo esta organización son públicos por defecto" + }, + "workflowDefinitions": { + "title": "Definiciones de flujo de trabajo", + "name": "Nombre de la definición del flujo de trabajo", + "description": "Descripción", + "workflowScheme": "Workflow Scheme", + "workflowBusinessFlow": "Workflow Business Flow", + "properties": "Propiedades", + "add": "Add Workflow Definition", + "edit": "Edit Workflow Definition", + "storeType": "Tipo de tienda", + "enabled": "Habilitado", + "enabledDescription": "Workflow definitions may not be used until enabled.", + "workflowAdded": "Workflow Definition added", + "workflowUpdated": "Workflow Definition updated", + "emptyStoreType": "Need to select a store type for this workflow definition", + "emptyWorkflowType": "Need to select a workflow type for this workflow definition", + "workflowType": "Workflow Type", + "workflowTypes": { + "1": "Startup", + "2": "Reconstruir", + "3": "Publicar nuevamente" + } + }, + "productDefinitions": { + "title": "Definiciones de producto", + "name": "Product definition Name", + "add": "Añadir definición de producto", + "edit": "Editar definición de producto", + "description": "Descripción", + "properties": "Propiedades", + "type": "Tipo de aplicación", + "workflow": "Flujo trabajo", + "republishWorkflow": "Republish Workflow", + "rebuildWorkflow": "Rebuild Workflow", + "addSuccess": "Definición del producto añadida", + "editSuccess": "Definición del producto actualizada", + "emptyName": "Nombre no puede estar vacío", + "emptyType": "Necesita seleccionar un tipo de aplicación", + "emptyWorkflow": "Need to select a Workflow definition", + "noWorkflow": "No Workflow Required" + }, + "storeTypes": { + "title": "Tipos de tienda", + "name": "Store Type Name", + "add": "Añadir tipo de tienda", + "edit": "Editar tipo de tienda", + "description": "Descripción", + "type": "Tipo de aplicación", + "workflow": "Flujo de trabajo", + "addSuccess": "Tipo de tienda añadido", + "editSuccess": "Tipo de tienda actualizado", + "emptyName": "Nombre no puede estar vacío", + "emptyType": "Necesita seleccionar un tipo de aplicación", + "emptyWorkflow": "Need to select a Workflow definition" + }, + "buildEngines": { + "title": "Build Engine Statuses", + "accessToken": "Token de acceso del motor de construcción", + "websiteURL": "URL del sitio web", + "connected": "Connected", + "disconnected": "Disconnected", + "status": "Estado", + "lastUpdated": "Last update" + } + } + }, + "organization-membership": { + "invite": { + "error": { + "expired": "La invitación ha caducado", + "redeemed": "La invitación ya ha sido canjeada", + "not-found": "No se encontró la invitación", + "unexpected": "Ocurrió un error inesperado: {response}", + "invalid-response": "Hemos recibido una respuesta no válida... por favor, actualiza la página para intentarlo de nuevo." + }, + "create": { + "success": "Invitación enviada a {email}.", + "error": "Ocurrió un error mientras se intentaba invitar al usuario.", + "invite-user-button-title": "Invitar usuario", + "invite-user-modal-title": "Invitar usuario", + "email-input-placeholder": "Introduzca dirección de correo electrónico", + "send-invite-button": "Enviar invitación" + }, + "redemptionTitle": "Buscando invitación..." + } + }, + "system": { + "build-failed": "Build failed", + "publish-failed": "Publish failed" + }, + "downloads": { + "title": "Downloads" + } +} diff --git a/source/SIL.AppBuilder.Portal/src/lib/locales/fr-FR.json b/source/SIL.AppBuilder.Portal/src/lib/locales/fr-FR.json new file mode 100644 index 000000000..441a8bd2e --- /dev/null +++ b/source/SIL.AppBuilder.Portal/src/lib/locales/fr-FR.json @@ -0,0 +1,601 @@ +{ + "appName": "Scriptoria", + "welcome": "Bienvenue sur Scriptoria", + "search": "Search", + "contactUs": "Contact Us", + "exampleForm": "Example Form", + "updated": "Updated!", + "opensource": "Open Source", + "home": "Home", + "tabAppName": "{count, plural, =0 {} other {({ count })}} Scriptoria", + "locale-picker": { + "code": "Code", + "country": "Country", + "other": "Other Names", + "label": "Language", + "placeholder": "Search by Language...", + "region": "{num, plural, one {Region} other {Regions}}", + "name": "{num, plural, one {Name} other {Names}}", + "tag": "{num, plural, one {Tag} other {Tags}}", + "variant": "{num, plural, one {Variant} other {Variants}}", + "regionName": "Region Name" + }, + "attributions": { + "title": "Open Source Project used in Scriptoria", + "subtitle": "Libraries used by License" + }, + "notifications": { + "buildComplete": "The build for {projectName} has completed!", + "buildServerConnectionLost": "Connection to the build server has been lost!" + }, + "common": { + "search": "Search", + "noResults": "No Results...", + "change": "Change", + "cancel": "Cancel", + "save": "Save", + "add": "Add", + "name": "Name", + "clickToEdit": "Click to edit", + "none": "None", + "abbreviation": "Abbreviation", + "general": "General Information", + "notAvailable": "Not Available", + "archive": "Archive", + "reactivate": "Reactivate", + "build": "Build / Rebuild", + "rebuild": "Rebuild / Republish", + "updated": "Updated", + "continue": "Continue", + "error": "Error", + "workflow": "Workflow", + "default": "Default" + }, + "models": { + "add": "Add {name}", + "edit": "Edit {name}", + "save": "Save {name}", + "createSuccess": "{name} was successfully created!", + "updateSuccess": "{name} was successfully updated!" + }, + "auth": { + "title": "Scriptoria", + "signup": "Sign Up", + "login": "Log In" + }, + "directory": { + "title": "Project Directory {numProjects, plural, =0 {} other {({ numProjects })}}", + "search-help": "This allows you to search over:
• Project Name
• Project Language
• Owner Name
• Organization Name
• Group Name", + "filters": { + "dateRange": "Project Updated Date Between" + } + }, + "header": { + "myProfile": "My Profile", + "community": "Community", + "help": "Help", + "signOut": "Sign out", + "clearAll": "Clear All", + "emptyNotifications": "You have no notifications." + }, + "sidebar": { + "myTasks": "My Tasks {count, plural, =0 {} other {({ count })}}", + "myProjects": "My Projects", + "activeProjects": "Active Projects", + "organizationProjects": "Organization Projects", + "users": "Users", + "organizationSettings": "Organization Settings", + "adminSettings": "Admin", + "projectDirectory": "Project Directory", + "addProject": "Add Project", + "importProjects": "Import Projects" + }, + "invitations": { + "orgPrompt": "Like to sign up your organization?", + "missingTokenTitle": "Your invitation token is missing", + "missingTokenPrompt": "Please check the link and try again", + "orgInviteTitle": "You have been invited to create an organization!", + "orgName": "Organization Name", + "orgUrl": "Organization Website URL", + "orgSubmit": "Add Organization" + }, + "newOrganization": { + "title": "Add organization" + }, + "org": { + "allOrganizations": "All Organizations", + "createSuccess": "Organization created successfully!", + "settingsTitle": "Organization Settings", + "logoUrl": "Logo URL", + "noteLogUrl": "Note: For optimal quality use a square image", + "productsTitle": "Products and Publishing", + "makePrivateTitle": "Make Projects Public by Default", + "makePrivateDescription": "\n When a new project is created, it will be defaulted to Public.\n (Private projects cannot be viewed by anyone outside of your organization)", + "productSelectTitle": "Select all the products you would like to make available to your organization", + "noproducts": "No products available", + "storesTitle": "Stores", + "storeSelectTitle": "Select all the stores you would like to make available to your organization", + "nostores": "No stores available", + "navBasic": "Basic Info", + "navProducts": "Products & Publishing", + "navStores": "Stores", + "navGroups": "Groups", + "nameError": "Name cannot be empty", + "abbreviationError": "Abbreviation cannot be empty", + "groupCreated": "Group created", + "groupEdited": "Group edited", + "groupDeleted": "Group deleted", + "navInfrastructure": "Infrastructure", + "infrastructureTitle": "Infrastructure", + "useDefaultBuildEngineTitle": "Use Default Build Engine", + "groupsTitle": "Groups", + "noGroups": "Your organization has no groups", + "addGroupButton": "Add Group", + "basicTitle": "Basic Info", + "orgName": "Organization Name", + "save": "Save", + "buildEngineUrl": "Build Engine URL", + "buildEngineApiAccessToken": "Build Engine API Access Token" + }, + "products": { + "definition": "Useful files that result from a series of steps.", + "storeSelect": "Select a store for {name}", + "noStoresAvailable": "There are no stores available for the selected product. Please contact your organization administrator.", + "actions": { + "executed": "{actionName} was successfully executed.", + "cancelled": "{actionName} was successfully cancelled.", + "rebuild": "Rebuild", + "republish": "Republish", + "cancel": "Cancel", + "noneAvailable": "No actions are currently available for this product.", + "bulkNotAllAllowed": "Not all of the selected projects' products can have the {action} action(s) applied.", + "dispatched": "The {action} action has been dispatched.", + "properties": "Properties" + }, + "files": { + "title": "Product Files" + } + }, + "profile": { + "title": "Profile", + "pictureTitle": "Profile Picture", + "general": "General", + "generalInformation": "General Information", + "updated": "Profile updated successfully!", + "updatePicture": "Update your picture at Gravatar.com", + "uploadPicture": "Upload new picture", + "firstName": "First name", + "lastName": "Last name", + "name": "Display Name", + "email": "Email", + "phone": "Phone", + "location": "Location", + "timezone": "Timezone", + "locale": "Locale", + "timezonePlaceholder": "Select your timezone...", + "notificationSettingsTitle": "Notification Settings", + "optOutOfEmailOption": "I want to receive email notifications", + "sshSettingsTitle": "Manage Personal SSH Keys", + "sshKeyLabel": "Publishing SSH Key", + "visibleProfile": "Profile visibility", + "noPhone": "no phone added", + "noTimezone": "(GMT-0)", + "visibility": { + "visible": "My profile information is publicly viewable", + "restricted": "My profile information is restricted from the public" + } + }, + "errors": { + "generic": "An error occurred! {errorMessage}", + "requiredField": "The {field} is required, but has no value", + "notAuthorized": "You must login. This could be due to a prior login expiring.", + "notFoundTitle": "Not Found!", + "notFoundDescription": "Something went wrong and the page or resource could not be found!", + "groupRequired": "You must be a member of at least one group.", + "userForbidden": "An error occurred: Forbidden. Please contact your organization administrator.", + "friendlyForbidden": "You are not allowed to do that. Please contact your organization administrator", + "forbiddenForAllOrgs": "You are not allowed to do that. Please select an organization", + "notAMemberOfOrg": "You are not a member of that organization", + "notactiveUser": "User is not Active", + "notactiveUserText": "\n This user is currently set to not active.\n

\n Please contact your organization administrator to discuss the reason for the status change.\n ", + "orgMembershipRequired": "Organization Membership is Required", + "orgMembershipRequiredText": "\n In order to use Scriptoria, you must be a member of at least one organization.\n

\n Please contact your organization administrator to discuss receiving an invite to\n an organization on Scriptoria.\n ", + "orgMembershipChanged": "Organization Membership has Changed", + "orgMembershipChangedText": "\n Your organization membership has changed.\n

\n This can take a few moments to process. Please sign out, wait a minute, and then sign in again for the change to take effect.\n ", + "orgMustBeSelected": "An organization must be selected to view this page", + "verifyEmailTitle": "Please verify your email address", + "verifyEmailDescription": "\n In order to use Scriptoria, we need you to verify your email address.\n

\n Please log into your email and clik the verification link. ", + "invalidProjectSelection": "No valid products available for selected project(s)" + }, + "tasks": { + "title": "My Tasks", + "project": "Project", + "product": "Product", + "assignedTo": "Assigned To", + "status": "Status", + "waitTime": "Wait Time", + "unclaimed": "[unclaimed]", + "noTasksTitle": "No tasks are assigned to you.", + "noTasksDescription": "Tasks that require your attention will appear here.", + "reassign": "Reassign", + "waiting": "Waiting {waitTime}", + "forNames": "for {allowedNames} to {activityName}", + "scriptoria": "Scriptoria" + }, + "projects": { + "noBuilds": "No Builds Yet", + "latestBuild": "Latest Build ({version})", + "buildPending": "Build Pending", + "buildFailed": "Build Failed", + "switcher": { + "myProjects": "My Projects ({numProjects})", + "archived": "Archived ({numProjects})", + "dropdown": { + "orgProjects": "Organization Projects", + "myProjects": "My Projects", + "activeProjects": "Active Projects", + "archived": "Archived Projects", + "all": "All Projects" + } + }, + "bulk": { + "buildModal": { + "title": "Perform Bulk Rebuild/Republish" + } + } + }, + "productDefinitions": { + "filterAllProjects": "All projects that contain..." + }, + "projectImport": { + "importFile": "Import JSON File", + "createSuccess": "Project Import successfully created. You will receive an email when the import is completed." + }, + "project": { + "title": "Project", + "organizationContact": "Organization Contact: ", + "projectOwner": "Project Owner: ", + "claimOwnership": "Claim Ownership", + "claimSuccess": "Succesfully Claimed", + "editProject": "Edit Project", + "newProject": "New Project", + "importProjects": "Import Projects", + "importProjectsHelp": "Import Projects Help", + "projectName": "Project Name", + "noAvailableGroups": "There are no available groups for the selected organization", + "projectDescription": "Description", + "projectGroup": "Project Group", + "languageCode": "Language Code", + "type": "Type", + "public": "Public", + "private": "Private", + "visibilityLabel": "Public", + "visibilityDescription": "If you make your project Private, it will not be visible in the directory or accessible by other organizations", + "createdOn": "Created", + "overview": "Overview", + "productFiles": "Product files", + "dropdown": { + "transfer": "Transfer Ownership", + "archive": "Archive", + "reactivate": "Reactivate", + "build": "Build" + }, + "details": { + "title": "Details", + "language": "Language", + "type": "Project Type" + }, + "products": { + "title": "Products", + "empty": "You have no products for this project.", + "addRemove": "Add or Remove Products", + "add": "Add Products", + "remove": "Remove Products", + "popup": { + "addTitle": "Select Product to Add", + "removeTitle": "Select Product to Remove", + "done": "Done", + "empty": "No products available", + "details": "Details", + "properties": "Publishing Properties" + }, + "publications": { + "channel": "Channel", + "status": "Status", + "date": "Publish Date", + "url": "Publish Url", + "succeeded": "Success", + "failed": "Failure", + "console": "Console Text" + }, + "options": { + "update": "update", + "publish": "publish" + }, + "transitions": { + "productDetails": "Product Details", + "storeName": "Store Name", + "state": "State", + "user": "User", + "command": "Command", + "comment": "Comment", + "date": "Date", + "transitionTypes": { + "1": "Activity", + "2": "{workflowType} Workflow Started", + "3": "{workflowType} Workflow Completed", + "4": "{workflowType} Workflow Cancelled", + "5": "{workflowType} Project Access" + } + }, + "properties": { + "computeType": "Compute Type", + "selectComputeType": "Select compute type", + "small": "Small", + "medium": "Medium", + "title": "Product Publishing Properties" + }, + "updated": "Updated", + "size": "Size", + "filename": "Filename", + "published": "Published", + "unpublished": "Unpublished", + "numArtifacts": "{amount, plural, =0 {No Product Files} other {{ amount } Product Files}}", + "noArtifacts": "No Product Files", + "rebuild": "rebuild", + "creationInProgress": "Pending: You cannot add a product until the project setup has been completed." + }, + "settings": { + "title": "Settings", + "automaticRebuild": { + "title": "Automatic Rebuilds", + "description": "When automatic rebuilds are on, Scriptoria will automatically rebuild your products when the input source is updated" + }, + "organizationDownloads": { + "title": "Allow Other Organizations to download", + "description": "When this setting is on, any Scriptoria User that is able to view your project in the Directory will be able to download the Product Files (the outputs of the products)." + }, + "visibility": { + "title": "Public Visibility", + "description": "Public Projects allow any Scriptoria User to view your project in the Directory" + } + }, + "side": { + "repositoryLocation": "Repository Location", + "organization": "Organization", + "projectOwner": "Project Owner", + "projectGroup": "Project Group", + "authors": { + "title": "Authors", + "add": "add author", + "close": "close", + "form": { + "user": "user", + "userError": "User cannot be empty", + "submit": "Add Author" + } + }, + "reviewers": { + "title": "Reviewers", + "add": "add reviewer", + "close": "close", + "form": { + "name": "name", + "nameError": "Name cannot be empty", + "email": "email", + "emptyEmailError": "Email cannot be empty", + "invalidEmailError": "Invalid email address", + "submit": "Add Reviewer" + } + } + }, + "operations": { + "archive": { + "success": "Project archived", + "error": "There was an error trying to archive the project" + }, + "reactivate": { + "success": "Project reactivated", + "error": "There was an error trying to reactivate the project" + }, + "automaticBuilds": { + "on": "Automatic builds is ON", + "off": "Automatic builds is OFF", + "error": "Error: We could not change automatic build status" + }, + "allowDownloads": { + "on": "Allow project download is ON", + "off": "Allow project download is OFF", + "error": "Error: We could not change Allow Download status" + }, + "isPublic": { + "on": "Project visibility is set to Public", + "off": "Project visibility is set to Private", + "error": "Error: We could not change Project visibility" + } + } + }, + "projectTable": { + "columns": { + "project": "Project", + "owner": "Owner", + "organization": "Organization", + "language": "Language", + "group": "Group", + "buildVersion": "Build Version", + "buildDate": "Build Date", + "createdOn": "Created On", + "updatedOn": "Updated On", + "activeSince": "Active Since" + }, + "empty": "No projects found", + "products": "Products", + "noProducts": "This project has no configured products" + }, + "users": { + "settingsTitle": "User Settings", + "userProfile": "User Profile", + "userGroups": "Group Memberships", + "userRoles": "Organization Roles", + "noneFound": "No users matching the selected criteria were found.", + "noRoles": "No roles assigned", + "title": "Manage Users", + "addUser": { + "placeholder": "Enter an email", + "button": "Add User to {organization}", + "modalTitle": "Add User to {organization}", + "modalAddButton": "Add", + "error": "No user was found with that email address. Please ask them to create an account." + }, + "table": { + "columns": { + "name": "Name", + "role": "Role", + "groups": "Groups", + "active": "Active" + } + }, + "operations": { + "lock": { + "success": "User is locked. A locked user will not be able to log in to Scriptoria.", + "error": "There was an error locking the user" + }, + "unlock": { + "success": "User is active. The user will now be able to log in to Scriptoria.", + "error": "there was an error activating the user" + } + } + }, + "stores": { + "name": "Store", + "listTitle": "Stores", + "attributes": { + "name": "Name", + "description": "Description" + } + }, + "storeTypes": { + "name": "Store Type", + "listTitle": "Store Types" + }, + "admin": { + "settings": { + "title": "Admin settings", + "navigation": { + "organizations": "Organizations", + "workflowdefinitions": "Workflow Definitions", + "productDefinitions": "Product Definitions", + "storeTypes": "Store Types", + "stores": "Stores", + "buildEngines": "Build Engine Statuses" + }, + "organizations": { + "title": "Organizations", + "name": "Organization Name", + "owner": "Owner", + "emptyOwner": "Need to select an owner for this organization", + "add": "Add Organization", + "addSuccess": "Organization added", + "edit": "Edit Organization", + "editSuccess": "Organization updated", + "websiteURL": "Website URL", + "buildEngineURL": "Build Engine URL", + "accessToken": "Build Engine API Access Token", + "logoURL": "Logo URL", + "publicByDefault": "Public By Default", + "publicByDefaultDescription": "Projects created under this organization are set to public by default" + }, + "workflowDefinitions": { + "title": "Workflow Definitions", + "name": "Workflow Definition Name", + "description": "Description", + "workflowScheme": "Workflow Scheme", + "workflowBusinessFlow": "Workflow Business Flow", + "properties": "Properties", + "add": "Add Workflow Definition", + "edit": "Edit Workflow Definition", + "storeType": "Store Type", + "enabled": "Enabled", + "enabledDescription": "Workflow definitions may not be used until enabled.", + "workflowAdded": "Workflow Definition added", + "workflowUpdated": "Workflow Definition updated", + "emptyStoreType": "Need to select a store type for this workflow definition", + "emptyWorkflowType": "Need to select a workflow type for this workflow definition", + "workflowType": "Workflow Type", + "workflowTypes": { + "1": "Startup", + "2": "Rebuild", + "3": "Republish" + } + }, + "productDefinitions": { + "title": "Product Definitions", + "name": "Product definition Name", + "add": "Add Product Definition", + "edit": "Edit Product Definition", + "description": "Description", + "properties": "Properties", + "type": "Application Type", + "workflow": "Workflow", + "republishWorkflow": "Republish Workflow", + "rebuildWorkflow": "Rebuild Workflow", + "addSuccess": "Product Definition added", + "editSuccess": "Product Definition updated", + "emptyName": "Name cannot be empty", + "emptyType": "Need to select an Application Type", + "emptyWorkflow": "Need to select a Workflow definition", + "noWorkflow": "No Workflow Required" + }, + "storeTypes": { + "title": "Store Types", + "name": "Store Type Name", + "add": "Add Store Type", + "edit": "Edit Store Type", + "description": "Description", + "type": "Application Type", + "workflow": "Workflow", + "addSuccess": "Store Type added", + "editSuccess": "Store Type updated", + "emptyName": "Name cannot be empty", + "emptyType": "Need to select an Application Type", + "emptyWorkflow": "Need to select a Workflow definition" + }, + "buildEngines": { + "title": "Build Engine Statuses", + "accessToken": "Build Engine API Access Token", + "websiteURL": "Website URL", + "connected": "Connected", + "disconnected": "Disconnected", + "status": "Status", + "lastUpdated": "Last update" + } + } + }, + "organization-membership": { + "invite": { + "error": { + "expired": "Invitation has expired", + "redeemed": "Invitation has already been redeemed", + "not-found": "Invitation was not found", + "unexpected": "Unexpected error occured: {response}", + "invalid-response": "We've received an invalid response... please refresh the page to try again." + }, + "create": { + "success": "Invite sent to {email}.", + "error": "Error occured while trying to invite user.", + "invite-user-button-title": "Invite User", + "invite-user-modal-title": "Invite User", + "email-input-placeholder": "Enter email address", + "send-invite-button": "Send Invite" + }, + "redemptionTitle": "Looking up invitation..." + } + }, + "system": { + "build-failed": "Build failed", + "publish-failed": "Publish failed" + }, + "downloads": { + "title": "Downloads" + } +} diff --git a/source/SIL.AppBuilder.Portal/src/routes/+layout.svelte b/source/SIL.AppBuilder.Portal/src/routes/+layout.svelte index 2e511e004..e7ec3eada 100644 --- a/source/SIL.AppBuilder.Portal/src/routes/+layout.svelte +++ b/source/SIL.AppBuilder.Portal/src/routes/+layout.svelte @@ -1,5 +1,26 @@ + + + diff --git a/source/SIL.AppBuilder.Portal/src/routes/+layout.ts b/source/SIL.AppBuilder.Portal/src/routes/+layout.ts new file mode 100644 index 000000000..ba60ce4ea --- /dev/null +++ b/source/SIL.AppBuilder.Portal/src/routes/+layout.ts @@ -0,0 +1,12 @@ +// +layout.ts +import { browser } from '$app/environment'; +import '$lib/i18n'; // Import to initialize. Important :) +import { locale, waitLocale } from 'svelte-i18n'; +import type { LayoutLoad } from './$types'; + +export const load: LayoutLoad = async () => { + if (browser) { + locale.set(window.navigator.language); + } + await waitLocale(); +}; diff --git a/source/SIL.AppBuilder.Portal/src/routes/+page.svelte b/source/SIL.AppBuilder.Portal/src/routes/+page.svelte index 5982b0ae3..24fcb529b 100644 --- a/source/SIL.AppBuilder.Portal/src/routes/+page.svelte +++ b/source/SIL.AppBuilder.Portal/src/routes/+page.svelte @@ -1,2 +1,7 @@ -

Welcome to SvelteKit

-

Visit kit.svelte.dev to read the documentation

+ + +
+

{$_('welcome')}

+