Updated WarehouseShippingNote

This commit is contained in:
Luca Haid
2024-11-12 18:24:25 +01:00
parent 50228c36e4
commit e42a13041b
18 changed files with 1191 additions and 332 deletions

View File

@@ -151,6 +151,17 @@ input[type=number]::-webkit-outer-spin-button {
.tt-table.table-sm > tbody > tr > td * {
font-size: 16px !important;
}
.modal-footer {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 4px;
}
.modal-footer > button {
margin: 0 !important;
}
}
td {

View File

@@ -5,7 +5,7 @@
Vue.component('tt-autocomplete', {
template: `
<div class="form-group" :class="{'row': row}"
:data-api-url="apiUrl"
:data-api-url="apiUrl"
>
<slot name="prepend"></slot>
<label :class="{'col-form-label': row, 'col-sm-4': row, 'col-form-label-sm': sm && row}"
@@ -24,7 +24,8 @@ Vue.component('tt-autocomplete', {
:style="{'padding-right': $slots.append ? '30px' : '0'}"
/>
<slot name="append"></slot>
<button v-show="displayValue.length > 0" @click="displayValue = ''; $emit('input', '');" tabindex="-1" type="button" class="btn btn-link position-absolute"
<button v-show="displayValue.length > 0" @click="displayValue = ''; $emit('input', '');" tabindex="-1" type="button"
class="btn btn-link position-absolute"
style="right: -5px; top: 50%; transform: translateY(-50%);">
<i class="fas fa-times"></i>
</button>
@@ -67,7 +68,7 @@ Vue.component('tt-autocomplete', {
</div>
`, // TODO: Implement giving the option without the need of an API || need to use computed property to filter the items
// TODO: Fix the weirdness with timeout and selecting the suggestion
props: {
props: {
value: {type: [String, Number]},
label: {type: String, required: false},
apiUrl: String,
@@ -76,29 +77,38 @@ Vue.component('tt-autocomplete', {
sm: {type: Boolean, default: true},
row: {type: Boolean, default: false},
}, async mounted() {
if (this.value && this.apiUrl) {
const response = await axios.get(`${this.apiUrl}&autocomplete=1&searchedID=${this.value}`);
this.displayValue = response.data[0].text;
} else if (this.value) {
const selectedItem = this.items.find(item => item.value === this.value);
this.displayValue = selectedItem ? selectedItem.text : '';
} else {
this.$emit('input', '');
this.displayValue = '';
}
this.updateDisplayValue().then();
}, data() {
return {
displayingItems: [], displayValue: '', isLoading: false, showSuggestions: false, cursor: -1, fetchSuggestionsDebounceTimer: null,
displayingItems: [], displayValue: '', isLoading: false, showSuggestions: false, cursor: -1, fetchSuggestionsDebounceTimer: null, disableIDFetch: false
};
}, watch: {
value(newValue) {
const selectedItem = this.displayingItems.find(item => item.value === newValue);
this.displayValue = selectedItem ? selectedItem.text : '';
}, apiUrl() {
value: {handler: 'updateDisplayValue', immediate: true},
apiUrl() {
this.fetchSuggestions();
},
}, methods: {
async updateDisplayValue(newValue) {
if (this.disableIDFetch) {
this.disableIDFetch = false;
return;
}
if (newValue) {
this.value = newValue;
}
if (this.value && this.apiUrl) {
const response = await axios.get(`${this.apiUrl}&autocomplete=1&searchedID=${this.value}`);
this.displayValue = response.data[0].text;
} else if (this.value) {
const selectedItem = this.items.find(item => item.value === this.value);
this.displayValue = selectedItem ? selectedItem.text : '';
} else {
this.$emit('input', '');
this.displayValue = '';
}
},
onInput(event) {
this.displayValue = event.target.value;
this.$emit('input', '');
@@ -157,6 +167,7 @@ Vue.component('tt-autocomplete', {
}, 100);
}, 300); // Adjust the 300ms debounce time as needed
}, selectSuggestion(item) {
this.disableIDFetch = true;
this.$emit('input', item.value);
this.displayValue = item.text;
this.showSuggestions = false;

View File

@@ -2,6 +2,7 @@ Vue.component('tt-input', {
props: {
label: String,
type: String,
disabled: Boolean,
placeholder: String,
required: Boolean,
row: Boolean,
@@ -34,6 +35,7 @@ Vue.component('tt-input', {
:class="{'form-control-sm': sm, 'col-sm-8': row}"
:placeholder="placeholder"
:required="required"
:disabled="disabled"
v-bind="additionalProps"
v-model="inputValue"
@input="$emit('input', $event.target.value)"

View File

@@ -52,8 +52,8 @@ Vue.component('tt-modal', {
@mousedown="$emit('update:show', false)"
@keydown.esc="$emit('update:show', false)"
v-if="show">
<div class="modal-dialog modal-lg" role="document" @mousedown.stop>
<div class="modal-content">
<div class="modal-dialog modal-lg modal-dialog-scrollable" role="document" @mousedown.stop>
<div class="modal-content" style="min-height: 45vh;">
<div class="modal-header">
<h5 class="modal-title">{{title}}</h5>
<button type="button" class="close" @click="$emit('update:show', false)">
@@ -65,9 +65,10 @@ Vue.component('tt-modal', {
</div>
<div class="modal-footer">
<slot name="footer">
<slot name="footer-prepend"></slot>
<button v-if="save" class="btn btn-primary" @click="$emit('submit')">{{saveText}}</button>
<button v-if="$props.delete" class="btn btn-danger" @click="$emit('delete')">{{deleteText}}</button>
<button class="btn btn-secondary" @click="$emit('update:show', false)">Close</button>
<button class="btn btn-secondary" @click="$emit('update:show', false)">Schließen</button>
</slot>
</div>
</div>

View File

@@ -4,6 +4,7 @@ Vue.component('tt-select', {
label: {type: String, required: false},
required: {type: Boolean, default: false},
value: {type: [String, Number], required: false},
disabled: {type: Boolean, default: false},
suffix: {type: String, required: false},
sm: {type: Boolean, default: false},
row: {type: Boolean, default: false},
@@ -28,7 +29,7 @@ Vue.component('tt-select', {
:for="label">{{ label }}</label>
<select class="form-control" :class="{'form-control-sm': sm, 'col-sm-8': row}"
:required="required" v-model="selectedOption"
:required="required" v-model="selectedOption" :disabled="disabled"
@change="$emit('input', $event.target.value ? $event.target.value : undefined)">
<template v-for="option of options">
<option v-if="['string','number'].includes(typeof option)" :value="option" :disabled="option.disabled === true">{{ option }}

View File

@@ -805,12 +805,12 @@ Vue.component('tt-table', {
// use header#topnav as top to stick to but if window is resized then check if header#topnav height is changed
const headerHeight = document.querySelector('header#topnav')?.offsetHeight || 0;
style.innerHTML = `table thead th { position: sticky; top: ${headerHeight}px; z-index: 1; background-color: white; }`;
style.innerHTML = `table.tt-table thead th { position: sticky; top: ${headerHeight}px; z-index: 1; background-color: white; }`;
style.id = 'tt-table-sticky-header';
window.addEventListener('resize', () => {
const headerHeight = document.querySelector('header#topnav')?.offsetHeight || 0;
style.innerHTML = `table thead th { position: sticky; top: ${headerHeight}px; z-index: 1; background-color: white; }`;
style.innerHTML = `table.tt-table thead th { position: sticky; top: ${headerHeight}px; z-index: 1; background-color: white; }`;
})
document.head.appendChild(style);