import type { PropType } from 'vue'; import { computed, defineComponent, onMounted, ref, toRef, watch } from 'vue'; import { useI18n } from 'vue-i18n'; import { useUserStore } from '@store/UserStore'; import { useGlobalStore } from '@store/globalStore'; import { useQuasar } from 'quasar'; import { costanti } from '@costanti'; import { fieldsTable } from '@store/Modules/fieldsTable'; import { shared_consts } from '@/common/shared_vuejs'; import type { IColGridTable } from 'model'; import { IOperators } from 'model'; import { tools } from '@tools'; import { useProducts } from 'app/src/store/Products'; export default defineComponent({ name: 'CMySelect', emits: ['update:value', 'update:arrvalue', 'changeval', 'clear', 'searchOnGM'], props: { options: { type: Array, required: true, }, arrvalue: { type: Array, required: false, default: [], }, value: [String, Number, Object], label: { type: String, required: false, default: undefined, }, addstrrequired: { type: String, required: false, default: '', }, myclass: { type: String, required: false, default: '', }, tablesel: { type: String, required: false, default: '', }, type_out: { type: Number, required: false, }, row: { type: Object, required: false, default: () => { return {}; }, }, col: { type: Object as PropType, required: false, default: () => { return { name: '' }; }, }, filter_table: { type: String, required: false, default: '', }, filter_field: { type: String, required: false, default: '', }, filter_extra: { type: [Object, String], required: false, default: null, }, value_extra: { type: [String, Number], required: false, default: '', }, myvaltosee: { type: [String, Number], required: false, default: '', }, optlab: [String, Function], optval: { type: String, required: true, }, useinput: { type: Boolean, required: false, default: true, }, pickup: { type: Boolean, required: false, default: false, }, addall: { type: Boolean, required: false, default: false, }, addnone: { type: Boolean, required: false, default: false, }, addlast: { type: Boolean, required: false, default: false, }, dense: { type: Boolean, required: false, default: true, }, multiple: { type: Boolean, required: false, default: false, }, newvaluefunc: { type: Function, required: false, }, funcgetvaluebyid: { type: Function, required: false, }, multiselect_by_server: { type: Boolean, default: false, }, sola_lettura: { type: Boolean, default: false, }, focus: { type: Boolean, default: false, }, withToggle: { type: Boolean, default: false, }, icon_alternative: { type: String, required: false, default: '', }, filter: { type: Function, required: false, default: () => true, }, }, components: {}, setup(props, { emit }) { const $q = useQuasar(); const { t } = useI18n(); const userStore = useUserStore(); const globalStore = useGlobalStore(); const optFiltered = ref([]); const valori = ref([]); const myvalue = ref(''); const myarrvalue = ref([]); const arrtempOpt = ref([]); const optionsreal: any = []; const selectMultiServer = ref(null); const selectPickup = ref(null); const selectMultiple = ref(null); const selectGeneric = ref(null); const productStore = useProducts(); const mystr = ref(''); const myval_tosee = ref(''); const valoriload = computed(() => { return updateArrOptions(); }); watch( () => props.options, (value: any, oldval: any) => { if (!props.multiselect_by_server) { valori.value = valoriload.value; } else { // console.log('@@@ VALORI CHANGED (1)', valori.value) } } ); watch( () => props.value, (value: any, oldval: any) => { update(); } ); watch( () => props.arrvalue, (value: any, oldval: any) => { // console.log(' MODIF props.arrvalue', props.arrvalue) update(); } ); function saveOptInCookie(arrval: any) { // console.log('saveOptInCookie') if (arrval) { for (const id of arrval) { const trovato = arrtempOpt.value.find((rec) => rec._id === id); if (!trovato) { const rec = valori.value.find((rec: any) => rec._id === id); if (rec) { // console.log('SAVE OPT rec', rec) const obj: any = {}; obj[`${props.optval}`] = id; obj[`${props.optlab}`] = rec[`${props.optlab}`]; arrtempOpt.value.push(obj); let num = localStorage.getItem(props.tablesel + 'NUM') || 0; try { if (!num) { num = 0; } else { num = parseInt(num.toString(), 10); } } catch (e) { num = 0; } // console.log('----------- valori.value', valori.value) // console.log('----------- arrtempOpt.value', arrtempOpt.value) tools.localStSetItem(props.tablesel + num + props.optval, id); const mysaved = tools.getValueByFunzOrVal(rec, props.optlab); tools.localStSetItem(props.tablesel + num + props.optlab, mysaved); console.log( ' SAVED: ', props.tablesel + num + props.optlab, '=', mysaved ); num += 1; tools.localStSetItem(props.tablesel + 'NUM', num.toString()); } } } } } function changeval(newval: any) { // console.log(' ½½½½½½½ changeval', newval) if (props.multiple || props.multiselect_by_server) { // tools.localStSetItem(props.tablesel + '_' + newval, valori.value[newval]) if (props.type_out === costanti.FieldType.object) { const arrout = []; for (const val of newval) { const obj: any = {}; if (typeof val !== 'object') { obj[props.optval] = val; arrout.push(obj); } else { arrout.push(val); } } myarrvalue.value = arrout; } else { myarrvalue.value = newval && newval['arrvalue'] ? newval['arrvalue'] : newval; } saveOptInCookie(newval); console.log(' ----- Myselect changeval Arrvalue', myarrvalue.value); emit('update:arrvalue', myarrvalue.value); emit('changeval', myarrvalue.value); } else { if (props.tablesel === shared_consts.TAB_COUNTRY) myvalue.value = newval && newval['value'] ? newval['value'] : newval; else if (props.tablesel === shared_consts.TAB_CITIES) myvalue.value = newval && newval['value'] ? newval['value'] : newval; else if (props.tablesel === shared_consts.TAB_PHONES) myvalue.value = newval && newval['code'] ? newval['code'] : newval; else myvalue.value = newval; // console.log('Myselect changeval', myvalue.value) if (myvalue.value && JSON.stringify(myvalue.value)) { saveLastOpt(props.optval, JSON.stringify(myvalue.value)); } saveOptInCookie([myvalue.value]); emit('update:value', myvalue.value); emit('changeval', myvalue.value); } } function saveLastOpt(key: string, myval: any) { let ind = 9; // get free number for (let i = 0; i < 10; i++) { let myoldval = tools.getItemLS(props.tablesel + 'last_VAL' + i.toString()); myoldval = tools.strToObj(myoldval); if (myoldval && myoldval[key]) { if (myoldval[key] === myval) { // already exist return; } // if (myoldval[key] !== myval) { if (!myoldval[key]) { ind = i; break; } } else { ind = i; break; } } // console.log('saveLastOpt', ind, 'key', key, 'myval', myval) tools.localStSetItem(props.tablesel + 'last_OPT' + ind.toString(), key); tools.localStSetItem(props.tablesel + 'last_VAL' + ind.toString(), myval); } function mounted() { // console.log('CMYSELECT: mounted') myval_tosee.value = props.myvaltosee optionsreal.value = props.options; if (props.focus) { focusVisibleSelect(); } update(); } function focusVisibleSelect() { try { if (selectMultiServer.value && props.multiselect_by_server) { selectMultiServer.value.focus(); } else if (selectPickup.value && props.pickup) { selectPickup.value.focus(); } else if (selectMultiple.value && props.multiple) { selectMultiple.value?.focus(); } else { if (selectGeneric.value) selectGeneric.value?.focus(); } } catch (e) { console.error('Err', e); } } function update() { console.log('update', props.value, props); // console.log(' #### mounted myselect', props.options, 'arrvalue', myarrvalue.value) let rec: any; if (optionsreal.value) { if (!props.multiselect_by_server) { rec = optionsreal.value.find( (myrec: any) => myrec[`${props.optval}`] === props.value ); } } if (props.multiselect_by_server) { const num = parseInt(localStorage.getItem(props.tablesel + 'NUM')!, 10); // console.log('num LOADED ', num) arrtempOpt.value = []; if (props.addall) { let myobj: any = {}; if (typeof props.optlab === 'string') { myobj = tools.setRecordByField(props.optlab, myobj, '(Tutti)'); myobj = tools.setRecordByField(props.optval, myobj, costanti.FILTER_TUTTI); } arrtempOpt.value.push(myobj); } if (props.addnone) { const myobj: any = {}; if (typeof props.optlab === 'string') { myobj[props.optlab] = '[Nessuno]'; myobj[props.optval] = costanti.FILTER_NESSUNO; } arrtempOpt.value = [myobj, ...arrtempOpt.value]; } for (let i = 0; i < num; i++) { const itemId = parseInt( localStorage.getItem(props.tablesel + i + props.optval)!, 10 ); const itemlab = localStorage.getItem(props.tablesel + i + props.optlab); if (itemId) { const obj: any = {}; obj[`${props.optval}`] = itemId; obj[`${props.optlab}`] = itemlab; if (!arrtempOpt.value.find((rec) => rec._id === itemId)) arrtempOpt.value.push(obj); } } // Check if exist other array: if (props.col) { if (props.col.remote_table && props.col.remote_key && props.col.remote_field) { try { const myarrremote = props.row[props.col.remote_table]; for (const myrec of myarrremote) { const myidkey = myrec[props.col.remote_key]; if (!arrtempOpt.value.includes(myidkey)) { const myobj: any = {}; myobj[props.col.remote_key] = myidkey; if (props.col.remote_field === 'comune' && !!myrec['prov']) { myobj[props.col.remote_field] = myrec[props.col.remote_field] + ' (' + myrec['prov'] + ')'; } else { myobj[props.col.remote_field] = myrec[props.col.remote_field]; } arrtempOpt.value.push(myobj); } } } catch (e) {} } } myarrvalue.value = []; const myarr = props.arrvalue; if (tools.isArray(myarr)) { for (const val of myarr) { rec = arrtempOpt.value.find((myrec: any) => val === myrec[`${props.optval}`]); if (rec) { myarrvalue.value.push(rec[`${props.optval}`]); } else { myarrvalue.value.push(val); } } } } else { if (props.addnone) { const myobj: any = {}; if (typeof props.optlab === 'string') { myobj[props.optlab] = '[Nessuno]'; myobj[props.optval] = costanti.FILTER_NESSUNO; } myarrvalue.value = [myobj, ...myarrvalue.value]; } } if (props.tablesel === 'friendsandme') { // debugger; } if (props.multiple) { const arrrec = []; let myarr = props.arrvalue; if (myarr && !tools.isArray(myarr)) { myarr = [myarr]; } if (myarr) { for (const val of myarr) { rec = optionsreal.value.find( (myrec: any) => val === myrec[`${props.optval}`] ); if (rec) { arrrec.push(rec[`${props.optval}`]); } } } if (arrrec.length > 0) { if (props.funcgetvaluebyid) myarrvalue.value = props.funcgetvaluebyid(arrrec); else myarrvalue.value = arrrec; } else { if (props.arrvalue) { myarrvalue.value = props.arrvalue; } } } else { if (rec) { if (props.funcgetvaluebyid) myvalue.value = props.funcgetvaluebyid(rec[`${props.optval}`]); else myvalue.value = tools.getValueByFunzOrVal(rec, props.optlab); } else { // if (!props.useinput) { if (props.value) { myvalue.value = props.value; } else { myvalue.value = ''; } // } } // console.log('myvalue', props.tablesel, myvalue.value) // console.log('props.value', props.value) } if (props.multiselect_by_server) { valori.value = arrtempOpt.value; } else { valori.value = valoriload.value; } // console.log('cmyselect: myvalue.value', myvalue.value) } function updateArrOptions() { let myarr: any = []; // console.log(props.col.jointable, props.filter) if (props && props.col && props.col.jointable) { optionsreal.value = globalStore.getTableJoinByName( props.col.jointable, props.col.addall, props.col.addnone, props.filter ); // console.log('optionsreal.value', optionsreal.value) } else { optionsreal.value = props.options; } // console.log('optionsreal.value', optionsreal.value) myarr = optionsreal.value; if (!fieldsTable.tableRemotePickup.includes(props.tablesel)) { const needle: any = props.value_extra; // console.log('needle', needle, 'props.multiple', props.multiple) if (props.filter_table) { // console.log(' FILTERTABLE', props.filter_field, myarr) if (props.multiple) { myarr = myarr.filter((rec: any) => rec[props.filter_field] === needle); } else { myarr = myarr.filter((rec: any) => { if (tools.isArray(rec[props.filter_field])) return rec[props.filter_field].includes(needle); else return false; }); } // console.log(' RISSSSSSSSS: ', myarr) } } if (props.addall) { let myobj: any = {}; // if (typeof props.optlab === 'string') { myobj = tools.setRecordByField(props.optlab, myobj, '(Tutti)'); myobj = tools.setRecordByField(props.optval, myobj, costanti.FILTER_TUTTI); // } if (myarr && !tools.isObjectEmpty(myobj)) myarr = [myobj, ...myarr]; } if (props.addnone) { const myobj: any = {}; if (typeof props.optlab === 'string') { myobj[props.optlab] = '[Nessuno]'; myobj[props.optval] = costanti.FILTER_NESSUNO; } if (myarr) myarr = [myobj, ...myarr]; } if (props.addlast) { myarr = getLastInserted(myarr); } // console.log(' myarr: ', myarr) return myarr; } function getLastInserted(myarr: any) { for (let ind = 0; ind < 10; ind++) { const optlab = tools.getItemLS(props.tablesel + 'last_OPT' + ind.toString()); let optval = tools.getItemLS(props.tablesel + 'last_VAL' + ind.toString()); if (optval) optval = JSON.parse(optval); // console.log(ind, '¶¶¶¶¶¶¶¶¶¶ optlab', optlab, 'optval', optval) const myobj2: any = {}; if (typeof props.optlab === 'string') { if (optval && !!optval['comune']) { myobj2[props.optlab] = optval['comune']; myobj2[props.optval] = optval[optlab]; myarr = [...myarr, myobj2]; } } } return myarr; } function filterFn(val: any, update: any, abort: any) { update( async () => { // console.log('Filter val:', val, 'len=', val.length) // console.log('props.filter_extra', props.filter_extra) // console.log('valori.value', valori.value) let myarr: any = []; mystr.value = val.toLocaleLowerCase(); myarr = updateArrOptions(); if (!fieldsTable.tableRemotePickup.includes(props.tablesel)) { if (myarr && myarr.length > 0) { valori.value = myarr; } else { if (props.filter_table) { valori.value = []; } } if (!props.multiple && !props.multiselect_by_server) { if (val === '') { valori.value = myarr; } else { const optlab: any = props.optlab ? '' + props.optlab : ''; if (optlab) { valori.value = myarr.filter((v: any) => { const mioval = tools.getRecordByField(optlab, v); if (mioval) return mioval?.toLowerCase().indexOf(mystr.value) > -1; else return false; }); } } } return; } if ( val.length <= 1 && !( fieldsTable.tableRemotePickup.includes(props.tablesel) && props.filter_extra ) ) { console.log('@@@ LENGTH <= 1'); abort(); return; } // console.log('props.tablesel', props.tablesel) if (fieldsTable.tableRemotePickup.includes(props.tablesel)) { try { // myarr = optionsreal.value myarr = []; if (mystr.value !== '' || props.filter_extra) { // myarr = [{_id:1, prov: 'RN', descr: 'Rimini'}] /* if (val === '1') { myarr.push({ _id: 1, comune: 'PROVA 1', prov: 'AL' }) myarr.push({ _id: 2, comune: 'PROVA 1b', prov: 'AL' }) }else if (val === '2') { myarr.push({ _id: 1, comune: 'PROVA 2', prov: 'AL' }) myarr.push({ _id: 2, comune: 'PROVA 2B', prov: 'AL' }) }*/ // @ts-ignore myarr = await globalStore.loadPickup({ table: props.tablesel, search: mystr.value.trim(), filter: props.filter_extra, }); } if (myarr === null) { console.log('@@@ VALORI VALUE XXX', valori.value); valori.value = arrtempOpt.value; } } catch (e) { console.log('@@@ VALORI VALUE XXX', valori.value); valori.value = arrtempOpt.value; } // const needle = val.toLocaleLowerCase() // optFiltered.value = optFiltered.value.filter((v: any) => v.toLocaleLowerCase().indexOf(needle) > -1) if (props.addall) { let myobj: any = {}; if (typeof props.optlab === 'string') { myobj = tools.setRecordByField(props.optlab, myobj, '(Tutti)'); myobj = tools.setRecordByField( props.optval, myobj, costanti.FILTER_TUTTI ); } myarr = [myobj, ...myarr]; } if (props.addnone) { const myobj: any = {}; if (typeof props.optlab === 'string') { myobj[props.optlab] = '[Nessuno]'; myobj[props.optval] = costanti.FILTER_NESSUNO; } myarr = [myobj, ...myarr]; } if (props.addlast) { myarr = getLastInserted(myarr); } } if (myarr && myarr.length > 0) { valori.value = myarr; if (props.multiselect_by_server) { // console.log('@@@ VALORI CHANGED (3)', valori.value) } } else { valori.value = []; } console.log('*** OUT: tablesel', props.tablesel, 'filterFn', myarr); }, // "ref" is the Vue reference to the QSelect (ref: any) => { if (!props.useinput) { // console.log('ref.options', ref.options) if (val !== '' && ref.options.length > 0) { ref.setOptionIndex(-1); // reset optionIndex in case there is something selected ref.moveOptionSelection(1, true); // focus the first selectable option and do not update the input-value } } } ); } function abortFilterFn() { console.log('delayed filter aborted'); } function checkIfShowRec(rec: any) { return (rec._id > 0 && typeof rec._id === 'number') || rec._id !== 'number'; } async function newvaluefuncfirst(value: any, done: any) { if (props.newvaluefunc && props.col) { const fieldval = fieldsTable.getLabelByTable(props.col.jointable); // console.log('fieldval', fieldval, 'optionsreal.value', optionsreal.value) // Se esiste già, non crearlo const esiste = optionsreal.value.find((rec: any) => { // console.log('rec[fieldval]',rec[fieldval], value.toLowerCase()) return ( rec[fieldval]?.toLowerCase() === value.toLowerCase() && rec[props.filter_field] === props.value_extra ); }); console.log('esiste', esiste); if (!esiste || (esiste && esiste.length === 0)) { // console.log('non esiste, lo creo ! ', value) const newrec = await props.newvaluefunc(tools.CapitalizeAllWords(value)); if (newrec) { if (props.col && props.col.jointable) { // Reload // console.log(' A1', optionsreal.value) // valori.value = valoriload.value // optionsreal.value = valori.value console.log('DOPO', optionsreal.value); } console.log('newrec', newrec); const myid = fieldsTable.getKeyByTable(props.col.jointable); const recfound = valori.value.find((rec: any) => rec[myid] === newrec[myid]); if (!recfound) { done(newrec, 'add-unique'); } // console.log('myid', myid, optionsreal.value) // console.log('recfound',recfound) // console.log('newrec[myid]',newrec[myid]) /*if (recfound) { const arrout = [...myarrvalue.value] if (!arrout.includes(recfound[myid])) { arrout.push(recfound[myid]) } console.log(' arrout (1)', arrout) if (props.multiple || props.multiselect_by_server) { if (myid) { done(newrec, 'add-unique') } } else { done(recfound[myid], 'add-unique') } /* if (props.multiple || props.multiselect_by_server) { console.log('arrout (2)', arrout) changeval(arrout) } }*/ } } } } function getIcon() { if (props.icon_alternative) return props.icon_alternative; if (props.col && props.col['icon']) { return props.col['icon']; } return ''; } function selectText(event: any) { // Seleziona tutto il testo all'interno della casella di testo event.target.select(); } function getLabelValue(opt: any): string { const collabel = props.optlab; if (typeof collabel === 'function') { // Se collabel è una funzione, chiamala con opt return collabel(opt); } else if (typeof collabel === 'string') { // Se collabel è una stringa, usa il valore della proprietà corrispondente return opt[collabel] || 'N/A'; } // Fallback generico return 'N/A'; } function getOptionLabel(option: any): string { // console.log('getOptionLabel', option) let lab = ''; if (typeof props.optlab === 'function') { lab = props.optlab(option); // Se optlab è una funzione, chiamala } else { if (typeof option === "object") { lab = option[props.optlab]; // Se optlab è una stringa, usa la proprietà corrispondente } else { lab = myval_tosee.value ? myval_tosee.value : ''; } } if (!lab) { // console.log('⚠️ LAB NON PRESENTE !'); } return lab; } function clear() { emit('clear'); myvalue.value = ''; mystr.value = ''; myval_tosee.value = ''; } function searchOnGM(mystr: string) { emit('searchOnGM', mystr); } function applyLabelColorBasedOnProductStatus(myrec: any) { let classi = ''; if (props.tablesel === 'products') { if (productStore.isNonVendibile(myrec)) { classi = 'bg-grey'; } if (!productStore.isDisponibile(myrec)) { classi = 'bg-red-1'; } } return classi; } onMounted(mounted); return { changeval, myvalue, myarrvalue, valori, filterFn, fieldsTable, checkIfShowRec, abortFilterFn, newvaluefuncfirst, getIcon, tools, selectText, getLabelValue, getOptionLabel, clear, mystr, searchOnGM, applyLabelColorBasedOnProductStatus, }; }, });