Files
decpdf.site/src/ProductSelector.vue
2026-01-18 00:53:18 +00:00

173 lines
3.9 KiB
Vue
Executable File

<template>
<div>
<div v-for="p in products" class="btn-group m-1">
<button class="btn btn-secondary p-1" :title="p.full_path"><small>{{ p.title }}</small></button>
<button :pid="p.id" @click.stop="remove(p.id)" class="btn btn-secondary p-1" title="Remove"><small><i class="fa fa-close"></i></small></button>
</div>
<div ref="dropdown" class="dropdown" @show.bs.dropdown="add_show">
<button class="btn btn-success p-1 dropdown-toggle" title="Add" data-bs-toggle="dropdown" @click="add_show"><small><i class="fa fa-plus"></i></small></button>
<ul class="dropdown-menu" @show.bs.dropdown="add_show">
<li v-for="p in mru"><a href='#' @click="add_pid(p)" class="dropdown-item">{{ p.full_path }}</a></li>
<hr>
<li><input ref="searchinput" @input="do_search" class='form-control' name='search' v-model="search" autocomplete="off"></li>
<li v-for="p in searchres"><a href='#' @click="add_pid(p)" class="dropdown-item">{{ p.full_path }}</a></li>
</ul>
</div>
<button @click="set_default_pids" class="btn btn-primary">Set Default</button>
<button @click="clear_default_pids" class="btn btn-primary">Clear Default</button>
</div>
</template>
<script>
import { ref, computed } from 'vue/dist/vue.esm-bundler';
export default {
props: {
modelValue: ref(""),
},
setup(props, {emit}) {
return {
products: ref([]),
mru: ref([]),
search: ref(""),
searchres: ref([]),
pids: computed({
get: () => props.modelValue,
set: (value) => emit('update:modelValue', value)
}),
was_mod: ref(false),
req: ref(null),
}
},
methods: {
init() {
$(document).on("show.bs.dropdown", '.dropdown', this.add_show);
$(document).on("shown.bs.dropdown", $(this.$refs.dropdown), this.add_shown);
$(this.$refs.dropdown).on("show.bs.dropdown", this.add_show);
$(this.$refs.dropdown).on("shown.bs.dropdown", this.add_shown);
this.get_products();
this.$watch('modelValue', this.get_products);
},
get_products() {
if (this.pids!= "") {
$.ajax({
url: "/api/product/" + this.pids,
method: "GET"
}).done(this.got_products);
} else {
this.products = [];
}
var m = this.was_mod;
this.was_mod = false;
if (!m) {
if (this.pids == "") {
// Get default if available
var p = localStorage.getItem("default_pids");
if ((p != null) && (p != "")) {
this.was_mod = true;
this.pids = p;
}
}
}
},
got_products(data) {
this.products = data;
},
remove(e) {
this.was_mod = true;
var tmp = [];
var pidarray = [];
for (var i = 0; i < this.products.length; i++) {
if (this.products[i].id != e) {
tmp.push(this.products[i]);
pidarray.push(this.products[i].id);
}
}
this.products = tmp;
this.pids = pidarray.join(",");
},
add_show(e) {
this.search = "";
this.searchres = []
$.ajax({
url: "/api/productmru",
method: "GET"
}).done(this.fill_mru);
},
add_shown(e) {
this.$refs.searchinput.focus();
},
fill_mru(data) {
this.mru = data;
},
do_search(e) {
if (this.search.length >= 3) {
if (this.req != null) {
this.req.abort();
this.req = null;
}
this.req=$.ajax({
url: "/api/search/product",
method: "POST",
data: {
search: this.search
}
}).done(this.search_done);
}
},
search_done(data) {
this.searchres = data;
},
add_pid(prod) {
this.was_mod = true;
var pidarray;
if (this.pids == "") {
pidarray = [];
} else {
pidarray = this.pids.split(",");
}
if (pidarray.includes(prod.id)) {
return;
}
pidarray.push(prod.id);
this.pids = pidarray.join(",");
this.products.push(prod);
$.ajax({
url: "/api/productmru/" + prod.id,
method: "POST",
data: {
}
});
},
set_default_pids() {
localStorage.setItem("default_pids", this.pids);
},
clear_default_pids() {
localStorage.setItem("default_pids", "");
},
},
mounted() {
this.init();
},
};
</script>