improve profile page #36
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
weeman 2021-10-24 18:16:19 +02:00
parent 016a1bd959
commit 6ecf80f34c
Signed by: weeman
GPG Key ID: 34F0524D4DA694A1
7 changed files with 127 additions and 83 deletions

44
package-lock.json generated
View File

@ -21,6 +21,7 @@
"eslint-plugin-vue": "^7.0.0", "eslint-plugin-vue": "^7.0.0",
"sass": "^1.37.5", "sass": "^1.37.5",
"sass-loader": "^10.2.0", "sass-loader": "^10.2.0",
"v-tooltip": "^4.0.0-alpha.1",
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-router": "^4.0.0-0", "vue-router": "^4.0.0-0",
"vuex": "^4.0.2" "vuex": "^4.0.2"
@ -1215,7 +1216,6 @@
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.1.tgz", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.1.tgz",
"integrity": "sha512-HnUhk1Sy9IuKrxEMdIRCxpIqPw6BFsbYSEUO9p/hNw5sMld/+3OLMWQP80F8/db9qsv3qUjs7ZR5bS/R+iinXw==", "integrity": "sha512-HnUhk1Sy9IuKrxEMdIRCxpIqPw6BFsbYSEUO9p/hNw5sMld/+3OLMWQP80F8/db9qsv3qUjs7ZR5bS/R+iinXw==",
"dev": true, "dev": true,
"peer": true,
"funding": { "funding": {
"type": "opencollective", "type": "opencollective",
"url": "https://opencollective.com/popperjs" "url": "https://opencollective.com/popperjs"
@ -13008,6 +13008,19 @@
"uuid": "bin/uuid" "uuid": "bin/uuid"
} }
}, },
"node_modules/v-tooltip": {
"version": "4.0.0-alpha.1",
"resolved": "https://registry.npmjs.org/v-tooltip/-/v-tooltip-4.0.0-alpha.1.tgz",
"integrity": "sha512-TTNLJ/IVyoburxW0M3gxHhRb+d18xbozI5c0q2LCqIw4YUZzLKCG0ufx72d+j/1Xkqam9kDNHZChZq4KfsVpvw==",
"dev": true,
"dependencies": {
"@popperjs/core": "^2.6.0",
"vue-resize": "^2.0.0-alpha.1"
},
"peerDependencies": {
"vue": "^3.0.11"
}
},
"node_modules/v8-compile-cache": { "node_modules/v8-compile-cache": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npm.taobao.org/v8-compile-cache/download/v8-compile-cache-2.3.0.tgz?cache=0&sync_timestamp=1614993892777&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fv8-compile-cache%2Fdownload%2Fv8-compile-cache-2.3.0.tgz", "resolved": "https://registry.npm.taobao.org/v8-compile-cache/download/v8-compile-cache-2.3.0.tgz?cache=0&sync_timestamp=1614993892777&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fv8-compile-cache%2Fdownload%2Fv8-compile-cache-2.3.0.tgz",
@ -13225,6 +13238,15 @@
"integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
"dev": true "dev": true
}, },
"node_modules/vue-resize": {
"version": "2.0.0-alpha.1",
"resolved": "https://registry.npmjs.org/vue-resize/-/vue-resize-2.0.0-alpha.1.tgz",
"integrity": "sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg==",
"dev": true,
"peerDependencies": {
"vue": "^3.0.0"
}
},
"node_modules/vue-router": { "node_modules/vue-router": {
"version": "4.0.8", "version": "4.0.8",
"resolved": "https://registry.nlark.com/vue-router/download/vue-router-4.0.8.tgz", "resolved": "https://registry.nlark.com/vue-router/download/vue-router-4.0.8.tgz",
@ -15574,8 +15596,7 @@
"version": "2.10.1", "version": "2.10.1",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.1.tgz", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.1.tgz",
"integrity": "sha512-HnUhk1Sy9IuKrxEMdIRCxpIqPw6BFsbYSEUO9p/hNw5sMld/+3OLMWQP80F8/db9qsv3qUjs7ZR5bS/R+iinXw==", "integrity": "sha512-HnUhk1Sy9IuKrxEMdIRCxpIqPw6BFsbYSEUO9p/hNw5sMld/+3OLMWQP80F8/db9qsv3qUjs7ZR5bS/R+iinXw==",
"dev": true, "dev": true
"peer": true
}, },
"@soda/friendly-errors-webpack-plugin": { "@soda/friendly-errors-webpack-plugin": {
"version": "1.8.0", "version": "1.8.0",
@ -25577,6 +25598,16 @@
"integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=", "integrity": "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4=",
"dev": true "dev": true
}, },
"v-tooltip": {
"version": "4.0.0-alpha.1",
"resolved": "https://registry.npmjs.org/v-tooltip/-/v-tooltip-4.0.0-alpha.1.tgz",
"integrity": "sha512-TTNLJ/IVyoburxW0M3gxHhRb+d18xbozI5c0q2LCqIw4YUZzLKCG0ufx72d+j/1Xkqam9kDNHZChZq4KfsVpvw==",
"dev": true,
"requires": {
"@popperjs/core": "^2.6.0",
"vue-resize": "^2.0.0-alpha.1"
}
},
"v8-compile-cache": { "v8-compile-cache": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npm.taobao.org/v8-compile-cache/download/v8-compile-cache-2.3.0.tgz?cache=0&sync_timestamp=1614993892777&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fv8-compile-cache%2Fdownload%2Fv8-compile-cache-2.3.0.tgz", "resolved": "https://registry.npm.taobao.org/v8-compile-cache/download/v8-compile-cache-2.3.0.tgz?cache=0&sync_timestamp=1614993892777&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fv8-compile-cache%2Fdownload%2Fv8-compile-cache-2.3.0.tgz",
@ -25769,6 +25800,13 @@
} }
} }
}, },
"vue-resize": {
"version": "2.0.0-alpha.1",
"resolved": "https://registry.npmjs.org/vue-resize/-/vue-resize-2.0.0-alpha.1.tgz",
"integrity": "sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg==",
"dev": true,
"requires": {}
},
"vue-router": { "vue-router": {
"version": "4.0.8", "version": "4.0.8",
"resolved": "https://registry.nlark.com/vue-router/download/vue-router-4.0.8.tgz", "resolved": "https://registry.nlark.com/vue-router/download/vue-router-4.0.8.tgz",

View File

@ -20,6 +20,7 @@
"eslint-plugin-vue": "^7.0.0", "eslint-plugin-vue": "^7.0.0",
"sass": "^1.37.5", "sass": "^1.37.5",
"sass-loader": "^10.2.0", "sass-loader": "^10.2.0",
"v-tooltip": "^4.0.0-alpha.1",
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-router": "^4.0.0-0", "vue-router": "^4.0.0-0",
"vuex": "^4.0.2" "vuex": "^4.0.2"

View File

@ -9,25 +9,42 @@ SPDX-License-Identifier: AGPL-3.0-or-later
:values="values" :values="values"
:type="type" :type="type"
:editable="true" :editable="true"
:show-secondary="showSecondary"
@remove-value="removeValue($event)" @remove-value="removeValue($event)"
@update-values="this.$emit('update-values', this.values)" @update-values="this.$emit('update-values', this.values)"
> >
</profile-list> </profile-list>
<div v-bind="$attrs" class="card-body"> <div v-bind="$attrs" class="card-body">
<div class="row"> <div class="row">
<div class="col"> <div class="col-12 col-md-4 col-lg-3 col-xl-2">
<div class="form-control-plaintext form-control-sm">Eintrag hinzufügen:</div>
</div>
<div class="col-12 col-md-6">
<input <input
autocomplete="off" autocomplete="off"
type="text" type="text"
class="form-control" class="form-control form-control-sm"
id="searchText" id="searchText"
maxlength="25" maxlength="25"
:placeholder="placeholder"
v-model="searchText" v-model="searchText"
@input="search()" @input="search()"
@keyup.enter="addResult()" @keyup.enter="addResult()"
/> />
<div v-if="searchResults">
<ul class="list-group">
<li
class="list-group-item"
v-for="result in searchResults"
:key="result.id"
@click="addResult(result)"
>
{{ result.name }}
</li>
</ul>
</div>
</div> </div>
<div class="col"> <div class="col-md-2">
<button <button
v-if="searchText != ''" v-if="searchText != ''"
type="button" type="button"
@ -40,18 +57,6 @@ SPDX-License-Identifier: AGPL-3.0-or-later
</button> </button>
</div> </div>
</div> </div>
<div v-if="searchResults">
<ul class="list-group">
<li
class="list-group-item"
v-for="result in searchResults"
:key="result.id"
@click="addResult(result)"
>
{{ result.name }}
</li>
</ul>
</div>
</div> </div>
</template> </template>
<script> <script>
@ -76,6 +81,14 @@ export default {
values: { values: {
type: Array, type: Array,
}, },
showSecondary: {
type: Boolean,
default: true,
},
placeholder: {
type: String,
default: "",
},
}, },
data() { data() {
return { return {

View File

@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
:key="value.id" :key="value.id"
> >
<div class="row"> <div class="row">
<div class="col d-flex align-items-center"> <div class="col-12 col-md-5 d-flex align-items-center">
<div <div
class="list-icon me-1" class="list-icon me-1"
:style="{ backgroundImage: `url('${iconBaseUrl + value[type].icon_url}'` }" :style="{ backgroundImage: `url('${iconBaseUrl + value[type].icon_url}'` }"
@ -22,70 +22,49 @@ SPDX-License-Identifier: AGPL-3.0-or-later
{{ value[type].name }} {{ value[type].name }}
</div> </div>
</div> </div>
<div class="col"> <div class="col-10 col-md-5">
<div v-if="type == 'skill'"> <div v-if="type == 'skill' && showSecondary">
<div v-if="editable"> <select
<select class="form-select form-select-sm"
v-if="editableValues[valueKey]" aria-label="Selektiere dein Level"
class="form-select form-select-sm" v-model="editableValues[valueKey].level"
aria-label="Selektiere dein Level" @input="$emit('update-values', editableValues)"
v-model="editableValues[valueKey].level" >
@input="$emit('update-values', editableValues)" <option
v-for="(value, key) in levelSelection"
:value="key"
:key="key"
> >
<option {{ value.long || value }}
v-for="(value, key) in levelSelection" </option>
:value="key" </select>
:key="key"
>
{{ value.long || value }}
</option>
</select>
</div>
<div v-else><span v-if="value.level">({{ levelSelection[value.level] }})</span></div>
</div> </div>
<div v-else-if="type == 'language'"> <div v-else-if="type == 'language'">
<div v-if="editable"> <select
<div v-if="editable"> class="form-select form-select-sm"
<select aria-label="Selektiere dein Level"
v-if="editableValues[valueKey]" v-model="editableValues[valueKey].level"
class="form-select form-select-sm" @input="$emit('update-values', editableValues)"
aria-label="Selektiere dein Level" >
v-model="editableValues[valueKey].level" <option
@input="$emit('update-values', editableValues)" v-for="(value, key) in languagesSelection"
> :value="key"
<option :key="key"
v-for="(value, key) in languagesSelection" >
:value="key" {{ value }}
:key="key" </option>
> </select>
{{ value }}
</option>
</select>
</div>
</div>
<div v-else><span v-if="value.level">({{languagesSelection[value.level]}})</span></div>
</div> </div>
<div v-else-if="type == 'contacttype'"> <div v-else-if="type == 'contacttype'">
<div v-if="editable"> <input
<input class="form-control form-control-sm"
class="form-control form-control-sm" maxlength="200"
maxlength="200" v-model="editableValues[valueKey].content"
v-model="editableValues[valueKey].content" />
/>
</div>
<div v-else>
<span v-if="value[type].name === 'E-Mail'">
<a :href="`mailto:${value.content}`">{{ value.content }}</a>
</span>
<span v-else>
{{ value.content }}
</span>
</div>
</div> </div>
</div> </div>
<div class="col text-end"> <div class="col-2 text-end">
<button <button
v-if="editable"
type="button" type="button"
class="btn btn-sm btn-light" class="btn btn-sm btn-light"
aria-label="Löschen" aria-label="Löschen"
@ -112,10 +91,10 @@ export default {
type: Array, type: Array,
required: true, required: true,
}, },
editable: { showSecondary: {
type: Boolean, type: Boolean,
default: false, default: true
}, }
}, },
data() { data() {
return { return {

View File

@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<template> <template>
<div class="skill rounded me-2"> <div class="skill rounded me-2">
<div class="skill__left px-2"> <div class="skill__left p-2">
<div class="skill__icon" :style="{ backgroundImage: iconUrl }"></div> <div class="skill__icon" :style="{ backgroundImage: iconUrl }"></div>
</div> </div>
<div class="skill__right d-flex align-items-center rounded-end px-2"> <div class="skill__right d-flex align-items-center rounded-end px-2">

View File

@ -6,12 +6,15 @@ import { createApp } from 'vue/dist/vue.esm-bundler'
import App from './App.vue' import App from './App.vue'
import router from './router' import router from './router'
import store from '@/store' import store from '@/store'
import VTooltipPlugin from 'v-tooltip'
import 'v-tooltip/dist/v-tooltip.css'
import 'bootstrap-icons/font/bootstrap-icons.css' import 'bootstrap-icons/font/bootstrap-icons.css'
import './assets/global.scss' import './assets/global.scss'
const app = createApp(App) const app = createApp(App)
app.use(VTooltipPlugin)
app.use(router) app.use(router)
app.use(store) app.use(store)

View File

@ -46,7 +46,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<div class="col-6 mb-3"> <div class="col-6 mb-3">
<label class="form-label"> <label class="form-label">
Pronomen Pronomen
<i class="bi bi-info-circle" title="ToDo: Tooltip"></i> <i class="bi bi-info-circle" v-tooltip="pronounsTooltip"></i>
</label> </label>
<input <input
type="text" type="text"
@ -60,7 +60,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<label class="form-label">Anschrift</label> <label class="form-label">Anschrift</label>
<div class="row"> <div class="row">
<div class="col-4"> <div class="col-12 col-md-4 mb-3 mb-md-0">
<input <input
type="text" type="text"
class="form-control" class="form-control"
@ -70,7 +70,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
v-model="profile.address.postcode" v-model="profile.address.postcode"
/> />
</div> </div>
<div class="col-4"> <div class="col-12 col-md-4 mb-3 mb-md-0">
<input <input
type="text" type="text"
class="form-control" class="form-control"
@ -80,7 +80,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
v-model="profile.address.city" v-model="profile.address.city"
/> />
</div> </div>
<div class="col-4"> <div class="col-12 col-md-4">
<input <input
type="text" type="text"
class="form-control" class="form-control"
@ -98,6 +98,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<auto-complete <auto-complete
type="skill" type="skill"
:values="profile.skills" :values="profile.skills"
placeholder="z.B. Python, JavaScript, Linux"
@update-values="profile.skills = $event" @update-values="profile.skills = $event"
></auto-complete> ></auto-complete>
</template> </template>
@ -108,6 +109,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<auto-complete <auto-complete
type="language" type="language"
:values="profile.languages" :values="profile.languages"
placeholder="z.B. Deutsch, Englisch, Französisch"
@update-values="profile.languages = $event" @update-values="profile.languages = $event"
></auto-complete> ></auto-complete>
</template> </template>
@ -119,6 +121,8 @@ SPDX-License-Identifier: AGPL-3.0-or-later
type="skill" type="skill"
label="Ich suche" label="Ich suche"
:values="profile.searchtopics" :values="profile.searchtopics"
:showSecondary="false"
placeholder="z.B. Python, JavaScript, Linux"
@update-values="profile.searchtopics = $event" @update-values="profile.searchtopics = $event"
></auto-complete> ></auto-complete>
</template> </template>
@ -153,6 +157,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
class="form-control" class="form-control"
id="availability" id="availability"
rows="3" rows="3"
maxlength="4000"
v-model="profile.availability_text" v-model="profile.availability_text"
></textarea> ></textarea>
</Section> </Section>
@ -162,6 +167,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<auto-complete <auto-complete
type="contacttype" type="contacttype"
:values="profile.contacts" :values="profile.contacts"
placeholder="z.B. E-Mail, Mobiltelefon, Matrix, Web"
@update-values="profile.contacts = $event" @update-values="profile.contacts = $event"
></auto-complete> ></auto-complete>
</template> </template>
@ -253,6 +259,10 @@ export default {
searchtopics: [], searchtopics: [],
contacts: [], contacts: [],
}, },
pronounsTooltip: {
content: 'Wie möchtest du angesprochen werden?<br>Zum Beispiel "er/ihn" oder "sie/ihre".',
html: true
}
}; };
}, },
async created() { async created() {