make indentation consistent
This commit is contained in:
parent
d52575aa42
commit
9f63414ba2
27 changed files with 858 additions and 804 deletions
|
@ -1,7 +1,7 @@
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*.js]
|
[*.js]
|
||||||
indent_size = 2
|
indent_size = 4
|
||||||
|
|
||||||
[*.vue]
|
[*.vue]
|
||||||
indent_size = 2
|
indent_size = 4
|
|
@ -17,8 +17,7 @@ module.exports = {
|
||||||
'rules': {
|
'rules': {
|
||||||
"no-console": "off",
|
"no-console": "off",
|
||||||
'indent': [
|
'indent': [
|
||||||
'error',
|
'error', 4
|
||||||
2
|
|
||||||
],
|
],
|
||||||
'linebreak-style': [
|
'linebreak-style': [
|
||||||
'off',
|
'off',
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
<title>c3cloc</title>
|
<title>c3cloc</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>
|
<noscript>
|
||||||
<strong>We're sorry but c3cloc doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
<strong>We're sorry but c3cloc doesn't work properly without JavaScript enabled. Please enable it to
|
||||||
</noscript>
|
continue.</strong>
|
||||||
<div id="app"></div>
|
</noscript>
|
||||||
<!-- built files will be auto injected -->
|
<div id="app"></div>
|
||||||
</body>
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
<div aria-live="polite" aria-atomic="true"
|
<div aria-live="polite" aria-atomic="true"
|
||||||
class="d-flex justify-content-end align-items-start fixed-top mx-1 my-5 py-3"
|
class="d-flex justify-content-end align-items-start fixed-top mx-1 my-5 py-3"
|
||||||
style="min-height: 200px; z-index: 100000; pointer-events: none">
|
style="min-height: 200px; z-index: 100000; pointer-events: none">
|
||||||
<Toast v-for="toast in toasts" :key="toast" :title="toast.title" :message="toast.message" :color="toast.color"
|
<Toast v-for="toast in toasts" :key="toast" :title="toast.title" :message="toast.message"
|
||||||
|
:color="toast.color"
|
||||||
@close="removeToast(toast.key)" style="pointer-events: auto"/>
|
@close="removeToast(toast.key)" style="pointer-events: auto"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -18,7 +18,7 @@ import EditItem from '@/components/EditItem';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AddItemModal',
|
name: 'AddItemModal',
|
||||||
components: { Modal, EditItem },
|
components: {Modal, EditItem},
|
||||||
props: ['isModal'],
|
props: ['isModal'],
|
||||||
data: () => ({
|
data: () => ({
|
||||||
item: {}
|
item: {}
|
||||||
|
|
|
@ -55,12 +55,18 @@ export default {
|
||||||
name: 'Cards',
|
name: 'Cards',
|
||||||
mixins: [DataContainer],
|
mixins: [DataContainer],
|
||||||
created() {
|
created() {
|
||||||
this.columns.map(e => ({k: e, v: this.$store.getters.getFilters[e]})).filter(e => e.v).forEach(e => this.setFilter(e.k, e.v));
|
this.columns.map(e => ({
|
||||||
|
k: e,
|
||||||
|
v: this.$store.getters.getFilters[e]
|
||||||
|
})).filter(e => e.v).forEach(e => this.setFilter(e.k, e.v));
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
changeFilter(col, val) {
|
changeFilter(col, val) {
|
||||||
this.setFilter(col, val);
|
this.setFilter(col, val);
|
||||||
let newquery = Object.entries({...this.$store.getters.getFilters, [col]: val}).reduce((a,[k,v]) => (v ? {...a, [k]:v} : a), {});
|
let newquery = Object.entries({
|
||||||
|
...this.$store.getters.getFilters,
|
||||||
|
[col]: val
|
||||||
|
}).reduce((a, [k, v]) => (v ? {...a, [k]: v} : a), {});
|
||||||
router.push({query: newquery});
|
router.push({query: newquery});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -25,16 +25,16 @@
|
||||||
<script>
|
<script>
|
||||||
import InputString from './inputs/InputString';
|
import InputString from './inputs/InputString';
|
||||||
import InputCombo from './inputs/InputCombo';
|
import InputCombo from './inputs/InputCombo';
|
||||||
import { mapGetters } from 'vuex';
|
import {mapGetters} from 'vuex';
|
||||||
import InputPhoto from './inputs/InputPhoto';
|
import InputPhoto from './inputs/InputPhoto';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'EditItem',
|
name: 'EditItem',
|
||||||
components: {InputPhoto, InputCombo, InputString },
|
components: {InputPhoto, InputCombo, InputString},
|
||||||
props: ['item'],
|
props: ['item'],
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(['getBoxes']),
|
...mapGetters(['getBoxes']),
|
||||||
boxes({ getBoxes }) {
|
boxes({getBoxes}) {
|
||||||
return getBoxes.map(obj => ({cid: obj.cid, box: obj.name}));
|
return getBoxes.map(obj => ({cid: obj.cid, box: obj.name}));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,17 +20,17 @@ import config from '../config';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Lightbox',
|
name: 'Lightbox',
|
||||||
components: { Modal },
|
components: {Modal},
|
||||||
props: ['file'],
|
props: ['file'],
|
||||||
data: ()=>({
|
data: () => ({
|
||||||
baseUrl: config.service.url,
|
baseUrl: config.service.url,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#lightbox-image {
|
#lightbox-image {
|
||||||
max-height: 75vh;
|
max-height: 75vh;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
|
@ -38,38 +38,38 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.modal {
|
.modal {
|
||||||
background-color: rgba(0,0,0,0.4); /* Transparent dimmed overlay */
|
background-color: rgba(0, 0, 0, 0.4); /* Transparent dimmed overlay */
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: table !important;
|
display: table !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal.hidden {
|
.modal.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal .container {
|
.modal .container {
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal .body {
|
.modal .body {
|
||||||
box-shadow: 5px 10px #888888;
|
box-shadow: 5px 10px #888888;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hacky Fix, for this Issue: https://hannover.ccc.de/gitlab/c3lf/lffrontend/issues/26 */
|
/* Hacky Fix, for this Issue: https://hannover.ccc.de/gitlab/c3lf/lffrontend/issues/26 */
|
||||||
/*.modal-body {
|
/*.modal-body {
|
||||||
max-height: calc(100vh - 200px);
|
max-height: calc(100vh - 200px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}*/
|
}*/
|
||||||
</style>
|
</style>
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button class="btn text-light dropdown-toggle btn-heading" type="button" id="dropdownMenuButton"
|
<button class="btn text-light dropdown-toggle btn-heading" type="button" id="dropdownMenuButton"
|
||||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
{{getEventSlug}}
|
{{ getEventSlug }}
|
||||||
</button>
|
</button>
|
||||||
<div class="dropdown-menu bg-dark" aria-labelledby="dropdownMenuButton">
|
<div class="dropdown-menu bg-dark" aria-labelledby="dropdownMenuButton">
|
||||||
<a class="dropdown-item text-light" href="#" v-for="(event, index) in events" v-bind:key="index"
|
<a class="dropdown-item text-light" href="#" v-for="(event, index) in events" v-bind:key="index"
|
||||||
|
@ -13,7 +13,8 @@
|
||||||
|
|
||||||
<div class="custom-control-inline mr-1">
|
<div class="custom-control-inline mr-1">
|
||||||
<button type="button" class="btn mx-1 text-nowrap btn-success" @click="$emit('addClicked')">
|
<button type="button" class="btn mx-1 text-nowrap btn-success" @click="$emit('addClicked')">
|
||||||
<font-awesome-icon icon="plus"/><span class="d-none d-md-inline"> Add</span>
|
<font-awesome-icon icon="plus"/>
|
||||||
|
<span class="d-none d-md-inline"> Add</span>
|
||||||
</button>
|
</button>
|
||||||
<div class="btn-group btn-group-toggle">
|
<div class="btn-group btn-group-toggle">
|
||||||
<button :class="['btn', 'btn-info', { active: layout === 'cards' }]" @click="setLayout('cards')">
|
<button :class="['btn', 'btn-info', { active: layout === 'cards' }]" @click="setLayout('cards')">
|
||||||
|
@ -47,10 +48,11 @@
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<button class="btn nav-link dropdown-toggle" type="button" id="dropdownMenuButton2"
|
<button class="btn nav-link dropdown-toggle" type="button" id="dropdownMenuButton2"
|
||||||
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
{{getActiveView}}
|
{{ getActiveView }}
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu bg-dark" aria-labelledby="dropdownMenuButton2">
|
<ul class="dropdown-menu bg-dark" aria-labelledby="dropdownMenuButton2">
|
||||||
<li class="" v-for="(link, index) in views" v-bind:key="index" :class="{ active: link.path === getActiveView }">
|
<li class="" v-for="(link, index) in views" v-bind:key="index"
|
||||||
|
:class="{ active: link.path === getActiveView }">
|
||||||
<a class="nav-link text-nowrap" href="#" @click="changeView(link)">{{ link.title }}</a>
|
<a class="nav-link text-nowrap" href="#" @click="changeView(link)">{{ link.title }}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -66,18 +68,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapState, mapActions, mapMutations, mapGetters } from 'vuex';
|
import {mapState, mapActions, mapMutations, mapGetters} from 'vuex';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Navbar',
|
name: 'Navbar',
|
||||||
data: () => ({
|
data: () => ({
|
||||||
views: [
|
views: [
|
||||||
{'title':'items','path':'items'},
|
{'title': 'items', 'path': 'items'},
|
||||||
{'title':'boxes','path':'boxes'},
|
{'title': 'boxes', 'path': 'boxes'},
|
||||||
//{'title':'mass-edit','path':'massedit'},
|
//{'title':'mass-edit','path':'massedit'},
|
||||||
],
|
],
|
||||||
links: [
|
links: [
|
||||||
{'title':'howto engel','path':'/howto/'}
|
{'title': 'howto engel', 'path': '/howto/'}
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -85,12 +87,12 @@ export default {
|
||||||
...mapGetters(['getEventSlug', 'getActiveView']),
|
...mapGetters(['getEventSlug', 'getActiveView']),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['changeEvent', 'changeView','searchEventItems']),
|
...mapActions(['changeEvent', 'changeView', 'searchEventItems']),
|
||||||
...mapMutations(['setLayout'])
|
...mapMutations(['setLayout'])
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "../scss/navbar.scss";
|
@import "../scss/navbar.scss";
|
||||||
</style>
|
</style>
|
|
@ -46,12 +46,18 @@ export default {
|
||||||
name: 'Table',
|
name: 'Table',
|
||||||
mixins: [DataContainer],
|
mixins: [DataContainer],
|
||||||
created() {
|
created() {
|
||||||
this.columns.map(e => ({k: e, v: this.$store.getters.getFilters[e]})).filter(e => e.v).forEach(e => this.setFilter(e.k, e.v));
|
this.columns.map(e => ({
|
||||||
|
k: e,
|
||||||
|
v: this.$store.getters.getFilters[e]
|
||||||
|
})).filter(e => e.v).forEach(e => this.setFilter(e.k, e.v));
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
changeFilter(col, val) {
|
changeFilter(col, val) {
|
||||||
this.setFilter(col, val);
|
this.setFilter(col, val);
|
||||||
let newquery = Object.entries({...this.$store.getters.getFilters, [col]: val}).reduce((a,[k,v]) => (v ? {...a, [k]:v} : a), {});
|
let newquery = Object.entries({
|
||||||
|
...this.$store.getters.getFilters,
|
||||||
|
[col]: val
|
||||||
|
}).reduce((a, [k, v]) => (v ? {...a, [k]: v} : a), {});
|
||||||
router.push({query: newquery});
|
router.push({query: newquery});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -59,7 +65,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.table-body-move {
|
.table-body-move {
|
||||||
transition: transform 1s;
|
transition: transform 1s;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
|
@ -14,7 +14,7 @@
|
||||||
<script>
|
<script>
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import 'bootstrap/js/dist/toast';
|
import 'bootstrap/js/dist/toast';
|
||||||
import { DateTime } from 'luxon';
|
import {DateTime} from 'luxon';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Toast',
|
name: 'Toast',
|
||||||
|
@ -25,13 +25,13 @@ export default {
|
||||||
timer: undefined
|
timer: undefined
|
||||||
}),
|
}),
|
||||||
mounted() {
|
mounted() {
|
||||||
const { toast } = this.$refs;
|
const {toast} = this.$refs;
|
||||||
$(toast).toast('show');
|
$(toast).toast('show');
|
||||||
this.timer = setInterval(this.updateDisplayTime, 1000);
|
this.timer = setInterval(this.updateDisplayTime, 1000);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
close() {
|
close() {
|
||||||
const { toast } = this.$refs;
|
const {toast} = this.$refs;
|
||||||
$(toast).toast('hide');
|
$(toast).toast('hide');
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
this.$emit('close');
|
this.$emit('close');
|
||||||
|
|
|
@ -25,7 +25,7 @@ import 'bootstrap/js/dist/tooltip';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Addon',
|
name: 'Addon',
|
||||||
props: [ 'type', 'isValid' ],
|
props: ['type', 'isValid'],
|
||||||
mounted() {
|
mounted() {
|
||||||
$('[data-toggle="tooltip"]').tooltip();
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
class="btn btn-outline-secondary dropdown-toggle"
|
class="btn btn-outline-secondary dropdown-toggle"
|
||||||
type="button"
|
type="button"
|
||||||
data-toggle="dropdown"
|
data-toggle="dropdown"
|
||||||
>Search</button>
|
>Search
|
||||||
|
</button>
|
||||||
<div class="dropdown-menu">
|
<div class="dropdown-menu">
|
||||||
<a
|
<a
|
||||||
v-for="(option, index) in sortedOptions"
|
v-for="(option, index) in sortedOptions"
|
||||||
|
@ -42,20 +43,23 @@ import Addon from './Addon';
|
||||||
export default {
|
export default {
|
||||||
name: 'InputCombo',
|
name: 'InputCombo',
|
||||||
components: {Addon},
|
components: {Addon},
|
||||||
props: [ 'label', 'model', 'nameKey', 'uniqueKey', 'options', 'onOptionAdd' ],
|
props: ['label', 'model', 'nameKey', 'uniqueKey', 'options', 'onOptionAdd'],
|
||||||
data: ({ options, model, nameKey, uniqueKey }) => ({
|
data: ({options, model, nameKey, uniqueKey}) => ({
|
||||||
internalName: model[nameKey],
|
internalName: model[nameKey],
|
||||||
selectedOption: options.filter(e => e[uniqueKey] == model[uniqueKey])[0],
|
selectedOption: options.filter(e => e[uniqueKey] == model[uniqueKey])[0],
|
||||||
addingOption: false
|
addingOption: false
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
isValid: ({options, nameKey, internalName}) => options.some(e => e[nameKey] == internalName),
|
isValid: ({options, nameKey, internalName}) => options.some(e => e[nameKey] == internalName),
|
||||||
sortedOptions: ({options, nameKey}) => options.sort((a, b) => a[nameKey].localeCompare(b[nameKey], 'en', { numeric: true })),
|
sortedOptions: ({
|
||||||
|
options,
|
||||||
|
nameKey
|
||||||
|
}) => options.sort((a, b) => a[nameKey].localeCompare(b[nameKey], 'en', {numeric: true})),
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
internalName(newValue) {
|
internalName(newValue) {
|
||||||
if (this.isValid) {
|
if (this.isValid) {
|
||||||
if(!this.selectedOption || newValue!=this.selectedOption[this.nameKey]){
|
if (!this.selectedOption || newValue != this.selectedOption[this.nameKey]) {
|
||||||
this.selectedOption = this.options.filter(e => e[this.nameKey] === newValue)[0];
|
this.selectedOption = this.options.filter(e => e[this.nameKey] === newValue)[0];
|
||||||
}
|
}
|
||||||
this.model[this.nameKey] = this.selectedOption[this.nameKey];
|
this.model[this.nameKey] = this.selectedOption[this.nameKey];
|
||||||
|
|
|
@ -44,11 +44,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapMutations } from 'vuex';
|
import {mapMutations} from 'vuex';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'InputPhoto',
|
name: 'InputPhoto',
|
||||||
props: [ 'model', 'field', 'onCapture' ],
|
props: ['model', 'field', 'onCapture'],
|
||||||
data: () => ({
|
data: () => ({
|
||||||
capturing: false,
|
capturing: false,
|
||||||
streaming: false,
|
streaming: false,
|
||||||
|
@ -61,9 +61,9 @@ export default {
|
||||||
if (!this.capturing) {
|
if (!this.capturing) {
|
||||||
this.capturing = true;
|
this.capturing = true;
|
||||||
this.streaming = false;
|
this.streaming = false;
|
||||||
navigator.mediaDevices.getUserMedia({video: { facingMode: "environment" }, audio: false}).then(stream => {
|
navigator.mediaDevices.getUserMedia({video: {facingMode: "environment"}, audio: false}).then(stream => {
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
const { video } = this.$refs;
|
const {video} = this.$refs;
|
||||||
video.srcObject = stream;
|
video.srcObject = stream;
|
||||||
video.play();
|
video.play();
|
||||||
video.addEventListener('canplay', () => {
|
video.addEventListener('canplay', () => {
|
||||||
|
@ -73,9 +73,9 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
captureVideoImage() {
|
captureVideoImage() {
|
||||||
const { video, canvas } = this.$refs;
|
const {video, canvas} = this.$refs;
|
||||||
const context = canvas.getContext('2d');
|
const context = canvas.getContext('2d');
|
||||||
const { videoWidth, videoHeight } = video;
|
const {videoWidth, videoHeight} = video;
|
||||||
canvas.width = videoWidth;
|
canvas.width = videoWidth;
|
||||||
canvas.height = videoHeight;
|
canvas.height = videoHeight;
|
||||||
context.drawImage(video, 0, 0, videoWidth, videoHeight);
|
context.drawImage(video, 0, 0, videoWidth, videoHeight);
|
||||||
|
@ -90,7 +90,7 @@ export default {
|
||||||
this.streaming = false;
|
this.streaming = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onFileChange({ target }) {
|
onFileChange({target}) {
|
||||||
const file = target.files[0];
|
const file = target.files[0];
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
|
@ -101,7 +101,11 @@ export default {
|
||||||
self.closeStream();
|
self.closeStream();
|
||||||
};
|
};
|
||||||
reader.onerror = function (error) {
|
reader.onerror = function (error) {
|
||||||
this.createToast({ title: 'Error: Failed to parse image file', message: error.toString(), color: 'danger' });
|
this.createToast({
|
||||||
|
title: 'Error: Failed to parse image file',
|
||||||
|
message: error.toString(),
|
||||||
|
color: 'danger'
|
||||||
|
});
|
||||||
console.log('Error: ', error);
|
console.log('Error: ', error);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -117,7 +121,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.img-preview{
|
.img-preview {
|
||||||
max-height: 30vh;
|
max-height: 30vh;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
|
@ -14,13 +14,13 @@ import Addon from './Addon';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'InputString',
|
name: 'InputString',
|
||||||
components: { Addon },
|
components: {Addon},
|
||||||
props: [ 'label', 'model', 'field', 'validationFn' ],
|
props: ['label', 'model', 'field', 'validationFn'],
|
||||||
computed: {
|
computed: {
|
||||||
hasValidationFn({ validationFn }) {
|
hasValidationFn({validationFn}) {
|
||||||
return validationFn != undefined;
|
return validationFn != undefined;
|
||||||
},
|
},
|
||||||
isValid({ model, field, validationFn, hasValidationFn }) {
|
isValid({model, field, validationFn, hasValidationFn}) {
|
||||||
if (!hasValidationFn) return true;
|
if (!hasValidationFn) return true;
|
||||||
return validationFn(model[field]);
|
return validationFn(model[field]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import App from './App.vue';
|
import App from './App.vue';
|
||||||
import { sync } from 'vuex-router-sync';
|
import {sync} from 'vuex-router-sync';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import router from './router';
|
import router from './router';
|
||||||
|
|
||||||
|
@ -10,9 +10,28 @@ import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
import 'bootstrap/dist/js/bootstrap.min.js';
|
import 'bootstrap/dist/js/bootstrap.min.js';
|
||||||
|
|
||||||
// fontawesome
|
// fontawesome
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core';
|
import {library} from '@fortawesome/fontawesome-svg-core';
|
||||||
import { faPlus, faCheckCircle, faEdit, faTrash, faCat, faSyncAlt, faSort, faSortUp, faSortDown, faTh, faList, faWindowClose, faCamera, faStop, faPen, faCheck, faTimes, faSave } from '@fortawesome/free-solid-svg-icons';
|
import {
|
||||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
faPlus,
|
||||||
|
faCheckCircle,
|
||||||
|
faEdit,
|
||||||
|
faTrash,
|
||||||
|
faCat,
|
||||||
|
faSyncAlt,
|
||||||
|
faSort,
|
||||||
|
faSortUp,
|
||||||
|
faSortDown,
|
||||||
|
faTh,
|
||||||
|
faList,
|
||||||
|
faWindowClose,
|
||||||
|
faCamera,
|
||||||
|
faStop,
|
||||||
|
faPen,
|
||||||
|
faCheck,
|
||||||
|
faTimes,
|
||||||
|
faSave
|
||||||
|
} from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome';
|
||||||
|
|
||||||
import vueDebounce from 'vue-debounce';
|
import vueDebounce from 'vue-debounce';
|
||||||
|
|
||||||
|
|
|
@ -8,19 +8,18 @@ import VueRouter from 'vue-router';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Vue.use(VueRouter);
|
Vue.use(VueRouter);
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{ path: '/', redirect: '/Camp23/items' },
|
{path: '/', redirect: '/Camp23/items'},
|
||||||
{ path: '/howto', name: 'howto', component: HowTo},
|
{path: '/howto', name: 'howto', component: HowTo},
|
||||||
{ path: '/admin/files', name: 'files', component: Files},
|
{path: '/admin/files', name: 'files', component: Files},
|
||||||
{ path: '/admin/events', name: 'events', component: Events},
|
{path: '/admin/events', name: 'events', component: Events},
|
||||||
{ path: '/:event/boxes', name: 'boxes', component: Boxes},
|
{path: '/:event/boxes', name: 'boxes', component: Boxes},
|
||||||
{ path: '/:event/items', name: 'items', component: Items},
|
{path: '/:event/items', name: 'items', component: Items},
|
||||||
{ path: '/:event/box/:uid', name: 'boxes', component: Boxes},
|
{path: '/:event/box/:uid', name: 'boxes', component: Boxes},
|
||||||
{ path: '/:event/item/:uid', name: 'items', component: Items},
|
{path: '/:event/item/:uid', name: 'items', component: Items},
|
||||||
{ path: '*', component: Error},
|
{path: '*', component: Error},
|
||||||
];
|
];
|
||||||
|
|
||||||
const router = new VueRouter({
|
const router = new VueRouter({
|
||||||
|
|
|
@ -48,7 +48,7 @@ const store = new Vuex.Store({
|
||||||
lastUsed: localStorage.getItem('lf_lastUsed') || {},
|
lastUsed: localStorage.getItem('lf_lastUsed') || {},
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
getEventSlug: state => state.route && state.route.params.event? state.route.params.event : state.events.length ? state.events[0].slug : '36C3',
|
getEventSlug: state => state.route && state.route.params.event ? state.route.params.event : state.events.length ? state.events[0].slug : '36C3',
|
||||||
getActiveView: state => state.route.name || 'items',
|
getActiveView: state => state.route.name || 'items',
|
||||||
getFilters: state => state.route.query,
|
getFilters: state => state.route.query,
|
||||||
getBoxes: state => state.loadedBoxes
|
getBoxes: state => state.loadedBoxes
|
||||||
|
@ -74,17 +74,17 @@ const store = new Vuex.Store({
|
||||||
state.loadedBoxes = loadedBoxes;
|
state.loadedBoxes = loadedBoxes;
|
||||||
},
|
},
|
||||||
updateItem(state, updatedItem) {
|
updateItem(state, updatedItem) {
|
||||||
const item = state.loadedItems.filter(({ uid }) => uid === updatedItem.uid)[0];
|
const item = state.loadedItems.filter(({uid}) => uid === updatedItem.uid)[0];
|
||||||
Object.assign(item, updatedItem);
|
Object.assign(item, updatedItem);
|
||||||
},
|
},
|
||||||
removeItem(state, item) {
|
removeItem(state, item) {
|
||||||
state.loadedItems = state.loadedItems.filter(it => it !== item );
|
state.loadedItems = state.loadedItems.filter(it => it !== item);
|
||||||
},
|
},
|
||||||
appendItem(state, item) {
|
appendItem(state, item) {
|
||||||
state.loadedItems.push(item);
|
state.loadedItems.push(item);
|
||||||
},
|
},
|
||||||
createToast(state, { title, message, color }) {
|
createToast(state, {title, message, color}) {
|
||||||
state.toasts.push({ title, message, color, key: state.keyIncrement });
|
state.toasts.push({title, message, color, key: state.keyIncrement});
|
||||||
state.keyIncrement += 1;
|
state.keyIncrement += 1;
|
||||||
},
|
},
|
||||||
removeToast(state, key) {
|
removeToast(state, key) {
|
||||||
|
@ -92,50 +92,50 @@ const store = new Vuex.Store({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async loadEvents({ commit }) {
|
async loadEvents({commit}) {
|
||||||
const { data } = await axios.get('/1/events');
|
const {data} = await axios.get('/1/events');
|
||||||
commit('replaceEvents', data);
|
commit('replaceEvents', data);
|
||||||
},
|
},
|
||||||
changeEvent({ dispatch, getters}, eventName) {
|
changeEvent({dispatch, getters}, eventName) {
|
||||||
router.push({path: `/${eventName.slug}/${getters.getActiveView}`});
|
router.push({path: `/${eventName.slug}/${getters.getActiveView}`});
|
||||||
dispatch('loadEventItems');
|
dispatch('loadEventItems');
|
||||||
},
|
},
|
||||||
changeView({ getters }, link) {
|
changeView({getters}, link) {
|
||||||
router.push({path: `/${getters.getEventSlug}/${link.path}`});
|
router.push({path: `/${getters.getEventSlug}/${link.path}`});
|
||||||
},
|
},
|
||||||
showBoxContent({ getters }, box) {
|
showBoxContent({getters}, box) {
|
||||||
router.push({path: `/${getters.getEventSlug}/items`, query: {box}});
|
router.push({path: `/${getters.getEventSlug}/items`, query: {box}});
|
||||||
},
|
},
|
||||||
async loadEventItems({ commit, getters }) {
|
async loadEventItems({commit, getters}) {
|
||||||
const { data } = await axios.get(`/1/${getters.getEventSlug}/items`);
|
const {data} = await axios.get(`/1/${getters.getEventSlug}/items`);
|
||||||
commit('replaceLoadedItems', data);
|
commit('replaceLoadedItems', data);
|
||||||
},
|
},
|
||||||
async searchEventItems({ commit, getters }, query) {
|
async searchEventItems({commit, getters}, query) {
|
||||||
const foo = utf8.encode(query);
|
const foo = utf8.encode(query);
|
||||||
const bar = base64.encode(foo);
|
const bar = base64.encode(foo);
|
||||||
|
|
||||||
const {data} = await axios.get(`/1/${getters.getEventSlug}/items/${bar}`);
|
const {data} = await axios.get(`/1/${getters.getEventSlug}/items/${bar}`);
|
||||||
commit('replaceLoadedItems', data);
|
commit('replaceLoadedItems', data);
|
||||||
},
|
},
|
||||||
async loadBoxes({ commit }) {
|
async loadBoxes({commit}) {
|
||||||
const { data } = await axios.get('/1/boxes');
|
const {data} = await axios.get('/1/boxes');
|
||||||
commit('replaceBoxes', data);
|
commit('replaceBoxes', data);
|
||||||
},
|
},
|
||||||
async updateItem({ commit, getters }, item) {
|
async updateItem({commit, getters}, item) {
|
||||||
const { data } = await axios.put(`/1/${getters.getEventSlug}/item/${item.uid}`, item);
|
const {data} = await axios.put(`/1/${getters.getEventSlug}/item/${item.uid}`, item);
|
||||||
commit('updateItem', data);
|
commit('updateItem', data);
|
||||||
},
|
},
|
||||||
async markItemReturned({ commit, getters }, item) {
|
async markItemReturned({commit, getters}, item) {
|
||||||
await axios.put(`/1/${getters.getEventSlug}/item/${item.uid}`, {returned: true});
|
await axios.put(`/1/${getters.getEventSlug}/item/${item.uid}`, {returned: true});
|
||||||
commit('removeItem', item);
|
commit('removeItem', item);
|
||||||
},
|
},
|
||||||
async deleteItem({ commit, getters }, item) {
|
async deleteItem({commit, getters}, item) {
|
||||||
await axios.delete(`/1/${getters.getEventSlug}/item/${item.uid}`, item);
|
await axios.delete(`/1/${getters.getEventSlug}/item/${item.uid}`, item);
|
||||||
commit('removeItem',item);
|
commit('removeItem', item);
|
||||||
},
|
},
|
||||||
async postItem({ commit, getters }, item) {
|
async postItem({commit, getters}, item) {
|
||||||
commit('updateLastUsed',{box: item.box, cid: item.cid});
|
commit('updateLastUsed', {box: item.box, cid: item.cid});
|
||||||
const { data } = await axios.post(`/1/${getters.getEventSlug}/item`, item);
|
const {data} = await axios.post(`/1/${getters.getEventSlug}/item`, item);
|
||||||
commit('appendItem', data);
|
commit('appendItem', data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ const store = new Vuex.Store({
|
||||||
|
|
||||||
export default store;
|
export default store;
|
||||||
|
|
||||||
store.dispatch('loadEvents').then(() =>{
|
store.dispatch('loadEvents').then(() => {
|
||||||
store.dispatch('loadEventItems');
|
store.dispatch('loadEventItems');
|
||||||
store.dispatch('loadBoxes');
|
store.dispatch('loadBoxes');
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
v-slot="{ item }"
|
v-slot="{ item }"
|
||||||
>
|
>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button class="btn btn-secondary" @click.stop="showBoxContent(item.name)" >
|
<button class="btn btn-secondary" @click.stop="showBoxContent(item.name)">
|
||||||
<!--font-awesome-icon icon="archive"/--> content
|
<!--font-awesome-icon icon="archive"/--> content
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-danger" @click.stop="" title="delete">
|
<button class="btn btn-danger" @click.stop="" title="delete">
|
||||||
|
|
|
@ -9,11 +9,13 @@
|
||||||
v-slot="{ item }"
|
v-slot="{ item }"
|
||||||
>
|
>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button class="btn btn-secondary" @click.stop="changeEvent(item)" >
|
<button class="btn btn-secondary" @click.stop="changeEvent(item)">
|
||||||
<font-awesome-icon icon="archive"/> use
|
<font-awesome-icon icon="archive"/>
|
||||||
|
use
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-danger" @click.stop="" >
|
<button class="btn btn-danger" @click.stop="">
|
||||||
<font-awesome-icon icon="trash"/> delete
|
<font-awesome-icon icon="trash"/>
|
||||||
|
delete
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</Table>
|
</Table>
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
v-slot="{ item }"
|
v-slot="{ item }"
|
||||||
>
|
>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button class="btn btn-danger" @click.stop="" >
|
<button class="btn btn-danger" @click.stop="">
|
||||||
<font-awesome-icon icon="trash"/> delete
|
<font-awesome-icon icon="trash"/>
|
||||||
|
delete
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</Table>
|
</Table>
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
<li>Der Gegenstand wird in das c3lf-System eingetragen
|
<li>Der Gegenstand wird in das c3lf-System eingetragen
|
||||||
<ul>
|
<ul>
|
||||||
<li>Foto vom Gegenstand mit der Webcam machen</li>
|
<li>Foto vom Gegenstand mit der Webcam machen</li>
|
||||||
<li>Beschreibung des Gegenstands eintragen (gerne wie Tags behandeln die durch Leerzeichen getrennt
|
<li>Beschreibung des Gegenstands eintragen (gerne wie Tags behandeln die durch Leerzeichen
|
||||||
|
getrennt
|
||||||
sind)
|
sind)
|
||||||
</li>
|
</li>
|
||||||
<li>Nummer der Box eintragen in die der Gegenstand gelegt wird</li>
|
<li>Nummer der Box eintragen in die der Gegenstand gelegt wird</li>
|
||||||
|
@ -31,7 +32,9 @@
|
||||||
<h3>Lost (Jemand versucht einen Gegenstand wiederzufinden)</h3>
|
<h3>Lost (Jemand versucht einen Gegenstand wiederzufinden)</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Jemand möchte einen Gegenstand wiederfinden</li>
|
<li>Jemand möchte einen Gegenstand wiederfinden</li>
|
||||||
<li>Die Person soll möglichst genau beschreiben was sie sucht (insbesondere bei wertvolleren Dingen)</li>
|
<li>Die Person soll möglichst genau beschreiben was sie sucht (insbesondere bei wertvolleren
|
||||||
|
Dingen)
|
||||||
|
</li>
|
||||||
<li>Du schaust im System nach ob der Gegenstand vorhanden ist</li>
|
<li>Du schaust im System nach ob der Gegenstand vorhanden ist</li>
|
||||||
<li>Wenn ein passender Gegenstand gefunden ist:
|
<li>Wenn ein passender Gegenstand gefunden ist:
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -42,9 +45,12 @@
|
||||||
<li>Wenn kein passender Gegenstand existiert:
|
<li>Wenn kein passender Gegenstand existiert:
|
||||||
<ul>
|
<ul>
|
||||||
<li>Sagen, dass es den Gegenstand nicht gibt</li>
|
<li>Sagen, dass es den Gegenstand nicht gibt</li>
|
||||||
<li>Darauf verweisen dass die Person entweder zu späterem Zeitpunkt wiederkommt, oder ein Ticket bei <a
|
<li>Darauf verweisen dass die Person entweder zu späterem Zeitpunkt wiederkommt, oder ein
|
||||||
href="mailto:camp23@c3lf.de" target="_blank" rel="noopener">camp23@c3lf.de</a> aufmacht. Außerdem ist es
|
Ticket bei <a
|
||||||
gut möglich dass der Himmel und andere Villages eigene, kleinere Lost+Founds während des Events
|
href="mailto:camp23@c3lf.de" target="_blank" rel="noopener">camp23@c3lf.de</a>
|
||||||
|
aufmacht. Außerdem ist es
|
||||||
|
gut möglich dass der Himmel und andere Villages eigene, kleinere Lost+Founds während des
|
||||||
|
Events
|
||||||
aufgemacht haben. Rumfragen lohnt sich also.
|
aufgemacht haben. Rumfragen lohnt sich also.
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Achtung: Tickets werden erst nach Ende des Events bearbeitet.</b></li>
|
<li><b>Achtung: Tickets werden erst nach Ende des Events bearbeitet.</b></li>
|
||||||
|
@ -62,7 +68,8 @@
|
||||||
<h2>Lost&Found (English version)</h2>
|
<h2>Lost&Found (English version)</h2>
|
||||||
<p>Welcome to Lost&Found of $Event!</p>
|
<p>Welcome to Lost&Found of $Event!</p>
|
||||||
<p>Your tasks are to accept and register lost items, as well as to return items to their owners.</p>
|
<p>Your tasks are to accept and register lost items, as well as to return items to their owners.</p>
|
||||||
<p><b>Please do not leave the contents of the Lost+Found lying around or show them around. Ask for a description of the item first, then show them (if the description seems correct).</b></p>
|
<p><b>Please do not leave the contents of the Lost+Found lying around or show them around. Ask for a
|
||||||
|
description of the item first, then show them (if the description seems correct).</b></p>
|
||||||
<h3>Found (Someone brings a lost item)</h3>
|
<h3>Found (Someone brings a lost item)</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Get as much information as possible about the circumstances
|
<li>Get as much information as possible about the circumstances
|
||||||
|
@ -83,7 +90,8 @@
|
||||||
<h3>Lost (Someone tries to find an item)</h3>
|
<h3>Lost (Someone tries to find an item)</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Someone wants to find an item</li>
|
<li>Someone wants to find an item</li>
|
||||||
<li>The person should describe as precisely as possible what they are looking for (especially for more
|
<li>The person should describe as precisely as possible what they are looking for (especially for
|
||||||
|
more
|
||||||
valuable things)
|
valuable things)
|
||||||
</li>
|
</li>
|
||||||
<li>You check the system to see if the item is available</li>
|
<li>You check the system to see if the item is available</li>
|
||||||
|
@ -97,8 +105,10 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li>Say that the item does not exist</li>
|
<li>Say that the item does not exist</li>
|
||||||
<li>Point out that the person either comes back at a later time, or opens a ticket at <a
|
<li>Point out that the person either comes back at a later time, or opens a ticket at <a
|
||||||
href="mailto:camp23@c3lf.de" target="_blank" rel="noopener">camp23@c3lf.de</a>. It is also possible that
|
href="mailto:camp23@c3lf.de" target="_blank" rel="noopener">camp23@c3lf.de</a>. It is
|
||||||
the Himmel and other Villages have their own, smaller Lost+Founds during the event. So it's worth asking
|
also possible that
|
||||||
|
the Himmel and other Villages have their own, smaller Lost+Founds during the event. So
|
||||||
|
it's worth asking
|
||||||
around.
|
around.
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Attention: Tickets will not be processed until after the event.</b></li>
|
<li><b>Attention: Tickets will not be processed until after the event.</b></li>
|
||||||
|
|
|
@ -85,12 +85,12 @@ export default {
|
||||||
editingItem: null,
|
editingItem: null,
|
||||||
baseUrl: config.service.url,
|
baseUrl: config.service.url,
|
||||||
}),
|
}),
|
||||||
components: {Lightbox, Table, Cards, Modal, EditItem },
|
components: {Lightbox, Table, Cards, Modal, EditItem},
|
||||||
computed: mapState(['loadedItems', 'layout']),
|
computed: mapState(['loadedItems', 'layout']),
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['deleteItem','markItemReturned']),
|
...mapActions(['deleteItem', 'markItemReturned']),
|
||||||
openLightboxModalWith(item) { // Opens the editing modal with a copy of the selected item.
|
openLightboxModalWith(item) { // Opens the editing modal with a copy of the selected item.
|
||||||
this.lightboxItem = { ...item };
|
this.lightboxItem = {...item};
|
||||||
},
|
},
|
||||||
closeLightboxModal() { // Closes the editing modal and discards the edited copy of the item.
|
closeLightboxModal() { // Closes the editing modal and discards the edited copy of the item.
|
||||||
this.lightboxItem = null;
|
this.lightboxItem = null;
|
||||||
|
|
Loading…
Reference in a new issue