Merge branch 'master' into 1588-frontend-expendable-paginated-link-list

This commit is contained in:
Alexander Friedland 2022-03-16 20:57:03 +01:00 committed by GitHub
commit 3ada62d20f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
89 changed files with 1225 additions and 869 deletions

View File

@ -1,3 +1,4 @@
node_modules
.git
.gitignore
.gitignore
!.eslintignore

View File

@ -1,4 +1,3 @@
node_modules
coverage
**/*.min.js
dist
node_modules/
dist/
coverage/

View File

@ -8,9 +8,20 @@ module.exports = {
parserOptions: {
parser: 'babel-eslint',
},
extends: ['standard', 'plugin:vue/essential', 'plugin:prettier/recommended'],
extends: [
'standard',
'plugin:vue/essential',
'plugin:prettier/recommended',
'plugin:@intlify/vue-i18n/recommended',
],
// required to lint *.vue files
plugins: ['vue', 'prettier', 'jest'],
overrides: [
{
files: ['*.json'],
extends: ['plugin:@intlify/vue-i18n/recommended'],
},
],
// add your custom rules here
rules: {
'no-console': ['error'],
@ -22,6 +33,17 @@ module.exports = {
allowBinding: false,
},
],
'@intlify/vue-i18n/no-dynamic-keys': 'error',
'@intlify/vue-i18n/no-unused-keys': [
'error',
{
src: './src',
extensions: ['.js', '.vue'],
ignores: [],
enableFix: false,
},
],
'@intlify/vue-i18n/no-missing-keys-in-other-locales': 'error',
'prettier/prettier': [
'error',
{
@ -29,4 +51,12 @@ module.exports = {
},
],
},
settings: {
'vue-i18n': {
localeDir: './src/locales/*.json',
// Specify the version of `vue-i18n` you are using.
// If not specified, the message will be parsed twice.
messageSyntaxVersion: '^8.26.5',
},
},
}

View File

@ -12,11 +12,10 @@
"build": "vue-cli-service build",
"dev": "yarn run serve",
"analyse-bundle": "yarn build && webpack-bundle-analyzer dist/webpack.stats.json",
"lint": "eslint --max-warnings=0 --ext .js,.vue .",
"lint": "eslint --max-warnings=0 --ext .js,.vue,.json .",
"stylelint": "stylelint --max-warnings=0 '**/*.{scss,vue}'",
"i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'",
"test": "TZ=UTC jest --coverage",
"locales": "scripts/missing-keys.sh && scripts/sort.sh"
"locales": "scripts/sort.sh"
},
"dependencies": {
"@babel/core": "^7.15.8",
@ -52,6 +51,7 @@
},
"devDependencies": {
"@babel/eslint-parser": "^7.15.8",
"@intlify/eslint-plugin-vue-i18n": "^1.4.0",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",

View File

@ -4,24 +4,24 @@
<b-row align-v="center" class="mt-4 justify-content-lg-between">
<b-col>
<div class="copyright text-center text-lg-center text-muted">
© {{ year }}
{{ $t('footer.copyright.year', { year }) }}
<a
:href="`https://gradido.net/${$i18n.locale}`"
class="font-weight-bold ml-1"
target="_blank"
>
{{ $t('gradido_admin_footer') }}
{{ $t('footer.copyright.link') }}
</a>
|
{{ $t('math.pipe') }}
<a href="https://github.com/gradido/gradido/releases/latest" target="_blank">
App version {{ version }}
{{ $t('footer.app_version', { version }) }}
</a>
<a
v-if="hash"
:href="'https://github.com/gradido/gradido/commit/' + hash"
target="_blank"
>
({{ shortHash }})
{{ $t('footer.short_hash', { shortHash }) }}
</a>
</div>
</b-col>

View File

@ -7,7 +7,7 @@
<b-row class="mt-4">
<b-col class="col-3">{{ $t('transactionlist.amount') }}</b-col>
<b-col class="h3">
<b>{{ item.amount }} GDD</b>
<b>{{ item.amount }} {{ $t('GDD') }}</b>
</b-col>
</b-row>
<b-row>

View File

@ -12,7 +12,7 @@
>
<b-icon icon="plus" variant="success"></b-icon>
</b-button>
<div v-else>{{ $t('e_mail') }}!</div>
<div v-else>{{ $t('e_mail') }}{{ $t('math.exclaim') }}</div>
</div>
</template>
</b-table-lite>

View File

@ -1,8 +1,6 @@
{
"all_emails": "Alle Nutzer",
"back": "zurück",
"bookmark": "bookmark",
"confirmed": "bestätigt",
"creation": "Schöpfung",
"creation_form": {
"creation_failed": "Ausstehende Schöpfung für {email} konnte nicht erzeugt werden.",
@ -16,7 +14,6 @@
"submit_creation": "Schöpfung einreichen",
"toasted": "Offene Schöpfung ({value} GDD) für {email} wurde gespeichert und liegt zur Bestätigung bereit",
"toasted_created": "Schöpfung wurde erfolgreich gespeichert",
"toasted_default": "`Fall {event} wird nicht unterstützt`",
"toasted_delete": "Offene Schöpfung wurde gelöscht",
"toasted_update": "`Offene Schöpfung {value} GDD) für {email} wurde geändert und liegt zur Bestätigung bereit",
"update_creation": "Schöpfung aktualisieren"
@ -27,14 +24,26 @@
"deleted": "gelöscht",
"deleted_user": "Alle gelöschten Nutzer",
"delete_user": "Nutzer löschen",
"details": "Details",
"edit": "Bearbeiten",
"enabled": "aktiviert",
"error": "Fehler",
"e_mail": "E-Mail",
"firstname": "Vorname",
"gradido_admin_footer": "Gradido Akademie Adminkonsole",
"footer": {
"app_version": "App version {version}",
"copyright": {
"link": "Gradido Akademie Adminkonsole",
"year": "© {year}"
},
"short_hash": "({shortHash})"
},
"GDD": "GDD",
"hide_details": "Details verbergen",
"lastname": "Nachname",
"math": {
"exclaim": "!",
"pipe": "|"
},
"moderator": "Moderator",
"multiple_creation_text": "Bitte wähle ein oder mehrere Mitglieder aus für die du Schöpfen möchtest.",
"name": "Name",
@ -47,7 +56,6 @@
"user_search": "Nutzersuche"
},
"not_open_creations": "Keine offenen Schöpfungen",
"open_creation": "Offene Schöpfung",
"open_creations": "Offene Schöpfungen",
"overlay": {
"confirm": {
@ -56,13 +64,6 @@
"text": "Nach dem Speichern ist der Datensatz nicht mehr änderbar und kann auch nicht mehr gelöscht werden. Bitte überprüfe genau, dass alles stimmt.",
"title": "Schöpfung bestätigen!",
"yes": "Ja, Schöpfung bestätigen und speichern!"
},
"remove": {
"no": "Nein, nicht löschen.",
"question": "Willst du die vorgespeicherte Schöpfung wirklich löschen?",
"text": "Nach dem Löschen gibt es keine Möglichkeit mehr diesen Datensatz wiederherzustellen. Es wird aber der gesamte Vorgang in der Logdatei als Übersicht gespeichert.",
"title": "Achtung! Schöpfung löschen!",
"yes": "Ja, Schöpfung löschen!"
}
},
"remove": "Entfernen",
@ -72,13 +73,11 @@
"status": "Status",
"success": "Erfolg",
"text": "Text",
"transaction": "Transaktion",
"transactionlist": {
"amount": "Betrag",
"balanceDate": "Schöpfungsdatum",
"community": "Gemeinschaft",
"date": "Datum",
"decay": "Vergänglichkeit",
"memo": "Nachricht",
"title": "Alle geschöpften Transaktionen für den Nutzer"
},

View File

@ -1,8 +1,6 @@
{
"all_emails": "All users",
"back": "back",
"bookmark": "Remember",
"confirmed": "confirmed",
"creation": "Creation",
"creation_form": {
"creation_failed": "Could not create pending creation for {email}",
@ -16,7 +14,6 @@
"submit_creation": "Submit creation",
"toasted": "Open creation ({value} GDD) for {email} has been saved and is ready for confirmation.",
"toasted_created": "Creation has been successfully saved",
"toasted_default": "`Case {event} is not supported`",
"toasted_delete": "Open creation has been deleted",
"toasted_update": "Open creation {value} GDD) for {email} has been changed and is ready for confirmation.",
"update_creation": "Creation update"
@ -27,14 +24,26 @@
"deleted": "deleted",
"deleted_user": "All deleted user",
"delete_user": "Delete user",
"details": "Details",
"edit": "Edit",
"enabled": "enabled",
"error": "Error",
"e_mail": "E-mail",
"firstname": "Firstname",
"gradido_admin_footer": "Gradido Academy Admin Console",
"footer": {
"app_version": "App version {version}",
"copyright": {
"link": "Gradido Academy Admin Console",
"year": "© {year}"
},
"short_hash": "({shortHash})"
},
"GDD": "GDD",
"hide_details": "Hide details",
"lastname": "Lastname",
"math": {
"exclaim": "!",
"pipe": "|"
},
"moderator": "Moderator",
"multiple_creation_text": "Please select one or more members for which you would like to perform creations.",
"name": "Name",
@ -47,7 +56,6 @@
"user_search": "User search"
},
"not_open_creations": "No open creations",
"open_creation": "Open creation",
"open_creations": "Open creations",
"overlay": {
"confirm": {
@ -56,13 +64,6 @@
"text": "After saving, the record can no longer be changed or deleted. Please check carefully that everything is correct.",
"title": "Confirm creation!",
"yes": "Yes, confirm and save creation!"
},
"remove": {
"no": "No, do not delete.",
"question": "Do you really want to delete the pre-stored creation?",
"text": "After deletion, there is no possibility to restore this data record. However, the entire process is saved in the log file as an overview.",
"title": "Attention! Delete creation!",
"yes": "Yes, delete creation!"
}
},
"remove": "Remove",
@ -72,13 +73,11 @@
"status": "Status",
"success": "Success",
"text": "Text",
"transaction": "Transaction",
"transactionlist": {
"amount": "Amount",
"balanceDate": "Creation date",
"community": "Community",
"date": "Date",
"decay": "Decay",
"memo": "Message",
"title": "All creation-transactions for the user"
},

View File

@ -2,7 +2,7 @@
<div class="creation">
<b-row>
<b-col cols="12" lg="6">
<label>Usersuche</label>
<label>{{ $t('user_search') }}</label>
<b-input-group>
<b-form-input
type="text"

View File

@ -2,7 +2,6 @@ import { ApolloClient, ApolloLink, InMemoryCache, HttpLink } from 'apollo-boost'
import VueApollo from 'vue-apollo'
import CONFIG from '../config'
import store from '../store/store'
import i18n from '../i18n'
const httpLink = new HttpLink({ uri: CONFIG.GRAPHQL_URI })
@ -15,7 +14,6 @@ const authLink = new ApolloLink((operation, forward) => {
})
return forward(operation).map((response) => {
if (response.errors && response.errors[0].message === '403.13 - Client certificate revoked') {
response.errors[0].message = i18n.t('error.session-expired')
store.dispatch('logout', null)
window.location.assign(CONFIG.WALLET_URL)
return response

View File

@ -14,6 +14,7 @@ module.exports = {
fallbackLocale: 'de',
localeDir: 'locales',
enableInSFC: false,
enableLegacy: false,
},
},
lintOnSave: true,

View File

@ -932,6 +932,13 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.14.0":
version "7.17.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.7.tgz#a5f3328dc41ff39d803f311cfe17703418cf9825"
integrity sha512-L6rvG9GDxaLgFjg41K+5Yv9OMrU98sWe+Ykmc6FDJW/+vYZMhdOMKkISgzptMaERHvS2Y2lw9MDRm2gHhlQQoA==
dependencies:
regenerator-runtime "^0.13.4"
"@babel/template@7", "@babel/template@^7.0.0", "@babel/template@^7.15.4", "@babel/template@^7.3.3", "@babel/template@^7.4.0":
version "7.15.4"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194"
@ -1001,6 +1008,21 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"
"@eslint/eslintrc@^1.2.0":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6"
integrity sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
espree "^9.3.1"
globals "^13.9.0"
ignore "^5.2.0"
import-fresh "^3.2.1"
js-yaml "^4.1.0"
minimatch "^3.0.4"
strip-json-comments "^3.1.1"
"@hapi/address@2.x.x":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
@ -1042,6 +1064,83 @@
cssnano-preset-default "^4.0.0"
postcss "^7.0.0"
"@intlify/core-base@^9.1.9":
version "9.1.9"
resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.1.9.tgz#e4e8c951010728e4af3a0d13d74cf3f9e7add7f6"
integrity sha512-x5T0p/Ja0S8hs5xs+ImKyYckVkL4CzcEXykVYYV6rcbXxJTe2o58IquSqX9bdncVKbRZP7GlBU1EcRaQEEJ+vw==
dependencies:
"@intlify/devtools-if" "9.1.9"
"@intlify/message-compiler" "9.1.9"
"@intlify/message-resolver" "9.1.9"
"@intlify/runtime" "9.1.9"
"@intlify/shared" "9.1.9"
"@intlify/vue-devtools" "9.1.9"
"@intlify/devtools-if@9.1.9":
version "9.1.9"
resolved "https://registry.yarnpkg.com/@intlify/devtools-if/-/devtools-if-9.1.9.tgz#a30e1dd1256ff2c5c98d8d75d075384fba898e5d"
integrity sha512-oKSMKjttG3Ut/1UGEZjSdghuP3fwA15zpDPcjkf/1FjlOIm6uIBGMNS5jXzsZy593u+P/YcnrZD6cD3IVFz9vQ==
dependencies:
"@intlify/shared" "9.1.9"
"@intlify/eslint-plugin-vue-i18n@^1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@intlify/eslint-plugin-vue-i18n/-/eslint-plugin-vue-i18n-1.4.0.tgz#f8fe791892c2dce7d189a364b6a908c87e1c3ac9"
integrity sha512-anB1eBf6rpxpWyW883gi6O1hozQy4Q02VyzyodOUnohOqT07GATVSxnr2J9/qQSV47xWukV+9LiRErJcU7d/uA==
dependencies:
"@eslint/eslintrc" "^1.2.0"
"@intlify/core-base" "^9.1.9"
"@intlify/message-compiler" "^9.1.9"
debug "^4.3.1"
glob "^7.1.3"
ignore "^5.0.5"
is-language-code "^3.1.0"
js-yaml "^4.0.0"
json5 "^2.1.3"
jsonc-eslint-parser "^2.0.0"
lodash "^4.17.11"
parse5 "^6.0.0"
semver "^7.3.4"
vue-eslint-parser "^8.0.0"
yaml-eslint-parser "^0.5.0"
"@intlify/message-compiler@9.1.9", "@intlify/message-compiler@^9.1.9":
version "9.1.9"
resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.1.9.tgz#1193cbd224a71c2fb981455b8534a3c766d2948d"
integrity sha512-6YgCMF46Xd0IH2hMRLCssZI3gFG4aywidoWQ3QP4RGYQXQYYfFC54DxhSgfIPpVoPLQ+4AD29eoYmhiHZ+qLFQ==
dependencies:
"@intlify/message-resolver" "9.1.9"
"@intlify/shared" "9.1.9"
source-map "0.6.1"
"@intlify/message-resolver@9.1.9":
version "9.1.9"
resolved "https://registry.yarnpkg.com/@intlify/message-resolver/-/message-resolver-9.1.9.tgz#3155ccd2f5e6d0dc16cad8b7f1d8e97fcda05bfc"
integrity sha512-Lx/DBpigeK0sz2BBbzv5mu9/dAlt98HxwbG7xLawC3O2xMF9MNWU5FtOziwYG6TDIjNq0O/3ZbOJAxwITIWXEA==
"@intlify/runtime@9.1.9":
version "9.1.9"
resolved "https://registry.yarnpkg.com/@intlify/runtime/-/runtime-9.1.9.tgz#2c12ce29518a075629efed0a8ed293ee740cb285"
integrity sha512-XgPw8+UlHCiie3fI41HPVa/VDJb3/aSH7bLhY1hJvlvNV713PFtb4p4Jo+rlE0gAoMsMCGcsiT982fImolSltg==
dependencies:
"@intlify/message-compiler" "9.1.9"
"@intlify/message-resolver" "9.1.9"
"@intlify/shared" "9.1.9"
"@intlify/shared@9.1.9":
version "9.1.9"
resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.1.9.tgz#0baaf96128b85560666bec784ffb01f6623cc17a"
integrity sha512-xKGM1d0EAxdDFCWedcYXOm6V5Pfw/TMudd6/qCdEb4tv0hk9EKeg7lwQF1azE0dP2phvx0yXxrt7UQK+IZjNdw==
"@intlify/vue-devtools@9.1.9":
version "9.1.9"
resolved "https://registry.yarnpkg.com/@intlify/vue-devtools/-/vue-devtools-9.1.9.tgz#2be8f4dbe7f7ed4115676eb32348141d411e426b"
integrity sha512-YPehH9uL4vZcGXky4Ev5qQIITnHKIvsD2GKGXgqf+05osMUI6WSEQHaN9USRa318Rs8RyyPCiDfmA0hRu3k7og==
dependencies:
"@intlify/message-resolver" "9.1.9"
"@intlify/runtime" "9.1.9"
"@intlify/shared" "9.1.9"
"@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
@ -2399,6 +2498,11 @@ acorn@^8.2.4:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2"
integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==
acorn@^8.5.0, acorn@^8.7.0:
version "8.7.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf"
integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==
address@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
@ -2645,6 +2749,11 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
arr-diff@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
@ -4892,7 +5001,7 @@ debug@^3.1.1, debug@^3.2.6, debug@^3.2.7:
dependencies:
ms "^2.1.1"
debug@^4.3.0, debug@^4.3.3:
debug@^4.3.0, debug@^4.3.1, debug@^4.3.3:
version "4.3.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
@ -5615,6 +5724,14 @@ eslint-scope@^5.1.1:
esrecurse "^4.3.0"
estraverse "^4.1.1"
eslint-scope@^7.0.0:
version "7.1.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642"
integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==
dependencies:
esrecurse "^4.3.0"
estraverse "^5.2.0"
eslint-utils@^2.0.0, eslint-utils@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27"
@ -5644,6 +5761,11 @@ eslint-visitor-keys@^3.0.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.0.0.tgz#e32e99c6cdc2eb063f204eda5db67bfe58bb4186"
integrity sha512-mJOZa35trBTb3IyRmo8xmKBZlxf+N7OnUl4+ZhJHs/r+0770Wh/LEACE2pqMGMe27G/4y8P2bYGk4J70IC5k1Q==
eslint-visitor-keys@^3.1.0, eslint-visitor-keys@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
eslint@7.25.0:
version "7.25.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.25.0.tgz#1309e4404d94e676e3e831b3a3ad2b050031eb67"
@ -5710,6 +5832,15 @@ espree@^7.3.0, espree@^7.3.1:
acorn-jsx "^5.3.1"
eslint-visitor-keys "^1.3.0"
espree@^9.0.0, espree@^9.3.1:
version "9.3.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd"
integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==
dependencies:
acorn "^8.7.0"
acorn-jsx "^5.3.1"
eslint-visitor-keys "^3.3.0"
esprima@^4.0.0, esprima@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
@ -7003,16 +7134,16 @@ ignore@^4.0.3, ignore@^4.0.6:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
ignore@^5.0.5, ignore@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
ignore@^5.1.1, ignore@^5.1.4:
version "5.1.8"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
ignore@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
import-cwd@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
@ -7386,6 +7517,13 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
dependencies:
is-extglob "^2.1.1"
is-language-code@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/is-language-code/-/is-language-code-3.1.0.tgz#b2386b49227e7010636f16d0c2c681ca40136ab5"
integrity sha512-zJdQ3QTeLye+iphMeK3wks+vXSRFKh68/Pnlw7aOfApFSEIOhYa8P9vwwa6QrImNNBMJTiL1PpYF0f4BxDuEgA==
dependencies:
"@babel/runtime" "^7.14.0"
is-negative-zero@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
@ -8571,6 +8709,13 @@ js-yaml@^3.13.1:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^4.0.0, js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
argparse "^2.0.1"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
@ -8723,7 +8868,7 @@ json3@^3.3.3:
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==
json5@2.x, json5@^2.1.2:
json5@2.x, json5@^2.1.2, json5@^2.1.3:
version "2.2.0"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
@ -8742,6 +8887,16 @@ json5@^1.0.1:
dependencies:
minimist "^1.2.0"
jsonc-eslint-parser@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/jsonc-eslint-parser/-/jsonc-eslint-parser-2.1.0.tgz#4c126b530aa583d85308d0b3041ff81ce402bbb2"
integrity sha512-qCRJWlbP2v6HbmKW7R3lFbeiVWHo+oMJ0j+MizwvauqnCV/EvtAeEeuCgoc/ErtsuoKgYB8U4Ih8AxJbXoE6/g==
dependencies:
acorn "^8.5.0"
eslint-visitor-keys "^3.0.0"
espree "^9.0.0"
semver "^7.3.5"
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
@ -10014,7 +10169,7 @@ parse5@5.1.0:
resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2"
integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==
parse5@6.0.1, parse5@^6.0.1:
parse5@6.0.1, parse5@^6.0.0, parse5@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
@ -11700,16 +11855,16 @@ source-map-url@^0.4.0:
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==
source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@^0.5.0, source-map@^0.5.6:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@^0.7.3:
version "0.7.3"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
@ -12970,6 +13125,19 @@ vue-eslint-parser@^7.10.0:
lodash "^4.17.21"
semver "^6.3.0"
vue-eslint-parser@^8.0.0:
version "8.3.0"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz#5d31129a1b3dd89c0069ca0a1c88f970c360bd0d"
integrity sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==
dependencies:
debug "^4.3.2"
eslint-scope "^7.0.0"
eslint-visitor-keys "^3.1.0"
espree "^9.0.0"
esquery "^1.4.0"
lodash "^4.17.21"
semver "^7.3.5"
vue-functional-data-merge@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/vue-functional-data-merge/-/vue-functional-data-merge-3.1.0.tgz#08a7797583b7f35680587f8a1d51d729aa1dc657"
@ -13515,7 +13683,16 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yaml@^1.10.0:
yaml-eslint-parser@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/yaml-eslint-parser/-/yaml-eslint-parser-0.5.0.tgz#01d4e4d992a820769ea85ef5fd526dfc20ebc6f5"
integrity sha512-nJeyLA3YHAzhBTZbRAbu3W6xrSCucyxExmA+ZDtEdUFpGllxAZpto2Zxo2IG0r0eiuEiBM4e+wiAdxTziTq94g==
dependencies:
eslint-visitor-keys "^3.0.0"
lodash "^4.17.21"
yaml "^1.10.2"
yaml@^1.10.0, yaml@^1.10.2:
version "1.10.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==

View File

@ -3,7 +3,7 @@ module.exports = {
verbose: true,
preset: 'ts-jest',
collectCoverage: true,
collectCoverageFrom: ['src/**/*.ts', '!**/node_modules/**'],
collectCoverageFrom: ['src/**/*.ts', '!**/node_modules/**', '!src/seeds/**'],
setupFiles: ['<rootDir>/test/testSetup.ts'],
moduleNameMapper: {
'@/(.*)': '<rootDir>/src/$1',

View File

@ -13,7 +13,8 @@
"start": "node build/src/index.js",
"dev": "nodemon -w src --ext ts --exec ts-node src/index.ts",
"lint": "eslint --max-warnings=0 --ext .js,.ts .",
"test": "TZ=UTC NODE_ENV=development jest --runInBand --coverage --forceExit --detectOpenHandles"
"test": "TZ=UTC NODE_ENV=development jest --runInBand --coverage --forceExit --detectOpenHandles",
"seed": "TZ=UTC ts-node src/seeds/index.ts"
},
"dependencies": {
"@types/jest": "^27.0.2",
@ -42,6 +43,7 @@
},
"devDependencies": {
"@types/express": "^4.17.12",
"@types/faker": "^5.5.9",
"@types/jsonwebtoken": "^8.5.2",
"@types/node": "^16.10.3",
"@types/nodemailer": "^6.4.4",
@ -54,6 +56,7 @@
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-promise": "^5.1.0",
"faker": "^5.5.3",
"nodemon": "^2.0.7",
"prettier": "^2.3.1",
"ts-node": "^10.0.0",

View File

@ -1,9 +1,11 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { testEnvironment, createUser, headerPushMock, cleanDB, resetToken } from '@test/helpers'
import { createUserMutation, setPasswordMutation } from '@test/graphql'
import gql from 'graphql-tag'
import { testEnvironment, headerPushMock, resetToken, cleanDB } from '@test/helpers'
import { createUserFactory } from '@/seeds/factory/user'
import { bibiBloxberg } from '@/seeds/users/bibi-bloxberg'
import { createUser, setPassword } from '@/seeds/graphql/mutations'
import { login, logout } from '@/seeds/graphql/queries'
import { GraphQLError } from 'graphql'
import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
import { User } from '@entity/User'
@ -11,8 +13,6 @@ import CONFIG from '@/config'
import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail'
// import { klicktippSignIn } from '@/apis/KlicktippController'
jest.setTimeout(1000000)
jest.mock('@/mailer/sendAccountActivationEmail', () => {
return {
__esModule: true,
@ -31,24 +31,6 @@ jest.mock('@/apis/KlicktippController', () => {
let mutate: any, query: any, con: any
const loginQuery = gql`
query ($email: String!, $password: String!, $publisherId: Int) {
login(email: $email, password: $password, publisherId: $publisherId) {
email
firstName
lastName
language
coinanimation
klickTipp {
newsletterState
}
hasElopage
publisherId
isAdmin
}
}
`
beforeAll(async () => {
const testEnv = await testEnvironment()
mutate = testEnv.mutate
@ -77,7 +59,7 @@ describe('UserResolver', () => {
beforeAll(async () => {
jest.clearAllMocks()
result = await mutate({ mutation: createUserMutation, variables })
result = await mutate({ mutation: createUser, variables })
})
afterAll(async () => {
@ -149,7 +131,7 @@ describe('UserResolver', () => {
describe('email already exists', () => {
it('throws an error', async () => {
await expect(mutate({ mutation: createUserMutation, variables })).resolves.toEqual(
await expect(mutate({ mutation: createUser, variables })).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('User already exists.')],
}),
@ -160,7 +142,7 @@ describe('UserResolver', () => {
describe('unknown language', () => {
it('sets "de" as default language', async () => {
await mutate({
mutation: createUserMutation,
mutation: createUser,
variables: { ...variables, email: 'bibi@bloxberg.de', language: 'es' },
})
await expect(User.find()).resolves.toEqual(
@ -177,7 +159,7 @@ describe('UserResolver', () => {
describe('no publisher id', () => {
it('sets publisher id to null', async () => {
await mutate({
mutation: createUserMutation,
mutation: createUser,
variables: { ...variables, email: 'raeuber@hotzenplotz.de', publisherId: undefined },
})
await expect(User.find()).resolves.toEqual(
@ -208,11 +190,11 @@ describe('UserResolver', () => {
let newUser: any
beforeAll(async () => {
await mutate({ mutation: createUserMutation, variables: createUserVariables })
await mutate({ mutation: createUser, variables: createUserVariables })
const loginEmailOptIn = await LoginEmailOptIn.find()
emailOptIn = loginEmailOptIn[0].verificationCode.toString()
result = await mutate({
mutation: setPasswordMutation,
mutation: setPassword,
variables: { code: emailOptIn, password: 'Aa12345_' },
})
newUser = await User.find()
@ -252,11 +234,11 @@ describe('UserResolver', () => {
describe('no valid password', () => {
beforeAll(async () => {
await mutate({ mutation: createUserMutation, variables: createUserVariables })
await mutate({ mutation: createUser, variables: createUserVariables })
const loginEmailOptIn = await LoginEmailOptIn.find()
emailOptIn = loginEmailOptIn[0].verificationCode.toString()
result = await mutate({
mutation: setPasswordMutation,
mutation: setPassword,
variables: { code: emailOptIn, password: 'not-valid' },
})
})
@ -280,9 +262,9 @@ describe('UserResolver', () => {
describe('no valid optin code', () => {
beforeAll(async () => {
await mutate({ mutation: createUserMutation, variables: createUserVariables })
await mutate({ mutation: createUser, variables: createUserVariables })
result = await mutate({
mutation: setPasswordMutation,
mutation: setPassword,
variables: { code: 'not valid', password: 'Aa12345_' },
})
})
@ -303,7 +285,7 @@ describe('UserResolver', () => {
describe('login', () => {
const variables = {
email: 'peter@lustig.de',
email: 'bibi@bloxberg.de',
password: 'Aa12345_',
publisherId: 1234,
}
@ -316,7 +298,7 @@ describe('UserResolver', () => {
describe('no users in database', () => {
beforeAll(async () => {
result = await query({ query: loginQuery, variables })
result = await query({ query: login, variables })
})
it('throws an error', () => {
@ -330,14 +312,8 @@ describe('UserResolver', () => {
describe('user is in database and correct login data', () => {
beforeAll(async () => {
await createUser(mutate, {
email: 'peter@lustig.de',
firstName: 'Peter',
lastName: 'Lustig',
language: 'de',
publisherId: 1234,
})
result = await query({ query: loginQuery, variables })
await createUserFactory(mutate, bibiBloxberg)
result = await query({ query: login, variables })
})
afterAll(async () => {
@ -350,15 +326,15 @@ describe('UserResolver', () => {
data: {
login: {
coinanimation: true,
email: 'peter@lustig.de',
firstName: 'Peter',
email: 'bibi@bloxberg.de',
firstName: 'Bibi',
hasElopage: false,
isAdmin: false,
klickTipp: {
newsletterState: false,
},
language: 'de',
lastName: 'Lustig',
lastName: 'Bloxberg',
publisherId: 1234,
},
},
@ -373,13 +349,7 @@ describe('UserResolver', () => {
describe('user is in database and wrong password', () => {
beforeAll(async () => {
await createUser(mutate, {
email: 'peter@lustig.de',
firstName: 'Peter',
lastName: 'Lustig',
language: 'de',
publisherId: 1234,
})
await createUserFactory(mutate, bibiBloxberg)
})
afterAll(async () => {
@ -388,7 +358,7 @@ describe('UserResolver', () => {
it('returns an error', () => {
expect(
query({ query: loginQuery, variables: { ...variables, password: 'wrong' } }),
query({ query: login, variables: { ...variables, password: 'wrong' } }),
).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('No user with this credentials')],
@ -399,16 +369,10 @@ describe('UserResolver', () => {
})
describe('logout', () => {
const logoutQuery = gql`
query {
logout
}
`
describe('unauthenticated', () => {
it('throws an error', async () => {
resetToken()
await expect(query({ query: logoutQuery })).resolves.toEqual(
await expect(query({ query: logout })).resolves.toEqual(
expect.objectContaining({
errors: [new GraphQLError('401 Unauthorized')],
}),
@ -418,19 +382,13 @@ describe('UserResolver', () => {
describe('authenticated', () => {
const variables = {
email: 'peter@lustig.de',
email: 'bibi@bloxberg.de',
password: 'Aa12345_',
}
beforeAll(async () => {
await createUser(mutate, {
email: 'peter@lustig.de',
firstName: 'Peter',
lastName: 'Lustig',
language: 'de',
publisherId: 1234,
})
await query({ query: loginQuery, variables })
await createUserFactory(mutate, bibiBloxberg)
await query({ query: login, variables })
})
afterAll(async () => {
@ -438,7 +396,7 @@ describe('UserResolver', () => {
})
it('returns true', async () => {
await expect(query({ query: logoutQuery })).resolves.toEqual(
await expect(query({ query: logout })).resolves.toEqual(
expect.objectContaining({
data: { logout: 'true' },
errors: undefined,

View File

@ -0,0 +1,43 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { createUser, setPassword } from '@/seeds/graphql/mutations'
import { User } from '@entity/User'
import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
import { ServerUser } from '@entity/ServerUser'
import { UserInterface } from '@/seeds/users/UserInterface'
export const createUserFactory = async (mutate: any, user: UserInterface): Promise<void> => {
await mutate({ mutation: createUser, variables: user })
let dbUser = await User.findOneOrFail({ where: { email: user.email } })
if (user.emailChecked) {
const optin = await LoginEmailOptIn.findOneOrFail({ where: { userId: dbUser.id } })
await mutate({
mutation: setPassword,
variables: { password: 'Aa12345_', code: optin.verificationCode },
})
}
// refetch data
dbUser = await User.findOneOrFail({ where: { email: user.email } })
if (user.createdAt || user.deletedAt) {
if (user.createdAt) dbUser.createdAt = user.createdAt
if (user.deletedAt) dbUser.deletedAt = user.deletedAt
await dbUser.save()
}
if (user.isAdmin) {
const admin = new ServerUser()
admin.username = dbUser.firstName
admin.password = 'please_refactor'
admin.email = dbUser.email
admin.role = 'admin'
admin.activated = 1
admin.lastLogin = new Date()
admin.created = dbUser.createdAt
admin.modified = dbUser.createdAt
await admin.save()
}
}

View File

@ -0,0 +1,9 @@
export const GdtEntryType = {
FORM: 'FORM',
CVS: 'CVS',
ELOPAGE: 'ELOPAGE',
ELOPAGE_PUBLISHER: 'ELOPAGE_PUBLISHER',
DIGISTORE: 'DIGISTORE',
CVS2: 'CVS2',
GLOBAL_MODIFICATOR: 'GLOBAL_MODIFICATOR',
}

View File

@ -0,0 +1,71 @@
import gql from 'graphql-tag'
export const subscribeNewsletter = gql`
mutation ($email: String!, $language: String!) {
subscribeNewsletter(email: $email, language: $language)
}
`
export const unsubscribeNewsletter = gql`
mutation ($email: String!) {
unsubscribeNewsletter(email: $email)
}
`
export const setPassword = gql`
mutation ($code: String!, $password: String!) {
setPassword(code: $code, password: $password)
}
`
export const updateUserInfos = gql`
mutation (
$firstName: String
$lastName: String
$password: String
$passwordNew: String
$locale: String
$coinanimation: Boolean
) {
updateUserInfos(
firstName: $firstName
lastName: $lastName
password: $password
passwordNew: $passwordNew
language: $locale
coinanimation: $coinanimation
)
}
`
export const createUser = gql`
mutation (
$firstName: String!
$lastName: String!
$email: String!
$language: String!
$publisherId: Int
) {
createUser(
email: $email
firstName: $firstName
lastName: $lastName
language: $language
publisherId: $publisherId
)
}
`
export const sendCoins = gql`
mutation ($email: String!, $amount: Decimal!, $memo: String!) {
sendCoins(email: $email, amount: $amount, memo: $memo)
}
`
export const createTransactionLink = gql`
mutation ($amount: Decimal!, $memo: String!) {
createTransactionLink(amount: $amount, memo: $memo) {
code
}
}
`

View File

@ -0,0 +1,144 @@
import gql from 'graphql-tag'
export const login = gql`
query ($email: String!, $password: String!, $publisherId: Int) {
login(email: $email, password: $password, publisherId: $publisherId) {
email
firstName
lastName
language
coinanimation
klickTipp {
newsletterState
}
hasElopage
publisherId
isAdmin
}
}
`
export const verifyLogin = gql`
query {
verifyLogin {
email
firstName
lastName
language
coinanimation
klickTipp {
newsletterState
}
hasElopage
publisherId
isAdmin
}
}
`
export const logout = gql`
query {
logout
}
`
export const transactionsQuery = gql`
query (
$currentPage: Int = 1
$pageSize: Int = 25
$order: Order = DESC
$onlyCreations: Boolean = false
) {
transactionList(
currentPage: $currentPage
pageSize: $pageSize
order: $order
onlyCreations: $onlyCreations
) {
balanceGDT
count
balance
decayStartBlock
transactions {
id
typeId
amount
balance
balanceDate
memo
linkedUser {
firstName
lastName
}
decay {
decay
start
end
duration
}
}
}
}
`
export const sendResetPasswordEmail = gql`
query ($email: String!) {
sendResetPasswordEmail(email: $email)
}
`
export const listGDTEntriesQuery = gql`
query ($currentPage: Int!, $pageSize: Int!) {
listGDTEntries(currentPage: $currentPage, pageSize: $pageSize) {
count
gdtEntries {
id
amount
date
comment
gdtEntryType
factor
gdt
}
gdtSum
}
}
`
export const communityInfo = gql`
query {
getCommunityInfo {
name
description
registerUrl
url
}
}
`
export const communities = gql`
query {
communities {
id
name
url
description
registerUrl
}
}
`
export const queryTransactionLink = gql`
query ($code: String!) {
queryTransactionLink(code: $code) {
amount
memo
createdAt
validUntil
user {
firstName
publisherId
}
}
}
`

View File

@ -0,0 +1,64 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import createServer from '../server/createServer'
import { createTestClient } from 'apollo-server-testing'
import { name, internet, random } from 'faker'
import { users } from './users/index'
import { createUserFactory } from './factory/user'
import { entities } from '@entity/index'
const context = {
token: '',
setHeaders: {
push: (value: string): void => {
context.token = value
},
// eslint-disable-next-line @typescript-eslint/no-empty-function
forEach: (): void => {},
},
}
export const cleanDB = async () => {
// this only works as lond we do not have foreign key constraints
for (let i = 0; i < entities.length; i++) {
await resetEntity(entities[i])
}
}
const resetEntity = async (entity: any) => {
const items = await entity.find({ withDeleted: true })
if (items.length > 0) {
const ids = items.map((i: any) => i.id)
await entity.delete(ids)
}
}
const run = async () => {
const server = await createServer(context)
const testClient = createTestClient(server.apollo)
const { mutate } = testClient
const { con } = server
await cleanDB()
// seed the standard users
for (let i = 0; i < users.length; i++) {
await createUserFactory(mutate, users[i])
}
// seed 100 random users
for (let i = 0; i < 100; i++) {
await createUserFactory(mutate, {
firstName: name.firstName(),
lastName: name.lastName(),
email: internet.email(),
language: random.boolean() ? 'en' : 'de',
})
}
await con.close()
}
run()

View File

@ -0,0 +1,12 @@
export interface UserInterface {
email?: string
firstName?: string
lastName?: string
// description?: string
createdAt?: Date
emailChecked?: boolean
language?: string
deletedAt?: Date
publisherId?: number
isAdmin?: boolean
}

View File

@ -0,0 +1,11 @@
import { UserInterface } from './UserInterface'
export const bibiBloxberg: UserInterface = {
email: 'bibi@bloxberg.de',
firstName: 'Bibi',
lastName: 'Bloxberg',
// description: 'Hex Hex',
emailChecked: true,
language: 'de',
publisherId: 1234,
}

View File

@ -0,0 +1,10 @@
import { UserInterface } from './UserInterface'
export const bobBaumeister: UserInterface = {
email: 'bob@baumeister.de',
firstName: 'Bob',
lastName: 'der Baumeister',
// description: 'Können wir das schaffen? Ja, wir schaffen das!',
emailChecked: true,
language: 'de',
}

View File

@ -0,0 +1,12 @@
import { UserInterface } from './UserInterface'
export const garrickOllivander: UserInterface = {
email: 'garrick@ollivander.com',
firstName: 'Garrick',
lastName: 'Ollivander',
// description: `Curious ... curious ...
// Renowned wandmaker Mr Ollivander owns the wand shop Ollivanders: Makers of Fine Wands Since 382 BC in Diagon Alley. His shop is widely considered the best place to purchase a wand.`,
createdAt: new Date('2022-01-10T10:23:17'),
emailChecked: false,
language: 'en',
}

View File

@ -0,0 +1,15 @@
import { peterLustig } from './peter-lustig'
import { bibiBloxberg } from './bibi-bloxberg'
import { bobBaumeister } from './bob-baumeister'
import { raeuberHotzenplotz } from './raeuber-hotzenplotz'
import { stephenHawking } from './stephen-hawking'
import { garrickOllivander } from './garrick-ollivander'
export const users = [
peterLustig,
bibiBloxberg,
bobBaumeister,
raeuberHotzenplotz,
stephenHawking,
garrickOllivander,
]

View File

@ -0,0 +1,12 @@
import { UserInterface } from './UserInterface'
export const peterLustig: UserInterface = {
email: 'peter@lustig.de',
firstName: 'Peter',
lastName: 'Lustig',
// description: 'Latzhose und Nickelbrille',
createdAt: new Date('2020-11-25T10:48:43'),
emailChecked: true,
language: 'de',
isAdmin: true,
}

View File

@ -0,0 +1,10 @@
import { UserInterface } from './UserInterface'
export const raeuberHotzenplotz: UserInterface = {
email: 'raeuber@hotzenplotz.de',
firstName: 'Räuber',
lastName: 'Hotzenplotz',
// description: 'Pfefferpistole',
emailChecked: true,
language: 'de',
}

View File

@ -0,0 +1,12 @@
import { UserInterface } from './UserInterface'
export const stephenHawking: UserInterface = {
email: 'stephen@hawking.uk',
firstName: 'Stephen',
lastName: 'Hawking',
// description: 'A Brief History of Time',
emailChecked: true,
createdAt: new Date('1942-01-08T09:17:52'),
deletedAt: new Date('2018-03-14T09:17:52'),
language: 'en',
}

View File

@ -1,25 +0,0 @@
import gql from 'graphql-tag'
export const createUserMutation = gql`
mutation (
$email: String!
$firstName: String!
$lastName: String!
$language: String!
$publisherId: Int
) {
createUser(
email: $email
firstName: $firstName
lastName: $lastName
language: $language
publisherId: $publisherId
)
}
`
export const setPasswordMutation = gql`
mutation ($code: String!, $password: String!) {
setPassword(code: $code, password: $password)
}
`

View File

@ -4,9 +4,6 @@
import { createTestClient } from 'apollo-server-testing'
import createServer from '../src/server/createServer'
import { initialize } from '@dbTools/helpers'
import { createUserMutation, setPasswordMutation } from './graphql'
import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
import { User } from '@entity/User'
import { entities } from '@entity/index'
export const headerPushMock = jest.fn((t) => {
@ -46,19 +43,6 @@ export const resetEntity = async (entity: any) => {
}
}
export const createUser = async (mutate: any, user: any) => {
// resetToken()
await mutate({ mutation: createUserMutation, variables: user })
const dbUser = await User.findOne({ where: { email: user.email } })
if (!dbUser) throw new Error('Ups, no user found')
const optin = await LoginEmailOptIn.findOne({ where: { userId: dbUser.id } })
if (!optin) throw new Error('Ups, no optin found')
await mutate({
mutation: setPasswordMutation,
variables: { password: 'Aa12345_', code: optin.verificationCode },
})
}
export const resetToken = () => {
context.token = ''
}

View File

@ -4,3 +4,4 @@
// eslint-disable-next-line @typescript-eslint/no-empty-function
console.info = () => {}
jest.setTimeout(1000000)

View File

@ -811,6 +811,11 @@
"@types/qs" "*"
"@types/serve-static" "*"
"@types/faker@^5.5.9":
version "5.5.9"
resolved "https://registry.yarnpkg.com/@types/faker/-/faker-5.5.9.tgz#588ede92186dc557bff8341d294335d50d255f0c"
integrity sha512-uCx6mP3UY5SIO14XlspxsGjgaemrxpssJI0Ol+GfhxtcKpv9pgRZYsS4eeKeHVLje6Qtc8lGszuBI461+gVZBA==
"@types/fs-capacitor@*":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/fs-capacitor/-/fs-capacitor-2.0.0.tgz#17113e25817f584f58100fb7a08eed288b81956e"
@ -2510,6 +2515,11 @@ express@^4.17.1:
utils-merge "1.0.1"
vary "~1.1.2"
faker@^5.5.3:
version "5.5.3"
resolved "https://registry.yarnpkg.com/faker/-/faker-5.5.3.tgz#c57974ee484431b25205c2c8dc09fda861e51e0e"
integrity sha512-wLTv2a28wjUyWkbnX7u/ABZBkUkIF2fCd73V6P2oFqEGEktDfzWx4UxrSqtPRw0xPRAcjeAOIiJWqZm3pP4u3g==
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"

View File

@ -1,3 +1,4 @@
node_modules
.git
.gitignore
.gitignore
!.eslintignore

View File

@ -1,3 +1,3 @@
node_modules
**/*.min.js
dist
node_modules/
dist/
coverage/

View File

@ -8,9 +8,24 @@ module.exports = {
parserOptions: {
parser: 'babel-eslint',
},
extends: ['standard', 'plugin:vue/essential', 'plugin:prettier/recommended'],
extends: [
'standard',
'plugin:vue/essential',
'plugin:prettier/recommended',
'plugin:@intlify/vue-i18n/recommended',
],
// required to lint *.vue files
plugins: ['vue', 'prettier', 'jest'],
overrides: [
{
files: ['*.json'],
extends: ['plugin:@intlify/vue-i18n/recommended'],
rules: {
// TODO: enable
'@intlify/vue-i18n/no-html-messages': 'off',
},
},
],
// add your custom rules here
rules: {
'no-console': ['error'],
@ -22,6 +37,29 @@ module.exports = {
allowBinding: false,
},
],
'@intlify/vue-i18n/no-dynamic-keys': 'error',
'@intlify/vue-i18n/no-unused-keys': [
'error',
{
src: './src',
extensions: ['.js', '.vue'],
// TODO: remove ignores
ignores: [
'/site.thx./',
'/form./',
'/time./',
'/decay.types./',
'settings.password.resend_subtitle',
'settings.password.reset-password.text',
'settings.password.set',
'settings.password.set-password.text',
'settings.password.subtitle',
'site.login.signin',
],
enableFix: false,
},
],
'@intlify/vue-i18n/no-missing-keys-in-other-locales': 'error',
'prettier/prettier': [
'error',
{
@ -29,4 +67,12 @@ module.exports = {
},
],
},
settings: {
'vue-i18n': {
localeDir: './src/locales/*.json',
// Specify the version of `vue-i18n` you are using.
// If not specified, the message will be parsed twice.
messageSyntaxVersion: '^8.22.4',
},
},
}

1
frontend/.gitignore vendored
View File

@ -5,7 +5,6 @@ dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
test/unit/coverage
package-lock.json
/.env

View File

@ -8,11 +8,10 @@
"build": "vue-cli-service build",
"dev": "yarn run serve",
"analyse-bundle": "yarn build && webpack-bundle-analyzer dist/webpack.stats.json",
"lint": "eslint --max-warnings=0 --ext .js,.vue .",
"lint": "eslint --max-warnings=0 --ext .js,.vue,.json .",
"stylelint": "stylelint --max-warnings=0 '**/*.{scss,vue}'",
"i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'",
"test": "TZ=UTC jest --coverage",
"locales": "scripts/missing-keys.sh && scripts/sort.sh"
"locales": "scripts/sort.sh"
},
"dependencies": {
"@babel/core": "^7.13.13",
@ -67,6 +66,7 @@
"vuex-persistedstate": "^4.0.0-beta.3"
},
"devDependencies": {
"@intlify/eslint-plugin-vue-i18n": "^1.4.0",
"@vue/cli-plugin-babel": "^3.7.0",
"@vue/cli-plugin-eslint": "^3.7.0",
"@vue/cli-service": "^3.7.0",

View File

@ -1,36 +0,0 @@
{"state":"success", "statisticdata":
[
{
"i_creation_sum": 29288278.4653,
"i_creation_mon": 68278.4653,
"i_creation_365d": 19288278.4653,
"i_creation_30d": 288278.4653,
"i_creation_14d": 88278.4653,
"i_creation_7d": 3278.4653
},
{
"i_transience_sum": 8278.4653,
"i_transience_mon": 8278.4653,
"i_transience_365d": 8278.4653,
"i_transience_30d": 178.4653,
"i_transience_14d": 78.4653,
"i_transience_7d": 8.4653
},
{
"i_exchange_sum": 23345.2324,
"i_exchange_mon": 2,
"i_exchange_365d": 2,
"i_exchange_30d": 2,
"i_exchange_14d": 2,
"i_exchange_7d": 2
},
{
"i_members_sum": 5398,
"i_members_mon": 234,
"i_members_365d": 2356,
"i_members_30d": 123,
"i_members_14d": 23,
"i_members_7d": 24
}
]
}

View File

@ -1,64 +0,0 @@
{"state":"success", "statisticdata":
[
{
"charts_creation_0_mon": 5635,
"charts_creation_1_mon": 5635,
"charts_creation_2_mon": 5635,
"charts_creation_3_mon": 5635,
"charts_creation_4_mon": 5635,
"charts_creation_5_mon": 5635,
"charts_creation_6_mon": 5635,
"charts_creation_7_mon": 5635,
"charts_creation_8_mon": 5635,
"charts_creation_9_mon": 5635,
"charts_creation_10_mon": 5635,
"charts_creation_11_mon": 5635,
"charts_creation_12_mon": 5635
},
{
"charts_transience_0_mon": 5635,
"charts_transience_1_mon": 5635,
"charts_transience_2_mon": 5635,
"charts_transience_3_mon": 5635,
"charts_transience_4_mon": 5635,
"charts_transience_5_mon": 5635,
"charts_transience_6_mon": 5635,
"charts_transience_7_mon": 5635,
"charts_transience_8_mon": 5635,
"charts_transience_9_mon": 5635,
"charts_transience_10_mon": 5635,
"charts_transience_11_mon": 5635,
"charts_transience_12_mon": 5635
},
{
"charts_exchange_0_mon": 5635,
"charts_exchange_1_mon": 5635,
"charts_exchange_2_mon": 5635,
"charts_exchange_3_mon": 5635,
"charts_exchange_4_mon": 5635,
"charts_exchange_5_mon": 5635,
"charts_exchange_6_mon": 5635,
"charts_exchange_7_mon": 5635,
"charts_exchange_8_mon": 5635,
"charts_exchange_9_mon": 5635,
"charts_exchange_10_mon": 5635,
"charts_exchange_11_mon": 5635,
"charts_exchange_12_mon": 5635
},
{
"charts_members_0_mon": 5635,
"charts_members_1_mon": 5635,
"charts_members_2_mon": 5635,
"charts_members_3_mon": 5635,
"charts_members_4_mon": 5635,
"charts_members_5_mon": 5635,
"charts_members_6_mon": 5635,
"charts_members_7_mon": 5635,
"charts_members_8_mon": 5635,
"charts_members_9_mon": 5635,
"charts_members_10_mon": 5635,
"charts_members_11_mon": 5635,
"charts_members_12_mon": 5635
}
]
}

View File

@ -1,19 +0,0 @@
{"state":"success", "statisticdata":
[
{
"community_entries1_mon": 5635,
"community_entries2_mon": 5635,
"community_entries3_mon": 5635,
"community_entries4_mon": 5635,
"community_entries5_mon": 5635,
"community_entries6_mon": 5635,
"community_entries7_mon": 5635,
"community_entries8_mon": 5635,
"community_entries9_mon": 5635,
"community_entries0_mon": 5635,
"community_entries10_mon": 5635,
"community_entries11_mon": 5635,
"community_entries12_mon": 5635
}
]
}

View File

@ -1,61 +0,0 @@
{"state":"success", "transactions":
[
{
"name": "Jon Tester",
"email": "jon@example.de",
"type": "send",
"transaction_id": 12,
"date": "29-11-2020",
"balance": 7000,
"memo": "Reperatur Waschbecken",
"pubkey": "abcdefghi123456789"
},
{
"name": "Gradido Community",
"email": "gradido@example.de",
"type": "creation",
"transaction_id": 11,
"date": "1-11-2020",
"balance": 10000,
"memo": "Müll gesammelt im Wald",
"pubkey": "abcdefghi123456789"
},
{
"name": "Maria Tester",
"email": "maria@example.de",
"type": "receive",
"transaction_id": 7,
"date": "23-10-2020",
"balance": 5000,
"memo": "Spende an Alice ",
"pubkey": "abcdefghi123456789"
},
{
"name": "Alice Tester",
"email": "alice@example.de",
"type": "receive",
"transaction_id": 5,
"date": "2-8-2020",
"balance": 1000,
"memo": "Bob hat meinen Müll getrennt",
"pubkey": "abcdefghi123456789"
},
{
"name": "Gradido Community",
"email": "gradido@example.de",
"type": "creation",
"transaction_id": 1,
"date": "11-7-2020",
"balance": 10000,
"memo": "Bob hat meinen Müll getrennt",
"pubkey": "abcdefghi123456789"
}
],
"transactionExecutingCount": 8750,
"count": 5
}

View File

@ -1,49 +0,0 @@
{"state":"success", "participation":
[
{
"name": "",
"type": "submitted",
"participation_id": 412,
"date_submitted": "9-12-2020",
"titel": "Lorem Ipsum panta lore es Tastina sero was. ",
"text": "Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. ",
"date_participation": "8-12-2020",
"plz_participation": "01099",
"pubkey": "abcdefghi123456789"
},
{
"name": "",
"type": "in progress",
"participation_id": 312,
"date_submitted": "2-11-2020",
"titel": "Lorem Ipsum panta lore es Tastina sero was. ",
"text": "Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. ",
"date_participation": "2-11-2020",
"plz_participation": "01099",
"pubkey": "abcdefghi123456789"
},
{
"name": "",
"type": "confirmed",
"participation_id": 212,
"date_submitted": "20-10-2020",
"titel": "Lorem Ipsum panta lore es Tastina sero was. ",
"text": "Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. ",
"date_participation": "20-10-2020",
"plz_participation": "01099",
"pubkey": "abcdefghi123456789"
},
{
"name": "",
"type": "rejected",
"participation_id": 142,
"date_submitted": "17-9-2020",
"titel": "Lorem Ipsum panta lore es Tastina sero was. ",
"text": "Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. ",
"date_participation": "17-9-2020",
"plz_participation": "01099",
"pubkey": "abcdefghi123456789"
}
],
"count": 4
}

View File

@ -1,52 +0,0 @@
{"state":"success", "admin0userlist":
[
{
"created": 1578688666,
"disabled": false,
"email": "dervommond@gmail.com",
"email_checked": true,
"first_name": "Max",
"group_alias": "gdd1",
"ident_hash": 2928827813,
"last_name": "Miau",
"public_hex": "2ed28a1cf5e116d83615406bc577152221c2f774a5656f66a0e7540f7576d71b",
"role": "admin",
"username": "",
"balance_gdd": 174500,
"balance_gdt": 4500,
"errorCount": 0
},
{
"created": 1578685678,
"disabled": false,
"email": "ttwer@gmail.com",
"email_checked": true,
"first_name": "John",
"group_alias": "gdd1",
"ident_hash": 2928827813,
"last_name": "Doe",
"public_hex": "2ed28a1cf5e116d83615406bc577152221c2f774a5656f66a0e7540f7576d71x",
"role": "user",
"username": "",
"balance_gdd": 144500,
"balance_gdt": 0,
"errorCount": 0
},
{
"created": 1578635671,
"disabled": false,
"email": "test@gmail.com",
"email_checked": true,
"first_name": "Alice",
"group_alias": "gdd1",
"ident_hash": 4928827813,
"last_name": "Seer",
"public_hex": "2ed28a1cf5e116d83615406bc577152221c2f774a5656f66a0e7540f7576d71a",
"role": "user",
"username": "",
"balance_gdd": 444500,
"balance_gdt": 4500,
"errorCount": 0
}
]
}

View File

@ -1,19 +0,0 @@
{"state":"success", "userdata":
[
{
"created": 1578688666,
"disabled": false,
"email": "dervommond@gmail.com",
"email_checked": true,
"first_name": "Max",
"group_alias": "gdd1",
"ident_hash": 2928827813,
"last_name": "Miau",
"public_hex": "2ed28a1cf5e116d83615406bc577152221c2f774a5656f66a0e7540f7576d71b",
"role": "admin",
"username": "",
"balance": 174500,
"errorCount": 0
}
]
}

View File

@ -1,45 +0,0 @@
{"state":"success", "participation":
[
{
"type": "submitted",
"participation_id": 412,
"date_submitted": "9-12-2020",
"titel": "Lorem Ipsum panta lore es Tastina sero was. ",
"text": "Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. ",
"date_participation": "8-12-2020",
"plz_participation": "01099",
"pubkey": "abcdefghi123456789"
},
{
"type": "in progress",
"participation_id": 312,
"date_submitted": "2-11-2020",
"titel": "Lorem Ipsum panta lore es Tastina sero was. ",
"text": "Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. ",
"date_participation": "2-11-2020",
"plz_participation": "01099",
"pubkey": "abcdefghi123456789"
},
{
"type": "confirmed",
"participation_id": 212,
"date_submitted": "20-10-2020",
"titel": "Lorem Ipsum panta lore es Tastina sero was. ",
"text": "Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. ",
"date_participation": "20-10-2020",
"plz_participation": "01099",
"pubkey": "abcdefghi123456789"
},
{
"type": "rejected",
"participation_id": 142,
"date_submitted": "17-9-2020",
"titel": "Lorem Ipsum panta lore es Tastina sero was. ",
"text": "Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. Lorem Ipsum panta lore es Tastina sero was. ",
"date_participation": "17-9-2020",
"plz_participation": "01099",
"pubkey": "abcdefghi123456789"
}
],
"count": 4
}

View File

@ -1,61 +0,0 @@
{"state":"success", "transactions":
[
{
"name": "Jon Tester",
"email": "jon@example.de",
"type": "send",
"transaction_id": 12,
"date": "29-11-2020",
"balance": 7000,
"memo": "Reperatur Waschbecken",
"pubkey": "abcdefghi123456789"
},
{
"name": "Gradido Community",
"email": "gradido@example.de",
"type": "creation",
"transaction_id": 11,
"date": "1-11-2020",
"balance": 10000,
"memo": "Müll gesammelt im Wald",
"pubkey": "abcdefghi123456789"
},
{
"name": "Maria Tester",
"email": "maria@example.de",
"type": "receive",
"transaction_id": 7,
"date": "23-10-2020",
"balance": 5000,
"memo": "Spende an Alice ",
"pubkey": "abcdefghi123456789"
},
{
"name": "Alice Tester",
"email": "alice@example.de",
"type": "receive",
"transaction_id": 5,
"date": "2-8-2020",
"balance": 1000,
"memo": "Bob hat meinen Müll getrennt",
"pubkey": "abcdefghi123456789"
},
{
"name": "Gradido Community",
"email": "gradido@example.de",
"type": "creation",
"transaction_id": 1,
"date": "11-7-2020",
"balance": 10000,
"memo": "Bob hat meinen Müll getrennt",
"pubkey": "abcdefghi123456789"
}
],
"transactionExecutingCount": 8750,
"count": 5
}

View File

@ -1,17 +0,0 @@
#!/bin/bash
ROOT_DIR=$(dirname "$0")/..
sorting="jq -f $ROOT_DIR/scripts/sort_filter.jq"
english="$sorting $ROOT_DIR/src/locales/en.json"
german="$sorting $ROOT_DIR/src/locales/de.json"
listPaths="jq -c 'path(..)|[.[]|tostring]|join(\".\")'"
diffString="<( $english | $listPaths ) <( $german | $listPaths )"
if eval "diff -q $diffString";
then
: # all good
else
eval "diff -y $diffString | grep '[|<>]'";
printf "\nEnglish and German translation keys do not match, see diff above.\n"
exit 1
fi

View File

@ -11,7 +11,7 @@ describe('ContentFooter', () => {
$i18n: {
locale: 'en',
},
$t: jest.fn((t) => t),
$t: jest.fn((t, options) => (options ? [t, options] : t)),
}
const Wrapper = () => {
@ -33,11 +33,11 @@ describe('ContentFooter', () => {
})
it('renders the copyright year', () => {
expect(wrapper.find('div.copyright').text()).toMatch(/©\s*2[0-9]{3,3}\s+/)
expect(mocks.$t).toBeCalledWith('footer.copyright.year', { year: 2022 })
})
it('renders a link to Gradido-Akademie', () => {
expect(wrapper.find('div.copyright').find('a').text()).toEqual('Gradido-Akademie')
expect(wrapper.find('div.copyright').find('a').text()).toEqual('footer.copyright.link')
})
it('links to the login page when clicked on copyright', () => {
@ -51,7 +51,7 @@ describe('ContentFooter', () => {
it('shows the current version', async () => {
wrapper.setData({ version: 1.23 })
await wrapper.vm.$nextTick()
expect(wrapper.find('div.copyright').findAll('a').at(1).text()).toEqual('App version 1.23')
expect(mocks.$t).toBeCalledWith('footer.app_version', { version: 1.23 })
})
it('links to latest release on GitHub', () => {
@ -64,7 +64,7 @@ describe('ContentFooter', () => {
wrapper.setData({ shortHash: 'ACCEDED' })
wrapper.setData({ hash: 'ACCEDEDC001D00DC001D00DC001D00DC001CAFA' })
await wrapper.vm.$nextTick()
expect(wrapper.find('div.copyright').findAll('a').at(2).text()).toEqual('(ACCEDED)')
expect(mocks.$t).toBeCalledWith('footer.short_hash', { shortHash: 'ACCEDED' })
})
it('links to last release commit', async () => {
@ -78,7 +78,7 @@ describe('ContentFooter', () => {
describe('links to gradido.net', () => {
it('has a link to the legal notice', () => {
expect(wrapper.findAll('a.nav-link').at(0).text()).toEqual('imprint')
expect(wrapper.findAll('a.nav-link').at(0).text()).toEqual('footer.imprint')
})
it('links to the https://gradido.net/en/impressum when locale is en', () => {
@ -88,7 +88,7 @@ describe('ContentFooter', () => {
})
it('has a link to the privacy policy', () => {
expect(wrapper.findAll('a.nav-link').at(1).text()).toEqual('privacy_policy')
expect(wrapper.findAll('a.nav-link').at(1).text()).toEqual('footer.privacy_policy')
})
it('links to the https://gradido.net/en/datenschutz when locale is en', () => {
@ -98,7 +98,7 @@ describe('ContentFooter', () => {
})
it('has a link to the members area', () => {
expect(wrapper.findAll('a.nav-link').at(2).text()).toEqual('members_area')
expect(wrapper.findAll('a.nav-link').at(2).text()).toEqual('navigation.members_area')
})
it('links to the elopage', () => {

View File

@ -3,24 +3,24 @@
<b-row align-v="center" class="mt-4 justify-content-lg-between">
<b-col>
<div class="copyright text-center text-lg-center text-muted">
© {{ year }}
{{ $t('footer.copyright.year', { year }) }}
<a
:href="`https://gradido.net/${$i18n.locale}`"
class="font-weight-bold ml-1"
target="_blank"
>
Gradido-Akademie
{{ $t('footer.copyright.link') }}
</a>
|
{{ $t('math.pipe') }}
<a href="https://github.com/gradido/gradido/releases/latest" target="_blank">
App version {{ version }}
{{ $t('footer.app_version', { version }) }}
</a>
<a
v-if="hash"
:href="'https://github.com/gradido/gradido/commit/' + hash"
target="_blank"
>
({{ shortHash }})
{{ $t('footer.short_hash', { shortHash }) }}
</a>
</div>
</b-col>
@ -29,16 +29,16 @@
<b-col>
<b-nav class="nav-footer justify-content-center">
<b-nav-item :href="`https://gradido.net/${$i18n.locale}/impressum/`" target="_blank">
{{ $t('imprint') }}
{{ $t('footer.imprint') }}
</b-nav-item>
<b-nav-item :href="`https://gradido.net/${$i18n.locale}/datenschutz/`" target="_blank">
{{ $t('privacy_policy') }}
{{ $t('footer.privacy_policy') }}
</b-nav-item>
<b-nav-item
:href="`https://elopage.com/s/gradido/sign_in?locale=${$i18n.locale}`"
target="_blank"
>
{{ $t('members_area') }}
{{ $t('navigation.members_area') }}
</b-nav-item>
<b-nav-item
:href="
@ -48,10 +48,10 @@
"
target="_blank"
>
{{ $t('whitepaper') }}
{{ $t('footer.whitepaper') }}
</b-nav-item>
<b-nav-item :href="`https://gradido.net/${$i18n.locale}/contact/`" target="_blank">
{{ $t('site.navbar.support') }}
{{ $t('navigation.support') }}
</b-nav-item>
</b-nav>
</b-col>

View File

@ -14,7 +14,7 @@
<b-col cols="6">
<div>
{{ (Number(balance) - Number(decay.decay)) | GDD }}
{{ decay.decay | GDD }} =
{{ decay.decay | GDD }} {{ $t('math.equal') }}
<b>{{ balance | GDD }}</b>
</div>
</b-col>

View File

@ -4,12 +4,11 @@
<b-col cols="12" class="text-center">
<div>
<div class="display-4">{{ $t('decay.Starting_block_decay') }}</div>
<div>{{ $t('decay.decay_introduced') }} :</div>
<div>{{ $t('decay.decay_introduced') }}</div>
</div>
<div>
<span v-if="decay.start">
{{ $d(new Date(decay.start), 'long') }}
{{ $i18n.locale === 'de' ? 'Uhr' : '' }}
</span>
</div>
</b-col>
@ -28,7 +27,8 @@
</b-row>
<!-- Type-->
<b-row>
<b-col cols="6" class="text-right">{{ $t(`decay.${typeId.toLowerCase()}`) }}</b-col>
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
<b-col cols="6" class="text-right">{{ $t(`decay.types.${typeId.toLowerCase()}`) }}</b-col>
<b-col cols="6">{{ amount | GDD }}</b-col>
</b-row>
<!-- Decay-->

View File

@ -15,7 +15,6 @@
<div>
<span>
{{ $d(new Date(decay.start), 'long') }}
{{ $i18n.locale === 'de' ? 'Uhr' : '' }}
</span>
</div>
</b-col>
@ -44,7 +43,8 @@
</b-row>
<!-- Type-->
<b-row>
<b-col cols="6" class="text-right">{{ $t(`decay.${typeId.toLowerCase()}`) }}</b-col>
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
<b-col cols="6" class="text-right">{{ $t(`decay.types.${typeId.toLowerCase()}`) }}</b-col>
<b-col cols="6">{{ amount | GDD }}</b-col>
</b-row>
<!-- Decay-->
@ -82,7 +82,8 @@ export default {
const result = []
order.forEach((timeSpan) => {
if (this.duration[timeSpan] > 0) {
const locale = this.$t(`decay.${timeSpan}`)
// eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys
const locale = this.$t(`time.${timeSpan}`)
result.push(`${this.duration[timeSpan]} ${locale}`)
}
})

View File

@ -1,5 +1,6 @@
<template>
<b-alert show variant="secondary">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-v-html -->
<span class="alert-text" v-html="$t('form.scann_code')"></span>
<b-col v-show="!scan" lg="12" class="text-right">
<a @click="toggle" class="nav-link pointer">
@ -18,6 +19,7 @@
<b-row>
<b-col lg="8">
<b-alert show variant="secondary">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-v-html -->
<span class="alert-text" v-html="$t('form.scann_code')"></span>
</b-alert>
</b-col>

View File

@ -28,12 +28,14 @@
<strong>{{ $t('gdd_per_link.decay-14-day') }}</strong>
</b-col>
<b-col class="text-right borderbottom">
<strong>~ {{ (amount * 0.028 * -1) | GDD }}</strong>
<strong>{{ $t('math.aprox') }} {{ (amount * 0.028 * -1) | GDD }}</strong>
</b-col>
</b-row>
<b-row class="pr-3">
<b-col class="text-right">{{ $t('form.new_balance') }}</b-col>
<b-col class="text-right">~ {{ (balance - amount - amount * 0.028) | GDD }}</b-col>
<b-col class="text-right">
{{ $t('math.aprox') }} {{ (balance - amount - amount * 0.028) | GDD }}
</b-col>
</b-row>
</b-container>

View File

@ -15,7 +15,7 @@
<label class="input-2" for="input-2">{{ $t('form.amount') }}</label>
<b-input-group id="input-group-2" class="borderbottom" size="lg">
<b-input-group-prepend class="p-2 d-none d-md-block gray-background">
<div class="m-1 mt-2">GDD</div>
<div class="m-1 mt-2">{{ $t('GDD') }}</div>
</b-input-group-prepend>
<div class="p-3">{{ (amount * -1) | GDD }}</div>
@ -27,7 +27,7 @@
<b-input-group-prepend class="d-none d-md-block gray-background">
<b-icon icon="chat-right-text" class="display-4 m-3 mt-4"></b-icon>
</b-input-group-prepend>
<div class="p-3">{{ memo ? memo : '-' }}</div>
<div class="p-3">{{ memo ? memo : $t('em-dash') }}</div>
</b-input-group>
</b-list-group>
</b-col>

View File

@ -76,7 +76,7 @@
<label class="input-2" for="input-2">{{ $t('form.amount') }}</label>
<b-input-group id="input-group-2" class="border border-default" size="lg">
<b-input-group-prepend class="p-2 d-none d-md-block">
<div class="m-1 mt-2">GDD</div>
<div class="m-1 mt-2">{{ $t('GDD') }}</div>
</b-input-group-prepend>
<b-form-input

View File

@ -19,7 +19,7 @@
>
{{ $t('transaction.receiverDeleted') }}
</div>
<div v-else>({{ errorResult }})</div>
<div v-else>{{ errorResult }}</div>
</div>
<p class="text-center mt-3">
<b-button variant="success" @click="$emit('on-reset')">{{ $t('form.close') }}</b-button>

View File

@ -440,7 +440,7 @@ describe('GddTransactionList', () => {
})
it('shows the text "1 / 2"', () => {
expect(paginationButtons.find('p.text-center').text()).toBe('1 / 2')
expect(paginationButtons.find('p.text-center').text()).toBe('1 math.div 2')
})
it('emits update-transactions when next button is clicked', async () => {
@ -452,7 +452,7 @@ describe('GddTransactionList', () => {
it('shows text "2 / 2" when next button is clicked', async () => {
await paginationButtons.find('button.next-page').trigger('click')
expect(paginationButtons.find('p.text-center').text()).toBe('2 / 2')
expect(paginationButtons.find('p.text-center').text()).toBe('2 math.div 2')
})
it('has next-button disabled when next button is clicked', async () => {

View File

@ -2,10 +2,12 @@
<div>
<b-list-group>
<b-list-group-item v-if="count > 5">
<!-- eslint-disable @intlify/vue-i18n/no-v-html -->
<router-link
to="/transactions"
v-html="$t('transaction.show_all', { count: count })"
v-html="$t('transaction.show_all', { count })"
></router-link>
<!-- eslint-enable @intlify/vue-i18n/no-v-html -->
</b-list-group-item>
</b-list-group>
</div>

View File

@ -54,31 +54,31 @@ describe('Navbar', () => {
expect(wrapper.findAll('.nav-item').at(1).text()).toEqual('1234 GDD')
})
it('has first nav-item "overview" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(3).text()).toEqual('overview')
it('has first nav-item "navigation.overview" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(3).text()).toEqual('navigation.overview')
})
it('has first nav-item "send" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(4).text()).toEqual('send')
it('has first nav-item "navigation.send" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(4).text()).toEqual('navigation.send')
})
it('has first nav-item "transactions" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(5).text()).toEqual('transactions')
it('has first nav-item "navigation.transactions" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(5).text()).toEqual('navigation.transactions')
})
it('has first nav-item "my-profil" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(6).text()).toEqual('site.navbar.my-profil')
it('has first nav-item "navigation.profile" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(6).text()).toEqual('navigation.profile')
})
it('has a link to the members area', () => {
expect(wrapper.findAll('.nav-item').at(7).text()).toContain('members_area')
expect(wrapper.findAll('.nav-item').at(7).text()).toContain('navigation.members_area')
expect(wrapper.findAll('.nav-item').at(7).find('a').attributes('href')).toBe(
'https://elopage.com',
)
})
it('has first nav-item "admin_area" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(8).text()).toEqual('admin_area')
it('has first nav-item "navigation.admin_area" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(8).text()).toEqual('navigation.admin_area')
})
it('has first nav-item "logout" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(9).text()).toEqual('logout')
it('has first nav-item "navigation.logout" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(9).text()).toEqual('navigation.logout')
})
})
})

View File

@ -10,10 +10,10 @@
</div>
<b-navbar-nav class="ml-auto" is-nav>
<b-nav-item>{{ pending ? '—' : balance | amount }} GDD</b-nav-item>
<b-nav-item>{{ pending ? $t('em-dash') : balance | amount }} {{ $t('GDD') }}</b-nav-item>
<b-nav-item to="/profile" right class="d-none d-sm-none d-md-none d-lg-flex shadow-lg">
<small>
{{ $store.state.firstName }} {{ $store.state.lastName }},
{{ $store.state.firstName }} {{ $store.state.lastName }}
<b>{{ $store.state.email }}</b>
<b-icon class="ml-3" icon="gear-fill" aria-hidden="true"></b-icon>
</small>
@ -32,40 +32,42 @@
<b-link to="/profile">
<small>
{{ $store.state.firstName }}
{{ $store.state.lastName }},
{{ $store.state.lastName }}
<b>{{ $store.state.email }}</b>
</small>
</b-link>
</div>
<b-nav-item to="/overview" class="mb-3">
<b-icon icon="house" aria-hidden="true"></b-icon>
{{ $t('overview') }}
{{ $t('navigation.overview') }}
</b-nav-item>
<b-nav-item to="/send" class="mb-3">
<b-icon icon="arrow-left-right" aria-hidden="true"></b-icon>
{{ $t('send') }}
{{ $t('navigation.send') }}
</b-nav-item>
<b-nav-item to="/transactions" class="mb-3">
<b-icon icon="layout-text-sidebar-reverse" aria-hidden="true"></b-icon>
{{ $t('transactions') }}
{{ $t('navigation.transactions') }}
</b-nav-item>
<b-nav-item to="/profile" class="mb-3">
<b-icon icon="gear" aria-hidden="true"></b-icon>
{{ $t('site.navbar.my-profil') }}
{{ $t('navigation.profile') }}
</b-nav-item>
<br />
<b-nav-item :href="elopageUri" class="mb-3" target="_blank">
<b-icon icon="link45deg" aria-hidden="true"></b-icon>
{{ $t('members_area') }}
<b-badge v-if="!$store.state.hasElopage" pill variant="danger">!</b-badge>
{{ $t('navigation.members_area') }}
<b-badge v-if="!$store.state.hasElopage" pill variant="danger">
{{ $t('math.exclaim') }}
</b-badge>
</b-nav-item>
<b-nav-item class="mb-3" v-if="$store.state.isAdmin" @click="$emit('admin')">
<b-icon icon="shield-check" aria-hidden="true"></b-icon>
{{ $t('admin_area') }}
{{ $t('navigation.admin_area') }}
</b-nav-item>
<b-nav-item class="mb-3" @click="$emit('logout')">
<b-icon icon="power" aria-hidden="true"></b-icon>
{{ $t('logout') }}
{{ $t('navigation.logout') }}
</b-nav-item>
</b-nav>
</b-collapse>

View File

@ -36,29 +36,29 @@ describe('Sidebar', () => {
expect(wrapper.findAll('.nav-item')).toHaveLength(7)
})
it('has first nav-item "overview" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(0).text()).toEqual('overview')
it('has first nav-item "navigation.overview" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(0).text()).toEqual('navigation.overview')
})
it('has first nav-item "send" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(1).text()).toEqual('send')
it('has first nav-item "navigation.send" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(1).text()).toEqual('navigation.send')
})
it('has first nav-item "transactions" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(2).text()).toEqual('transactions')
it('has first nav-item "navigation.transactions" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(2).text()).toEqual('navigation.transactions')
})
it('has first nav-item "my-profil" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(3).text()).toEqual('site.navbar.my-profil')
it('has first nav-item "navigation.profile" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(3).text()).toEqual('navigation.profile')
})
it('has a link to the members area', () => {
expect(wrapper.findAll('.nav-item').at(4).text()).toContain('members_area')
expect(wrapper.findAll('.nav-item').at(4).text()).toContain('navigation.members_area')
expect(wrapper.findAll('.nav-item').at(4).find('a').attributes('href')).toBe('#')
})
it('has first nav-item "admin_area" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(5).text()).toEqual('admin_area')
it('has first nav-item "navigation.admin_area" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(5).text()).toEqual('navigation.admin_area')
})
it('has first nav-item "logout" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(6).text()).toEqual('logout')
it('has first nav-item "navigation.logout" in navbar', () => {
expect(wrapper.findAll('.nav-item').at(6).text()).toEqual('navigation.logout')
})
})
})

View File

@ -6,35 +6,37 @@
<b-nav vertical class="w-200">
<b-nav-item to="/overview" class="mb-3">
<b-icon icon="house" aria-hidden="true"></b-icon>
{{ $t('overview') }}
{{ $t('navigation.overview') }}
</b-nav-item>
<b-nav-item to="/send" class="mb-3">
<b-icon icon="arrow-left-right" aria-hidden="true"></b-icon>
{{ $t('send') }}
{{ $t('navigation.send') }}
</b-nav-item>
<b-nav-item to="/transactions" class="mb-3">
<b-icon icon="layout-text-sidebar-reverse" aria-hidden="true"></b-icon>
{{ $t('transactions') }}
{{ $t('navigation.transactions') }}
</b-nav-item>
<b-nav-item to="/profile" class="mb-3">
<b-icon icon="gear" aria-hidden="true"></b-icon>
{{ $t('site.navbar.my-profil') }}
{{ $t('navigation.profile') }}
</b-nav-item>
</b-nav>
<hr />
<b-nav vertical class="w-100">
<b-nav-item class="mb-3" :href="elopageUri" target="_blank">
<b-icon icon="link45deg" aria-hidden="true"></b-icon>
{{ $t('members_area') }}
<b-badge v-if="!$store.state.hasElopage" pill variant="danger">!</b-badge>
{{ $t('navigation.members_area') }}
<b-badge v-if="!$store.state.hasElopage" pill variant="danger">
{{ $t('math.exclaim') }}
</b-badge>
</b-nav-item>
<b-nav-item class="mb-3" v-if="$store.state.isAdmin" @click="$emit('admin')">
<b-icon icon="shield-check" aria-hidden="true"></b-icon>
{{ $t('admin_area') }}
{{ $t('navigation.admin_area') }}
</b-nav-item>
<b-nav-item class="mb-3" @click="$emit('logout')">
<b-icon icon="power" aria-hidden="true"></b-icon>
{{ $t('logout') }}
{{ $t('navigation.logout') }}
</b-nav-item>
</b-nav>
</div>

View File

@ -12,8 +12,12 @@ const propsData = {
describe('PaginationButtons', () => {
let wrapper
const mocks = {
$t: jest.fn((t) => t),
}
const Wrapper = () => {
return mount(PaginationButtons, { localVue, propsData })
return mount(PaginationButtons, { localVue, mocks, propsData })
}
describe('mount', () => {

View File

@ -7,7 +7,7 @@
</b-button>
</b-col>
<b-col cols="3">
<p class="text-center pt-2">{{ value }} / {{ totalPages }}</p>
<p class="text-center pt-2">{{ value }} {{ $t('math.div') }} {{ totalPages }}</p>
</b-col>
<b-col>
<b-button class="next-page" :disabled="!hasNext" @click="currentValue++">

View File

@ -7,6 +7,7 @@ describe('Status', () => {
let wrapper
const mocks = {
$t: jest.fn((t) => t),
$n: jest.fn((n) => n),
}
@ -26,7 +27,7 @@ describe('Status', () => {
describe('balance is pending', () => {
it('it displays an en-dash', () => {
expect(wrapper.find('div.gdd-status-div').text()).toEqual(' GDD')
expect(wrapper.find('div.gdd-status-div').text()).toEqual('em-dash GDD')
})
})

View File

@ -1,7 +1,7 @@
<template>
<div class="gdd-status">
<div class="p-0 gdd-status-div">
{{ pending || balance === null ? '—' : $n(balance, 'decimal') }} {{ statusText }}
{{ pending || balance === null ? $t('em-dash') : $n(balance, 'decimal') }} {{ statusText }}
</div>
</div>
</template>

View File

@ -51,7 +51,7 @@
{{ $t('form.date') }}
</b-col>
<b-col cols="6">
{{ $d(new Date(date), 'long') }} {{ $i18n.locale === 'de' ? 'Uhr' : '' }}
{{ $d(new Date(date), 'long') }}
</b-col>
</b-row>

View File

@ -15,18 +15,18 @@
<div class="text-center font-weight-bold">
{{ $n(balance, 'decimal') }}
</div>
<div class="text-center">GDD</div>
<div class="text-center">{{ $t('GDD') }}</div>
</b-col>
<b-col>
<div class="text-center font-weight-bold">
{{ transactionCount }}
</div>
<div class="text-center">
{{ $t('transactions') }}
{{ $t('navigation.transactions') }}
</div>
</b-col>
<b-col>
<div class="text-center font-weight-bold">--</div>
<div class="text-center font-weight-bold">{{ $t('em-dash') }}</div>
<div class="text-center">
{{ $t('community.community') }}
</div>

View File

@ -42,8 +42,8 @@ describe('UserCard_FormUserMail', () => {
expect(wrapper.find('a[href="#formusermail"]').exists()).toBeTruthy()
})
it('renders the E-Mail form.change', () => {
expect(wrapper.findAll('div.col').at(0).text()).toBe('E-Mail form.change')
it('renders the form.email form.change', () => {
expect(wrapper.findAll('div.col').at(0).text()).toBe('form.email form.change')
})
it('renders the E-Mail', () => {

View File

@ -4,7 +4,7 @@
<b-row class="mb-4 text-right">
<b-col class="text-right">
<a href="#formusermail" v-if="edit_email" @click="edit_email = !edit_email">
<span>E-Mail {{ $t('form.change') }}</span>
<span>{{ $t('form.email') }} {{ $t('form.change') }}</span>
</a>
<div v-else>
<a href="#formusermail" @click="onSubmit">
@ -21,7 +21,7 @@
<b-row class="mb-3">
<b-col class="col-lg-3 col-md-10 col-sm-10 text-md-left text-lg-right">
<small>E-Mail</small>
<small>{{ $t('form.email') }}</small>
</b-col>
<b-col v-if="edit_email" class="col-md-9 col-sm-10">{{ $store.state.email }}</b-col>
<b-col v-else class="col-md-9 col-sm-10">

View File

@ -22,6 +22,7 @@
<b>{{ $t('language') }}</b>
</small>
</b-col>
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
<b-col class="col-12">{{ $t(buildTagFromLanguageString()) }}</b-col>
</b-row>
</div>

View File

@ -8,7 +8,7 @@
</div>
</template>
<script>
import ContentFooter from './ContentFooter.vue'
import ContentFooter from '@/components/ContentFooter.vue'
import LanguageSwitch from '@/components/LanguageSwitch.vue'
export default {
components: {

View File

@ -41,7 +41,7 @@
import Navbar from '@/components/Menu/Navbar.vue'
import Sidebar from '@/components/Menu/Sidebar.vue'
import { logout, transactionsQuery } from '@/graphql/queries'
import ContentFooter from './ContentFooter.vue'
import ContentFooter from '@/components/ContentFooter.vue'
import { FadeTransition } from 'vue2-transitions'
import CONFIG from '@/config'

View File

@ -1,22 +1,11 @@
{
"admin_area": "Adminbereich",
"advanced-calculation": "Vorausberechnung",
"back": "Zurück",
"community": {
"choose-another-community": "Eine andere Gemeinschaft auswählen",
"communities": {
"form": {
"date_period": "Datum / Zeitraum",
"hours": "Stunden",
"hours_report": "Stundenbericht",
"more_hours": "weitere Stunden",
"submit": "Einreichen"
}
},
"community": "Gemeinschaft",
"continue-to-registration": "Weiter zur Registrierung",
"current-community": "Aktuelle Gemeinschaft",
"location": "Ort:",
"other-communities": "Weitere Gemeinschaften",
"switch-to-this-community": "zu dieser Gemeinschaft wechseln"
},
@ -24,38 +13,40 @@
"before_startblock_transaction": "Diese Transaktion beinhaltet keine Vergänglichkeit.",
"calculation_decay": "Berechnung der Vergänglichkeit",
"calculation_total": "Berechnung der Gesamtsumme",
"created": "Geschöpft",
"days": "Tage",
"decay": "Vergänglichkeit",
"decayStart": " - Startblock für Vergänglichkeit am: ",
"decay_introduced": "Die Vergänglichkeit wurde eingeführt am ",
"decay_introduced": "Die Vergänglichkeit wurde eingeführt am:",
"decay_since_last_transaction": "Vergänglichkeit seit der letzten Transaktion",
"first_transaction": "Die erste Transaktion beinhaltet keine Vergänglichkeit.",
"hours": "Stunden",
"last_transaction": "Letzte Transaktion",
"minutes": "Minuten",
"months": "Monate",
"noDecay": "Keine Vergänglichkeit",
"past_time": "Vergangene Zeit",
"receive": "Empfangen",
"seconds": "Sekunden",
"send": "Gesendet",
"since_introduction": "seit Einführung der Vergänglichkeit",
"Starting_block_decay": "Startblock Vergänglichkeit",
"toCommunity": "An die Gemeinschaft",
"total": "Gesamt",
"year": "Jahre"
"types": {
"created": "Geschöpft",
"noDecay": "Keine Vergänglichkeit",
"receive": "Empfangen",
"send": "Gesendet"
}
},
"delete": "löschen",
"em-dash": "—",
"error": {
"change-password": "Fehler beim Ändern des Passworts",
"empty-transactionlist": "Es gab einen Fehler mit der Übermittlung der Anzahl deiner Transaktionen.",
"error": "Fehler",
"error": "Fehler!",
"no-account": "Leider konnten wir keinen Account mit diesen Daten finden.",
"no-email-verify": "Dein Konto wurde noch nicht bestätigt. Bitte überprüfe deine E-Mails und klicke auf den Aktivierungslink!",
"no-transactionlist": "Es gab leider einen Fehler. Es wurden keine Transaktionen vom Server übermittelt",
"session-expired": "Die Sitzung wurde aus Sicherheitsgründen beendet."
},
"footer": {
"app_version": "App version {version}",
"copyright": {
"link": "Gradido-Akademie",
"year": "© {year}"
},
"imprint": "Impressum",
"privacy_policy": "Datenschutzerklärung",
"short_hash": "({shortHash})",
"whitepaper": "Whitepaper"
},
"form": {
"amount": "Betrag",
"at": "am",
@ -101,6 +92,7 @@
},
"your_amount": "Dein Betrag"
},
"GDD": "GDD",
"gdd_per_link": {
"copy": "kopieren",
"created": "Der Link wurde erstellt!",
@ -113,14 +105,9 @@
"links_count": "Aktive Links",
"links_sum": "Summe deiner versendeten Gradidos",
"not-copied": "Konnte den Link nicht kopieren: {err}",
"sentence_1": "Wähle einen Betrag aus, welchen du per Link versenden möchtest. Du kannst auch noch eine Nachricht eintragen. Beim Klick „jetzt generieren“ wird ein Link erstellt, den du versenden kannst.",
"sentence_2": "Der Link ist 14 Tage gültig!",
"sentence_3": "Wird der Link nicht innerhalb der 14 Tage Frist abgerufen, wird er automatisch gelöscht. Der Betrag wird dann wieder deinem Konto gutgeschrieben.",
"sentence_4": "Wer den Link aktiviert, erhält die Zahlung von deinem Konto. Wer noch nicht Mitglied bei Gradido ist, wird durch den Registrierungsprozess geleitet und bekommt den GDD Betrag nach Registrierung / Bestätigung seines Gradido Kontos gut geschrieben.",
"sentence_5": "Der Vergänglichkeitsbetrag wird von dir getragen und für die maximale Gültigkeit deinem Betrag aufgerechnet. Dir wird aber nur der Betrag als Vergänglichkeit berechnet, je nachdem wie viel Tage bis zum Einlösen des Links vergangen sind. Bis zum Einlösen wird die Vergänglichkeit für den gesamten Zeitraum der Gültigkeit vorgehalten."
"sentence_1": "Wähle einen Betrag aus, welchen du per Link versenden möchtest. Du kannst auch noch eine Nachricht eintragen. Beim Klick „jetzt generieren“ wird ein Link erstellt, den du versenden kannst."
},
"gdt": {
"action": "Aktion",
"calculation": "Berechnung der GradidoTransform",
"contribution": "Beitrag",
"conversion": "Umrechnung",
@ -136,23 +123,33 @@
"raise": "Erhöhung",
"recruited-member": "Eingeladenes Mitglied"
},
"imprint": "Impressum",
"language": "Sprache",
"link-load": "den letzten Link nachladen | die letzten {n} Links nachladen | weitere {n} Links nachladen",
"links-list": {
"header": "Liste deiner aktiven Links"
},
"login": "Anmeldung",
"logout": "Abmelden",
"members_area": "Mitgliederbereich",
"message": "hallo gradido!!",
"overview": "Übersicht",
"privacy_policy": "Datenschutzerklärung",
"math": {
"aprox": "~",
"div": "/",
"equal": "=",
"exclaim": "!",
"pipe": "|"
},
"navigation": {
"admin_area": "Adminbereich",
"logout": "Abmelden",
"members_area": "Mitgliederbereich",
"overview": "Übersicht",
"profile": "Mein Profil",
"send": "Senden",
"support": "Support",
"transactions": "Transaktionen"
},
"publisher": {
"infoText": "Wenn dir dein Empfehlungsgeber seine Publisher-Id gegeben hat, trage sie hier ein, sonst lass das Feld bitte unverändert!",
"publisherId": "Publisher-Id"
"publisherId": "Publisher-Id:"
},
"send": "Senden",
"send_gdd": "GDD versenden",
"send_per_link": "GDD versenden per Link",
"settings": {
@ -165,7 +162,6 @@
"changeLanguage": "Sprache ändern",
"de": "Deutsch",
"en": "English",
"select_language": "Bitte wähle eine Sprache.",
"success": "Deine Sprache wurde erfolgreich geändert."
},
"name": {
@ -180,7 +176,6 @@
"password": {
"change-password": "Passwort ändern",
"forgot_pwd": "Passwort vergessen?",
"not-authenticated": "Leider konnten wir dich nicht authentifizieren. Bitte wende dich an den Support.",
"resend_subtitle": "Dein Aktivierungslink ist abgelaufen. Du kannst hier ein neuen anfordern.",
"reset": "Passwort zurücksetzen",
"reset-password": {
@ -196,24 +191,12 @@
},
"signup": "Registrieren",
"site": {
"404": {
"back": "Zurück zur Übersicht",
"ooops": "Ooops!",
"text": "Seite nicht gefunden. Aber keine Sorge, wir haben noch viele andere Seiten zu erkunden."
},
"checkEmail": {
"errorText": "E-Mail konnte nicht verifiziert werden.",
"title": "E-Mail wird verifiziert"
},
"login": {
"community": "Tausend Dank, weil du bei uns bist!",
"heading": "Gradido",
"new_wallet": "Neues Konto erstellen",
"signin": "Anmelden"
},
"navbar": {
"my-profil": "Mein Profil",
"support": "Support"
},
"signup": {
"agree": "Ich stimme der <a href='https://gradido.net/de/datenschutz/' target='_blank' >Datenschutzerklärung</a> zu.",
"dont_match": "Die Passwörter stimmen nicht überein.",
@ -238,10 +221,17 @@
}
},
"success": "Erfolg",
"time": {
"days": "Tage",
"hours": "Stunden",
"minutes": "Minuten",
"months": "Monate",
"seconds": "Sekunden",
"year": "Jahre"
},
"transaction": {
"gdd-text": "Gradido Transaktionen",
"gdt-text": "GradidoTransform Transaktionen",
"more": "mehr",
"nullTransactions": "Du hast noch keine Transaktionen auf deinem Konto.",
"receiverDeleted": "Das Empfängerkonto wurde gelöscht",
"receiverNotFound": "Empfänger nicht gefunden",
@ -250,7 +240,5 @@
"transaction-link": {
"button": "einlösen",
"send_you": "sendet dir"
},
"transactions": "Transaktionen",
"whitepaper": "Whitepaper"
}
}

View File

@ -1,22 +1,11 @@
{
"admin_area": "Admin Area",
"advanced-calculation": "Advanced calculation",
"back": "Back",
"community": {
"choose-another-community": "Choose another community",
"communities": {
"form": {
"date_period": "Date / Period",
"hours": "hours",
"hours_report": "Hourly report",
"more_hours": "more hours",
"submit": "Submit"
}
},
"community": "Community",
"continue-to-registration": "Continue to registration",
"current-community": "Current community",
"location": "Location:",
"other-communities": "Other communities",
"switch-to-this-community": "Switch to this community"
},
@ -24,38 +13,40 @@
"before_startblock_transaction": "This transaction does not include decay.",
"calculation_decay": "Calculation of Decay",
"calculation_total": "Calculation of the total Amount",
"created": "Created",
"days": "Days",
"decay": "Decay",
"decayStart": " - Starting block for decay at: ",
"decay_introduced": "Decay was introduced on",
"decay_introduced": "Decay was introduced on:",
"decay_since_last_transaction": "Decay since the last transaction",
"first_transaction": "The first transaction does not include decay.",
"hours": "Hours",
"last_transaction": "Last transaction:",
"minutes": "Minutes",
"months": "Months",
"noDecay": "No Decay",
"past_time": "Time passed",
"receive": "Received",
"seconds": "Seconds",
"send": "Sent",
"since_introduction": "Since the introduction of Decay",
"Starting_block_decay": "Starting Block Decay",
"toCommunity": "To the community",
"total": "Total",
"year": "Years"
"types": {
"created": "Created",
"noDecay": "No Decay",
"receive": "Received",
"send": "Sent"
}
},
"delete": "delete",
"em-dash": "—",
"error": {
"change-password": "Error while changing password",
"empty-transactionlist": "There was an error with the transmission of the number of your transactions.",
"error": "Error",
"error": "Error!",
"no-account": "Unfortunately we could not find an account to the given data!",
"no-email-verify": "Your account has not been confirmed yet. Please check your emails and click on the activation link!",
"no-transactionlist": "Unfortunately, there was an error. No transactions have been sent from the server.",
"session-expired": "The session was closed for security reasons."
},
"footer": {
"app_version": "App version {version}",
"copyright": {
"link": "Gradido-Akademie",
"year": "© {year}"
},
"imprint": "Legal notice",
"privacy_policy": "Privacy policy",
"short_hash": "({shortHash})",
"whitepaper": "Whitepaper"
},
"form": {
"amount": "Amount",
"at": "at",
@ -101,6 +92,7 @@
},
"your_amount": "Your amount"
},
"GDD": "GDD",
"gdd_per_link": {
"copy": "copy",
"created": "Link was created!",
@ -113,14 +105,9 @@
"links_count": "Active links",
"links_sum": "Total of your sent Gradidos",
"not-copied": "Could not copy link: {err}",
"sentence_1": "Select an amount that you would like to send via link. You can also enter a message. Click 'Generate now' to create a link that you can share.",
"sentence_2": "The link is valid for 14 days!",
"sentence_3": "If the link is not redeemed within the 14-day validity period, it will be invalidated automatically. The amount will then be available to your account again.",
"sentence_4": "Whoever activates the link will receive the payment from your account. If the recipient is not yet a member of Gradido, he will be guided through the registration process and will get the GDD amount credited after registration / confirmation of the newly created Gradido account.",
"sentence_5": "The decay amount will be blocked for your account for the whole duration of the link. However, you will only be charged the amount of decay for the time which has actually passed until the link is redeemed. The remaining amount will then be available to your account again."
"sentence_1": "Select an amount that you would like to send via link. You can also enter a message. Click 'Generate now' to create a link that you can share."
},
"gdt": {
"action": "Action",
"calculation": "Calculation of GradidoTransform",
"contribution": "Contribution",
"conversion": "Conversion",
@ -136,23 +123,33 @@
"raise": "Increase",
"recruited-member": "Invited member"
},
"imprint": "Legal notice",
"language": "Language",
"link-load": "Load the last link | Load the last {n} links | Load more {n} links",
"links-list": {
"header": "List of your active links"
},
"login": "Login",
"logout": "Logout",
"members_area": "Members area",
"message": "hello gradido !!",
"overview": "Overview",
"privacy_policy": "Privacy policy",
"math": {
"aprox": "~",
"div": "/",
"equal": "=",
"exclaim": "!",
"pipe": "|"
},
"navigation": {
"admin_area": "Admin Area",
"logout": "Logout",
"members_area": "Members area",
"overview": "Overview",
"profile": "My profile",
"send": "Send",
"support": "Support",
"transactions": "Transactions"
},
"publisher": {
"infoText": "If your referrer has given you his publisher id, enter it here, otherwise leave the field unchanged!",
"publisherId": "PublisherID"
"publisherId": "PublisherID:"
},
"send": "Send",
"send_gdd": "GDD send",
"send_per_link": "GDD send via link",
"settings": {
@ -165,7 +162,6 @@
"changeLanguage": "Change language",
"de": "Deutsch",
"en": "English",
"select_language": "Please choose your language.",
"success": "Your language has been successfully updated."
},
"name": {
@ -180,7 +176,6 @@
"password": {
"change-password": "Change password",
"forgot_pwd": "Forgot password?",
"not-authenticated": "Unfortunately we could not authenticate you. Please contact the support.",
"resend_subtitle": "Your activation link has expired, here you can order a new one.",
"reset": "Reset password",
"reset-password": {
@ -196,24 +191,12 @@
},
"signup": "Sign up",
"site": {
"404": {
"back": "Back to the overview",
"ooops": "Ooops!",
"text": "Page not found. But don't worry, we have many other sites to explore."
},
"checkEmail": {
"errorText": "Could not verify the email.",
"title": "Verifing email"
},
"login": {
"community": "A thousand thanks for being with us!",
"heading": "Gradido",
"new_wallet": "Create new account",
"signin": "Sign in"
},
"navbar": {
"my-profil": "My profile",
"support": "Support"
},
"signup": {
"agree": "I agree to the <a href='https://gradido.net/en/datenschutz/' target='_blank' > privacy policy</a>.",
"dont_match": "Passwords don't match.",
@ -238,10 +221,17 @@
}
},
"success": "Success",
"time": {
"days": "Days",
"hours": "Hours",
"minutes": "Minutes",
"months": "Months",
"seconds": "Seconds",
"year": "Years"
},
"transaction": {
"gdd-text": "Gradido Transactions",
"gdt-text": "GradidoTransform Transactions",
"more": "more",
"nullTransactions": "You don't have any transactions on your account yet.",
"receiverDeleted": "The recipient account was deleted",
"receiverNotFound": "Recipient not found",
@ -250,7 +240,5 @@
"transaction-link": {
"button": "redeem",
"send_you": "wants to send you"
},
"transactions": "Transactions",
"whitepaper": "Whitepaper"
}
}

View File

@ -5,8 +5,9 @@
<div class="header-body text-center mb-7">
<b-row class="justify-content-center">
<b-col xl="5" lg="6" md="8" class="px-2">
<h1>{{ $t(displaySetup.headline) }}</h1>
<p class="text-lead">{{ $t(displaySetup.subtitle) }}</p>
<h1>{{ $t('settings.password.reset') }}</h1>
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
<p class="text-lead">{{ $t(subtitle) }}</p>
</b-col>
</b-row>
</div>
@ -22,7 +23,7 @@
<input-email v-model="form.email"></input-email>
<div class="text-center">
<b-button type="submit" variant="primary">
{{ $t(displaySetup.button) }}
{{ $t('settings.password.send_now') }}
</b-button>
</div>
</b-form>
@ -41,21 +42,6 @@
import { sendResetPasswordEmail } from '@/graphql/queries'
import InputEmail from '@/components/Inputs/InputEmail'
const textFields = {
resetPassword: {
headline: 'settings.password.reset',
subtitle: 'settings.password.resend_subtitle',
button: 'settings.password.send_now',
cancel: 'back',
},
login: {
headline: 'settings.password.reset',
subtitle: 'settings.password.subtitle',
button: 'settings.password.send_now',
cancel: 'back',
},
}
export default {
name: 'ForgotPassword',
components: {
@ -67,7 +53,7 @@ export default {
form: {
email: '',
},
displaySetup: {},
subtitle: 'settings.password.subtitle',
}
},
methods: {
@ -89,9 +75,7 @@ export default {
},
created() {
if (this.$route.params.comingFrom) {
this.displaySetup = textFields[this.$route.params.comingFrom]
} else {
this.displaySetup = textFields.login
this.subtitle = 'settings.password.resend_subtitle'
}
},
}

View File

@ -98,7 +98,7 @@ describe('Login', () => {
describe('Login header', () => {
it('has a welcome message', () => {
expect(wrapper.find('div.header').text()).toBe('Gradido site.login.community')
expect(wrapper.find('div.header').text()).toBe('site.login.heading site.login.community')
})
})

View File

@ -6,7 +6,7 @@
<div class="text-center mb-7 header">
<b-row class="justify-content-center">
<b-col xl="5" lg="6" md="8" class="px-2">
<h1>Gradido</h1>
<h1>{{ $t('site.login.heading') }}</h1>
<p class="text-lead">{{ $t('site.login.community') }}</p>
</b-col>
</b-row>

View File

@ -270,7 +270,7 @@ describe('Register', () => {
it('shows error message', () => {
expect(wrapper.find('span.alert-text').exists()).toBeTruthy()
expect(wrapper.find('span.alert-text').text().length !== 0).toBeTruthy()
expect(wrapper.find('span.alert-text').text()).toContain('error.error!')
expect(wrapper.find('span.alert-text').text()).toContain('error.error')
expect(wrapper.find('span.alert-text').text()).toContain('Ouch!')
})

View File

@ -100,6 +100,7 @@
v-model="form.agree"
:name="$t('site.signup.agree')"
>
<!-- eslint-disable-next-line @intlify/vue-i18n/no-v-html -->
<span class="text-muted" v-html="$t('site.signup.agree')"></span>
</b-form-checkbox>
</b-col>
@ -113,14 +114,12 @@
>
<span class="alert-icon"><i class="ni ni-point"></i></span>
<span class="alert-text">
<strong>{{ $t('error.error') }}!</strong>
<strong>{{ $t('error.error') }}</strong>
{{ messageError }}
</span>
</b-alert>
<b-row v-b-toggle:my-collapse class="text-muted shadow-sm p-3 publisherCollaps">
<b-col>
{{ $t('publisher.publisherId') }} : {{ $store.state.publisherId }}
</b-col>
<b-col>{{ $t('publisher.publisherId') }} {{ $store.state.publisherId }}</b-col>
<b-col class="text-right">
<b-icon icon="chevron-down" aria-hidden="true"></b-icon>
</b-col>

View File

@ -5,9 +5,11 @@
<div class="header-body text-center mb-7">
<b-row class="justify-content-center">
<b-col xl="5" lg="6" md="8" class="px-2">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
<h1>{{ $t(displaySetup.authenticated) }}</h1>
<div class="pb-4">
<span>
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
{{ $t(displaySetup.notAuthenticated) }}
</span>
</div>
@ -26,6 +28,7 @@
<input-password-confirmation v-model="form" />
<div class="text-center">
<b-button type="submit" variant="primary" class="mt-4">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
{{ $t(displaySetup.button) }}
</b-button>
</div>

View File

@ -4,10 +4,13 @@
<div class="header py-7 py-lg-8 pt-lg-9">
<b-container>
<div class="header-body text-center mb-7">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
<p class="h1">{{ $t(displaySetup.headline) }}</p>
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
<p class="h4">{{ $t(displaySetup.subtitle) }}</p>
<hr />
<b-button v-if="displaySetup.linkTo" :to="displaySetup.linkTo">
<!-- eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys-->
{{ $t(displaySetup.button) }}
</b-button>
</div>

View File

@ -5,7 +5,9 @@ import { required, email, min, max, is_not } from 'vee-validate/dist/rules'
export const loadAllRules = (i18nCallback) => {
configure({
defaultMessage: (field, values) => {
// eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys
values._field_ = i18nCallback.t(`fields.${field}`)
// eslint-disable-next-line @intlify/vue-i18n/no-dynamic-keys
return i18nCallback.t(`validations.messages.${values._rule_}`, values)
},
classes: {
@ -17,21 +19,25 @@ export const loadAllRules = (i18nCallback) => {
extend('email', {
...email,
// eslint-disable-next-line @intlify/vue-i18n/no-missing-keys
message: (_, values) => i18nCallback.t('validations.messages.email', values),
})
extend('required', {
...required,
// eslint-disable-next-line @intlify/vue-i18n/no-missing-keys
message: (_, values) => i18nCallback.t('validations.messages.required', values),
})
extend('min', {
...min,
// eslint-disable-next-line @intlify/vue-i18n/no-missing-keys
message: (_, values) => i18nCallback.t('validations.messages.min', values),
})
extend('max', {
...max,
// eslint-disable-next-line @intlify/vue-i18n/no-missing-keys
message: (_, values) => i18nCallback.t('validations.messages.max', values),
})

View File

@ -15,6 +15,7 @@ module.exports = {
fallbackLocale: 'de',
localeDir: 'locales',
enableInSFC: false,
enableLegacy: false,
},
},
lintOnSave: true,

View File

@ -1726,6 +1726,13 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.14.0":
version "7.17.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.7.tgz#a5f3328dc41ff39d803f311cfe17703418cf9825"
integrity sha512-L6rvG9GDxaLgFjg41K+5Yv9OMrU98sWe+Ykmc6FDJW/+vYZMhdOMKkISgzptMaERHvS2Y2lw9MDRm2gHhlQQoA==
dependencies:
regenerator-runtime "^0.13.4"
"@babel/template@7", "@babel/template@^7.12.13", "@babel/template@^7.16.0", "@babel/template@^7.3.3":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6"
@ -1875,6 +1882,21 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"
"@eslint/eslintrc@^1.2.0":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6"
integrity sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
espree "^9.3.1"
globals "^13.9.0"
ignore "^5.2.0"
import-fresh "^3.2.1"
js-yaml "^4.1.0"
minimatch "^3.0.4"
strip-json-comments "^3.1.1"
"@hapi/address@2.x.x":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
@ -1916,6 +1938,83 @@
cssnano-preset-default "^4.0.0"
postcss "^7.0.0"
"@intlify/core-base@^9.1.9":
version "9.1.9"
resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-9.1.9.tgz#e4e8c951010728e4af3a0d13d74cf3f9e7add7f6"
integrity sha512-x5T0p/Ja0S8hs5xs+ImKyYckVkL4CzcEXykVYYV6rcbXxJTe2o58IquSqX9bdncVKbRZP7GlBU1EcRaQEEJ+vw==
dependencies:
"@intlify/devtools-if" "9.1.9"
"@intlify/message-compiler" "9.1.9"
"@intlify/message-resolver" "9.1.9"
"@intlify/runtime" "9.1.9"
"@intlify/shared" "9.1.9"
"@intlify/vue-devtools" "9.1.9"
"@intlify/devtools-if@9.1.9":
version "9.1.9"
resolved "https://registry.yarnpkg.com/@intlify/devtools-if/-/devtools-if-9.1.9.tgz#a30e1dd1256ff2c5c98d8d75d075384fba898e5d"
integrity sha512-oKSMKjttG3Ut/1UGEZjSdghuP3fwA15zpDPcjkf/1FjlOIm6uIBGMNS5jXzsZy593u+P/YcnrZD6cD3IVFz9vQ==
dependencies:
"@intlify/shared" "9.1.9"
"@intlify/eslint-plugin-vue-i18n@^1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@intlify/eslint-plugin-vue-i18n/-/eslint-plugin-vue-i18n-1.4.0.tgz#f8fe791892c2dce7d189a364b6a908c87e1c3ac9"
integrity sha512-anB1eBf6rpxpWyW883gi6O1hozQy4Q02VyzyodOUnohOqT07GATVSxnr2J9/qQSV47xWukV+9LiRErJcU7d/uA==
dependencies:
"@eslint/eslintrc" "^1.2.0"
"@intlify/core-base" "^9.1.9"
"@intlify/message-compiler" "^9.1.9"
debug "^4.3.1"
glob "^7.1.3"
ignore "^5.0.5"
is-language-code "^3.1.0"
js-yaml "^4.0.0"
json5 "^2.1.3"
jsonc-eslint-parser "^2.0.0"
lodash "^4.17.11"
parse5 "^6.0.0"
semver "^7.3.4"
vue-eslint-parser "^8.0.0"
yaml-eslint-parser "^0.5.0"
"@intlify/message-compiler@9.1.9", "@intlify/message-compiler@^9.1.9":
version "9.1.9"
resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-9.1.9.tgz#1193cbd224a71c2fb981455b8534a3c766d2948d"
integrity sha512-6YgCMF46Xd0IH2hMRLCssZI3gFG4aywidoWQ3QP4RGYQXQYYfFC54DxhSgfIPpVoPLQ+4AD29eoYmhiHZ+qLFQ==
dependencies:
"@intlify/message-resolver" "9.1.9"
"@intlify/shared" "9.1.9"
source-map "0.6.1"
"@intlify/message-resolver@9.1.9":
version "9.1.9"
resolved "https://registry.yarnpkg.com/@intlify/message-resolver/-/message-resolver-9.1.9.tgz#3155ccd2f5e6d0dc16cad8b7f1d8e97fcda05bfc"
integrity sha512-Lx/DBpigeK0sz2BBbzv5mu9/dAlt98HxwbG7xLawC3O2xMF9MNWU5FtOziwYG6TDIjNq0O/3ZbOJAxwITIWXEA==
"@intlify/runtime@9.1.9":
version "9.1.9"
resolved "https://registry.yarnpkg.com/@intlify/runtime/-/runtime-9.1.9.tgz#2c12ce29518a075629efed0a8ed293ee740cb285"
integrity sha512-XgPw8+UlHCiie3fI41HPVa/VDJb3/aSH7bLhY1hJvlvNV713PFtb4p4Jo+rlE0gAoMsMCGcsiT982fImolSltg==
dependencies:
"@intlify/message-compiler" "9.1.9"
"@intlify/message-resolver" "9.1.9"
"@intlify/shared" "9.1.9"
"@intlify/shared@9.1.9":
version "9.1.9"
resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-9.1.9.tgz#0baaf96128b85560666bec784ffb01f6623cc17a"
integrity sha512-xKGM1d0EAxdDFCWedcYXOm6V5Pfw/TMudd6/qCdEb4tv0hk9EKeg7lwQF1azE0dP2phvx0yXxrt7UQK+IZjNdw==
"@intlify/vue-devtools@9.1.9":
version "9.1.9"
resolved "https://registry.yarnpkg.com/@intlify/vue-devtools/-/vue-devtools-9.1.9.tgz#2be8f4dbe7f7ed4115676eb32348141d411e426b"
integrity sha512-YPehH9uL4vZcGXky4Ev5qQIITnHKIvsD2GKGXgqf+05osMUI6WSEQHaN9USRa318Rs8RyyPCiDfmA0hRu3k7og==
dependencies:
"@intlify/message-resolver" "9.1.9"
"@intlify/runtime" "9.1.9"
"@intlify/shared" "9.1.9"
"@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
@ -3192,6 +3291,11 @@ acorn@^8.2.4:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895"
integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==
acorn@^8.5.0, acorn@^8.7.0:
version "8.7.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf"
integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==
address@^1.0.3:
version "1.1.2"
resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
@ -3466,6 +3570,11 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
arr-diff@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
@ -5504,7 +5613,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9:
dependencies:
ms "2.0.0"
debug@4, debug@^4.1.0, debug@^4.3.3:
debug@4, debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3:
version "4.3.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
@ -6409,6 +6518,14 @@ eslint-scope@^5.0.0, eslint-scope@^5.1.1:
esrecurse "^4.3.0"
estraverse "^4.1.1"
eslint-scope@^7.0.0:
version "7.1.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642"
integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==
dependencies:
esrecurse "^4.3.0"
estraverse "^5.2.0"
eslint-utils@^2.0.0, eslint-utils@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27"
@ -6426,6 +6543,11 @@ eslint-visitor-keys@^2.0.0:
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8"
integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==
eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.1.0, eslint-visitor-keys@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
eslint@^4.19.1:
version "4.19.1"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300"
@ -6544,6 +6666,15 @@ espree@^7.3.0, espree@^7.3.1:
acorn-jsx "^5.3.1"
eslint-visitor-keys "^1.3.0"
espree@^9.0.0, espree@^9.3.1:
version "9.3.1"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd"
integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==
dependencies:
acorn "^8.7.0"
acorn-jsx "^5.3.1"
eslint-visitor-keys "^3.3.0"
esprima@^4.0.0, esprima@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
@ -7401,6 +7532,13 @@ globals@^13.6.0:
dependencies:
type-fest "^0.20.2"
globals@^13.9.0:
version "13.12.1"
resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.1.tgz#ec206be932e6c77236677127577aa8e50bf1c5cb"
integrity sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==
dependencies:
type-fest "^0.20.2"
globals@^9.18.0:
version "9.18.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
@ -7939,16 +8077,16 @@ ignore@^4.0.3, ignore@^4.0.6:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
ignore@^5.0.5, ignore@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
ignore@^5.1.1, ignore@^5.1.4:
version "5.1.8"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
ignore@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
import-cwd@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
@ -8329,6 +8467,13 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
dependencies:
is-extglob "^2.1.1"
is-language-code@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/is-language-code/-/is-language-code-3.1.0.tgz#b2386b49227e7010636f16d0c2c681ca40136ab5"
integrity sha512-zJdQ3QTeLye+iphMeK3wks+vXSRFKh68/Pnlw7aOfApFSEIOhYa8P9vwwa6QrImNNBMJTiL1PpYF0f4BxDuEgA==
dependencies:
"@babel/runtime" "^7.14.0"
is-negative-zero@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
@ -9551,6 +9696,13 @@ js-yaml@^3.13.1, js-yaml@^3.9.1:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^4.0.0, js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
argparse "^2.0.1"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
@ -9740,7 +9892,7 @@ json3@^3.3.3:
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==
json5@2.x, json5@^2.1.2:
json5@2.x, json5@^2.1.2, json5@^2.1.3:
version "2.2.0"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
@ -9759,6 +9911,16 @@ json5@^1.0.1:
dependencies:
minimist "^1.2.0"
jsonc-eslint-parser@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/jsonc-eslint-parser/-/jsonc-eslint-parser-2.1.0.tgz#4c126b530aa583d85308d0b3041ff81ce402bbb2"
integrity sha512-qCRJWlbP2v6HbmKW7R3lFbeiVWHo+oMJ0j+MizwvauqnCV/EvtAeEeuCgoc/ErtsuoKgYB8U4Ih8AxJbXoE6/g==
dependencies:
acorn "^8.5.0"
eslint-visitor-keys "^3.0.0"
espree "^9.0.0"
semver "^7.3.5"
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
@ -11104,7 +11266,7 @@ parse5@5.1.0:
resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2"
integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==
parse5@6.0.1, parse5@^6.0.1:
parse5@6.0.1, parse5@^6.0.0, parse5@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
@ -12968,16 +13130,16 @@ source-map-url@^0.4.0:
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==
source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@^0.5.0, source-map@^0.5.6:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@^0.7.3:
version "0.7.3"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
@ -14340,6 +14502,19 @@ vue-eslint-parser@^7.6.0:
esquery "^1.4.0"
lodash "^4.17.15"
vue-eslint-parser@^8.0.0:
version "8.3.0"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz#5d31129a1b3dd89c0069ca0a1c88f970c360bd0d"
integrity sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==
dependencies:
debug "^4.3.2"
eslint-scope "^7.0.0"
eslint-visitor-keys "^3.1.0"
espree "^9.0.0"
esquery "^1.4.0"
lodash "^4.17.21"
semver "^7.3.5"
vue-flatpickr-component@^8.1.2:
version "8.1.6"
resolved "https://registry.yarnpkg.com/vue-flatpickr-component/-/vue-flatpickr-component-8.1.6.tgz#8fb25dc72946ceb1ab005b871a8151461c0883f6"
@ -14979,7 +15154,16 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yaml@^1.10.0:
yaml-eslint-parser@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/yaml-eslint-parser/-/yaml-eslint-parser-0.5.0.tgz#01d4e4d992a820769ea85ef5fd526dfc20ebc6f5"
integrity sha512-nJeyLA3YHAzhBTZbRAbu3W6xrSCucyxExmA+ZDtEdUFpGllxAZpto2Zxo2IG0r0eiuEiBM4e+wiAdxTziTq94g==
dependencies:
eslint-visitor-keys "^3.0.0"
lodash "^4.17.21"
yaml "^1.10.2"
yaml@^1.10.0, yaml@^1.10.2:
version "1.10.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==