163 lines
7.0 KiB
JavaScript
163 lines
7.0 KiB
JavaScript
Vue.component('tt-positions-manager', {
|
|
props: {
|
|
value: {type: Array, required: false},
|
|
config: {type: Object, required: true},
|
|
},
|
|
data() {
|
|
return {
|
|
window: window,
|
|
positions: this.value,
|
|
formData: {},
|
|
selectedIndex: null,
|
|
resolvingFields: {},
|
|
}
|
|
},
|
|
template: `
|
|
<div class="positions-manager">
|
|
<div class="form-container">
|
|
<template v-for="(field, key) in config.fields">
|
|
<slot :name="key" v-bind:field="field" v-bind:value="formData[key]">
|
|
<tt-input
|
|
v-if="field.type === 'input'"
|
|
:label="field.label"
|
|
v-model="formData[key]"
|
|
@input="$emit('updateField-' + key, $event)"
|
|
sm
|
|
:type="field.inputType || 'text'"
|
|
/>
|
|
<tt-autocomplete
|
|
v-else-if="field.type === 'autocomplete'"
|
|
:label="field.label"
|
|
v-model="formData[key]"
|
|
@input="$emit('updateField-' + key, $event); window.console.log($event)"
|
|
:api-url="window.TT_CONFIG['BASE_PATH'] + field.apiUrl"
|
|
sm
|
|
/>
|
|
<tt-checkbox
|
|
v-else-if="field.type === 'checkbox'"
|
|
:label="field.label"
|
|
@input="$emit('updateField-' + key, $event)"
|
|
sm
|
|
v-model="formData[key]"
|
|
/>
|
|
<tt-select
|
|
v-else-if="field.type === 'select'"
|
|
:label="field.label"
|
|
@input="$emit('updateField-' + key, $event); window.console.log('updatefield-' + key, $event)"
|
|
sm
|
|
v-model="formData[key]"
|
|
:options="field.options"
|
|
/>
|
|
</slot>
|
|
</template>
|
|
<div class="button-wrapper">
|
|
<tt-button @click="saveEntry" sm :additional-class="selectedIndex === null ? 'btn-primary' : 'btn-success'"
|
|
:text="selectedIndex === null ? 'Hinzufügen' : 'Aktualisieren'"/>
|
|
</div>
|
|
</div>
|
|
|
|
<table class="table table-striped table-sm">
|
|
<thead>
|
|
<tr>
|
|
<th v-for="field in config.fields">{{ field.label }}</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="(position, index) in positions" :key="index">
|
|
<td v-for="(field, key) in config.fields">
|
|
<template v-if="resolvingFields[index + key] === true">
|
|
<div class="d-flex justify-content-center align-items-center">
|
|
<div class="spinner-border spinner-border-sm text-primary" role="status">
|
|
<span class="sr-only">Loading...</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<span v-else-if="resolvingFields[index + key]">{{ resolvingFields[index + key] }}</span>
|
|
<span v-else>{{ formatFieldValue(position[key], field) }}</span>
|
|
</td>
|
|
<td>
|
|
<button @click="editEntry(index)" class="btn btn-sm btn-primary">Editieren</button>
|
|
<button @click="deleteEntry(index)" class="btn btn-sm btn-danger">Löschen</button>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
`,
|
|
methods: {
|
|
updateField(key, value) {
|
|
this.$set(this.formData, key, value);
|
|
},
|
|
async saveEntry() {
|
|
if (this.config.validateForm && !await this.config.validateForm(this.formData)) return;
|
|
|
|
if (this.selectedIndex === null) this.positions.push(this.formData);
|
|
else this.$set(this.positions, this.selectedIndex, this.formData);
|
|
|
|
if (this.config.customOrdering) {
|
|
this.positions.sort((a, b) => a[this.config.customOrdering] - b[this.config.customOrdering]);
|
|
}
|
|
|
|
this.$emit('input', this.positions);
|
|
this.resetForm();
|
|
},
|
|
editEntry(index) {
|
|
this.selectedIndex = index;
|
|
this.formData = {...this.positions[index]};
|
|
},
|
|
deleteEntry(index) {
|
|
this.positions.splice(index, 1);
|
|
this.$emit('input', this.positions);
|
|
},
|
|
resetForm() {
|
|
this.formData = {};
|
|
this.selectedIndex = null;
|
|
},
|
|
formatFieldValue(value, field) {
|
|
if (field.formatter) return field.formatter(value);
|
|
return value;
|
|
},
|
|
async resolveFields() {
|
|
for (let i = 0; i < this.positions.length; i++) {
|
|
for (let key in this.config.fields) {
|
|
if (this.config.fields[key].customFieldResolver) {
|
|
this.$set(this.resolvingFields, i + key, true);
|
|
const textValue = await this.config.fields[key].customFieldResolver(this.positions[i][key]);
|
|
this.$set(this.resolvingFields, i + key, textValue);
|
|
} else if (this.config.fields[key].customFieldReference) {
|
|
this.$set(this.resolvingFields, i + key, true);
|
|
if (this.config.fields[key].customFieldReference) {
|
|
const entry = await axios.get(window.TT_CONFIG['BASE_PATH'] +
|
|
'/' +
|
|
this.config.fields[key].customFieldReference +
|
|
'/getById?id=' +
|
|
this.positions[i][key]);
|
|
const textValue = entry.data.name ?? entry.data.title ?? entry.data.text ?? '[E] Key not found';
|
|
console.log(textValue);
|
|
this.$set(this.resolvingFields, i + key, textValue);
|
|
} else this.$set(this.resolvingFields, i + key, '');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
created() {
|
|
if (this.config.customMethods) Object.assign(this, this.config.customMethods);
|
|
},
|
|
watch: {
|
|
positions: {
|
|
handler() {
|
|
this.resolveFields().then();
|
|
},
|
|
deep: true
|
|
},
|
|
value: {
|
|
handler() {
|
|
this.positions = this.value;
|
|
},
|
|
deep: true
|
|
}
|
|
}
|
|
}); |