Merge pull request #1214 from gradido/refactor_adminarea

pr_admin_refactor
This commit is contained in:
Alexander Friedland 2021-12-27 16:20:57 +01:00 committed by GitHub
commit cb041b2816
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 184 additions and 19 deletions

View File

@ -47,7 +47,7 @@ jobs:
########################################################################## ##########################################################################
- name: Admin | Build `test` image - name: Admin | Build `test` image
run: | run: |
docker build --target test -t "gradido/admin:test" admin/ docker build --target test -t "gradido/admin:test" admin/ --build-arg NODE_ENV="test"
docker save "gradido/admin:test" > /tmp/admin.tar docker save "gradido/admin:test" > /tmp/admin.tar
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
@ -294,6 +294,35 @@ jobs:
- name: Admin Interface | Lint - name: Admin Interface | Lint
run: docker run --rm gradido/admin:test yarn run lint run: docker run --rm gradido/admin:test yarn run lint
##############################################################################
# JOB: LOCALES ADMIN ######################################################
##############################################################################
locales_admin:
name: Locales - Admin
runs-on: ubuntu-latest
needs: [build_test_admin]
steps:
##########################################################################
# CHECKOUT CODE ##########################################################
##########################################################################
- name: Checkout code
uses: actions/checkout@v2
##########################################################################
# DOWNLOAD DOCKER IMAGE ##################################################
##########################################################################
- name: Download Docker Image (Admin Interface)
uses: actions/download-artifact@v2
with:
name: docker-admin-test
path: /tmp
- name: Load Docker Image
run: docker load < /tmp/admin.tar
##########################################################################
# LOCALES FRONTEND #######################################################
##########################################################################
- name: admin | Locales
run: docker run --rm gradido/admin:test yarn run locales
############################################################################## ##############################################################################
# JOB: LINT BACKEND ########################################################## # JOB: LINT BACKEND ##########################################################
############################################################################## ##############################################################################

View File

@ -13,7 +13,7 @@ ENV BUILD_VERSION="0.0.0.0"
## We cannot do `$(git rev-parse --short HEAD)` here so we default to 0000000 ## We cannot do `$(git rev-parse --short HEAD)` here so we default to 0000000
ENV BUILD_COMMIT="0000000" ENV BUILD_COMMIT="0000000"
## SET NODE_ENV ## SET NODE_ENV
ENV NODE_ENV="production" ARG NODE_ENV="production"
## App relevant Envs ## App relevant Envs
ENV PORT="8080" ENV PORT="8080"

View File

@ -1,4 +1,15 @@
module.exports = { module.exports = function (api) {
presets: ['@babel/preset-env'], api.cache(true)
plugins: ['transform-require-context'],
const presets = ['@babel/preset-env']
const plugins = []
if (process.env.NODE_ENV === 'test') {
plugins.push('transform-require-context')
}
return {
presets,
plugins,
}
} }

View File

@ -12,7 +12,8 @@
"dev": "yarn run serve", "dev": "yarn run serve",
"build": "vue-cli-service build", "build": "vue-cli-service build",
"lint": "eslint --ext .js,.vue .", "lint": "eslint --ext .js,.vue .",
"test": "jest --coverage" "test": "jest --coverage",
"locales": "scripts/missing-keys.sh && scripts/sort.sh"
}, },
"dependencies": { "dependencies": {
"@babel/core": "^7.15.8", "@babel/core": "^7.15.8",

17
admin/scripts/missing-keys.sh Executable file
View File

@ -0,0 +1,17 @@
#!/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

25
admin/scripts/sort.sh Executable file
View File

@ -0,0 +1,25 @@
#!/bin/bash
ROOT_DIR=$(dirname "$0")/..
tmp=$(mktemp)
exit_code=0
for locale_file in $ROOT_DIR/src/locales/*.json
do
jq -f $(dirname "$0")/sort_filter.jq $locale_file > "$tmp"
if [ "$*" == "--fix" ]
then
mv "$tmp" $locale_file
else
if diff -q "$tmp" $locale_file > /dev/null ;
then
: # all good
else
exit_code=$?
echo "$(basename -- $locale_file) is not sorted by keys"
fi
fi
done
exit $exit_code

View File

@ -0,0 +1,13 @@
def walk(f):
. as $in
| if type == "object" then
reduce keys_unsorted[] as $key
( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f
elif type == "array" then map( walk(f) ) | f
else f
end;
def keys_sort_by(f):
to_entries | sort_by(.key|f ) | from_entries;
walk(if type == "object" then keys_sort_by(ascii_upcase) else . end)

View File

@ -171,14 +171,17 @@ export default {
currentMonth: { currentMonth: {
short: this.$moment().format('MMMM'), short: this.$moment().format('MMMM'),
long: this.$moment().format('YYYY-MM-DD'), long: this.$moment().format('YYYY-MM-DD'),
year: this.$moment().format('YYYY'),
}, },
lastMonth: { lastMonth: {
short: this.$moment().subtract(1, 'month').format('MMMM'), short: this.$moment().subtract(1, 'month').format('MMMM'),
long: this.$moment().subtract(1, 'month').format('YYYY-MM') + '-01', long: this.$moment().subtract(1, 'month').format('YYYY-MM') + '-01',
year: this.$moment().subtract(1, 'month').format('YYYY'),
}, },
beforeLastMonth: { beforeLastMonth: {
short: this.$moment().subtract(2, 'month').format('MMMM'), short: this.$moment().subtract(2, 'month').format('MMMM'),
long: this.$moment().subtract(2, 'month').format('YYYY-MM') + '-01', long: this.$moment().subtract(2, 'month').format('YYYY-MM') + '-01',
year: this.$moment().subtract(2, 'month').format('YYYY'),
}, },
submitObj: null, submitObj: null,
isdisabled: true, isdisabled: true,
@ -190,6 +193,7 @@ export default {
// Auswählen eines Zeitraumes // Auswählen eines Zeitraumes
updateRadioSelected(name, index, openCreation) { updateRadioSelected(name, index, openCreation) {
this.createdIndex = index this.createdIndex = index
this.text = 'Schöpfung für ' + name.short + ' ' + name.year
// Wenn Mehrfachschöpfung // Wenn Mehrfachschöpfung
if (this.type === 'massCreation') { if (this.type === 'massCreation') {
// An Creation.vue emitten und radioSelectedMass aktualisieren // An Creation.vue emitten und radioSelectedMass aktualisieren

View File

@ -36,6 +36,10 @@
hover hover
stacked="md" stacked="md"
> >
<template #cell(creation)="data">
<div v-html="data.value"></div>
</template>
<template #cell(edit_creation)="row"> <template #cell(edit_creation)="row">
<b-button variant="info" size="md" @click="rowToogleDetails(row, 0)" class="mr-2"> <b-button variant="info" size="md" @click="rowToogleDetails(row, 0)" class="mr-2">
<b-icon :icon="row.detailsShowing ? 'x' : 'pencil-square'" aria-label="Help"></b-icon> <b-icon :icon="row.detailsShowing ? 'x' : 'pencil-square'" aria-label="Help"></b-icon>

View File

@ -4,7 +4,7 @@ import VueI18n from 'vue-i18n'
Vue.use(VueI18n) Vue.use(VueI18n)
const loadLocaleMessages = () => { const loadLocaleMessages = () => {
const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i) const locales = require.context('./locales/', true, /[A-Za-z0-9-_,\s]+\.json$/i)
const messages = {} const messages = {}
locales.keys().forEach((key) => { locales.keys().forEach((key) => {
const matched = key.match(/([A-Za-z0-9-_]+)\./i) const matched = key.match(/([A-Za-z0-9-_]+)\./i)

View File

@ -1 +1,4 @@
{} {
"not_open_creations": "keine offene Schöpfungen",
"open_creations": "offene Schöpfungen"
}

View File

@ -1 +1,4 @@
{} {
"not_open_creations": "No open creations",
"open_creations": "Open creations"
}

View File

@ -0,0 +1,16 @@
const locales = [
{
name: 'English',
code: 'en',
iso: 'en-US',
enabled: true,
},
{
name: 'Deutsch',
code: 'de',
iso: 'de-DE',
enabled: true,
},
]
export default locales

View File

@ -31,6 +31,7 @@ const mocks = {
openCreations: 2, openCreations: 2,
}, },
}, },
$t: jest.fn((t) => t),
} }
describe('Overview', () => { describe('Overview', () => {

View File

@ -3,7 +3,7 @@
<b-card <b-card
v-show="$store.state.openCreations > 0" v-show="$store.state.openCreations > 0"
border-variant="primary" border-variant="primary"
header="offene Schöpfungen" :header="$t('open_creations')"
header-bg-variant="danger" header-bg-variant="danger"
header-text-variant="white" header-text-variant="white"
align="center" align="center"
@ -17,7 +17,7 @@
<b-card <b-card
v-show="$store.state.openCreations < 1" v-show="$store.state.openCreations < 1"
border-variant="success" border-variant="success"
header="keine offene Schöpfungen" :header="$t('not_open_creations')"
header-bg-variant="success" header-bg-variant="success"
header-text-variant="white" header-text-variant="white"
align="center" align="center"

View File

@ -26,6 +26,16 @@ const mocks = {
$toasted: { $toasted: {
error: toastErrorMock, error: toastErrorMock,
}, },
$moment: jest.fn(() => {
return {
format: jest.fn((m) => m),
subtract: jest.fn(() => {
return {
format: jest.fn((m) => m),
}
}),
}
}),
} }
describe('UserSearch', () => { describe('UserSearch', () => {

View File

@ -1,5 +1,11 @@
<template> <template>
<div class="user-search"> <div class="user-search">
<div style="text-align: right">
<b-button block variant="danger" @click="unconfirmedRegisterMails">
<b-icon icon="envelope" variant="light"></b-icon>
Anzeigen aller nicht registrierten E-Mails.
</b-button>
</div>
<label>Usersuche</label> <label>Usersuche</label>
<b-input <b-input
type="text" type="text"
@ -15,12 +21,7 @@
:fieldsTable="fields" :fieldsTable="fields"
:criteria="criteria" :criteria="criteria"
/> />
<div> <div></div>
<b-button block variant="danger" @click="unconfirmedRegisterMails">
<b-icon icon="envelope" variant="light"></b-icon>
Anzeigen aller nicht registrierten E-Mails.
</b-button>
</div>
</div> </div>
</template> </template>
<script> <script>
@ -41,9 +42,27 @@ export default {
{ key: 'lastName', label: 'Lastname' }, { key: 'lastName', label: 'Lastname' },
{ {
key: 'creation', key: 'creation',
label: 'Creation', label: 'Open creations',
formatter: (value, key, item) => { formatter: (value, key, item) => {
return String(value) return (
`
<div>` +
this.$moment().subtract(2, 'month').format('MMMM') +
` - ` +
String(value[0]) +
` GDD</div>
<div>` +
this.$moment().subtract(1, 'month').format('MMMM') +
` - ` +
String(value[1]) +
` GDD</div>
<div>` +
this.$moment().format('MMMM') +
` - ` +
String(value[2]) +
` GDD</div>
`
)
}, },
}, },
{ key: 'show_details', label: 'Details' }, { key: 'show_details', label: 'Details' },
@ -53,6 +72,15 @@ export default {
searchResult: [], searchResult: [],
massCreation: [], massCreation: [],
criteria: '', criteria: '',
currentMonth: {
short: this.$moment().format('MMMM'),
},
lastMonth: {
short: this.$moment().subtract(1, 'month').format('MMMM'),
},
beforeLastMonth: {
short: this.$moment().subtract(2, 'month').format('MMMM'),
},
} }
}, },