Update code: fixed bugs and added new features
This commit is contained in:
		
							
								
								
									
										47
									
								
								src/components/Form/FiltersType/Type18.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/components/Form/FiltersType/Type18.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| <script setup lang="ts"> | ||||
| import Select from '@/components/Select.vue' | ||||
| import SelectMulti from '@/components/SelectMulti.vue' | ||||
|  | ||||
| import DatePicker from '@/components/DatePicker.vue' | ||||
| import { selectedUid, selectedUppp, selectedPosko ,fetchData, items,itemsUp3, itemsPosko} from './reference'; | ||||
| fetchData(); | ||||
|  | ||||
| const departments = [ | ||||
|     { id: 1, name: 'Marketing', contact: 'Durward Reynolds' }, | ||||
|     { id: 2, name: 'HR', contact: 'Kenton Towne' }, | ||||
|     { id: 3, name: 'Sales', contact: 'Therese Wunsch' }, | ||||
|     { id: 4, name: 'Finance', contact: 'Benedict Kessler' }, | ||||
|     { id: 5, name: 'Customer service', contact: 'Katelyn Rohan' }, | ||||
|   ] | ||||
|  | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|   <div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center"> | ||||
|     <label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Unit Induk Distribusi/Wilayah:</label> | ||||
|  | ||||
|     <Select @update:selected="selectedUid($event)" :data="items" placeholder="Semua Unit Induk Distribusi/Wilayah" /> | ||||
|   </div> | ||||
|  | ||||
|   <div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center"> | ||||
|     <label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Unit Pelaksanaan Pelayanan Pelanggan:</label> | ||||
|  | ||||
|     <Select @update:selected="selectedUppp($event)" :data="itemsUp3" | ||||
|       placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" /> | ||||
|   </div> | ||||
|  | ||||
|   <div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center"> | ||||
|     <label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Posko:</label> | ||||
|  | ||||
|     <Select @update:selected="selectedPosko($event)" :data="itemsPosko" placeholder="Semua Posko" /> | ||||
|   </div> | ||||
|   <div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center"> | ||||
|     <label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Jenis Transaksi:</label> | ||||
|  | ||||
|     <SelectMulti :data="departments" placeholder="Semua Jenis Transaksi" /> | ||||
|   </div> | ||||
|   <div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center"> | ||||
|     <label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Periode Tanggal:</label> | ||||
|     <DatePicker  /> | ||||
|   </div> | ||||
| </template> | ||||
| @@ -1,8 +1,16 @@ | ||||
| <script setup lang="ts"> | ||||
|   import InputNumber from '@/components/Form/InputNumber.vue' | ||||
|   import Select from '@/components/Select.vue' | ||||
|   import DatePicker from '@/components/DatePicker.vue' | ||||
|   import { selectedUid, selectedUppp, selectedPosko ,fetchData, items,itemsUp3, itemsPosko} from './reference'; | ||||
| import { useTotalReport } from '@/stores/totalReport'; | ||||
|   fetchData(); | ||||
|   const changeMinReport = (value: any) => { | ||||
|     useTotalReport().setDataMin(value) | ||||
|   } | ||||
|   const changeMaxReport = (value: any) => { | ||||
|     useTotalReport().setDataMax(value) | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
| @@ -36,9 +44,9 @@ | ||||
|     <label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Lapor Ulang:</label> | ||||
|  | ||||
|     <div class="grid grid-flow-col auto-cols-auto gap-x-1.5"> | ||||
|       <Select placeholder="1" /> | ||||
|       <InputNumber :value="1" @change="changeMinReport($event.target.value)" /> | ||||
|       <small class="flex items-center">s/d</small> | ||||
|       <Select placeholder="2" /> | ||||
|       <InputNumber :value="1" @change="changeMaxReport($event.target.value)"/> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|   | ||||
| @@ -2,6 +2,39 @@ | ||||
|   import Select from '@/components/Select.vue' | ||||
|   import DatePicker from '@/components/DatePicker.vue' | ||||
|   import InputWithSuffix from '../InputWithSuffix.vue'; | ||||
| import { useTotalDuration } from '@/stores/totalDuration'; | ||||
| import { ref } from 'vue'; | ||||
|   const data = [ | ||||
|     | ||||
|     { | ||||
|       id : 1, | ||||
|       name : 'Dibawah  / Sesuai SLA (<= 45 menit)' | ||||
|     }, | ||||
|     { | ||||
|       id : 2, | ||||
|       name : 'Melebihi SLA (> 45 menit)' | ||||
|     } | ||||
|    | ||||
|   ] | ||||
|   const triggerInput = ref(false) | ||||
|   const changeDuration = (value: any) => { | ||||
|     if(value.id === 0 ){ | ||||
|       console.log('Durasi Menit') | ||||
|       useTotalDuration().setDataMin(0) | ||||
|       useTotalDuration().setDataMax(5) | ||||
|       triggerInput.value = false | ||||
|     }else if(value.id === 1){ | ||||
|       useTotalDuration().setDataMin(0) | ||||
|       useTotalDuration().setDataMax(45) | ||||
|       console.log('Dibawah  / Sesuai SLA (<= 45 menit)') | ||||
|       triggerInput.value = true | ||||
|     }else{ | ||||
|       useTotalDuration().setDataMin(46) | ||||
|       useTotalDuration().setDataMax(7*60*24) | ||||
|       triggerInput.value = true | ||||
|       console.log('Melebihi SLA (> 45 menit)') | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
| @@ -35,12 +68,12 @@ | ||||
|     <label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Durasi:</label> | ||||
|  | ||||
|     <div class="flex flex-col gap-y-1"> | ||||
|       <Select placeholder="Durasi Menit" /> | ||||
|       <Select @update:selected="changeDuration($event)" :data="data" placeholder="Durasi Menit" /> | ||||
|  | ||||
|       <div class="grid grid-flow-col auto-cols-auto gap-x-1.5"> | ||||
|         <InputWithSuffix /> | ||||
|         <InputWithSuffix :value="useTotalDuration().getDataMin()" :disabled=triggerInput /> | ||||
|         <small class="flex items-center">s/d</small> | ||||
|         <InputWithSuffix /> | ||||
|         <InputWithSuffix :value="useTotalDuration().getDataMax()" :disabled="triggerInput" /> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
|   | ||||
| @@ -15,3 +15,4 @@ export { default as Type14 } from '@/components/Form/FiltersType/Type14.vue' | ||||
| export { default as Type15 } from '@/components/Form/FiltersType/Type15.vue'  | ||||
| export { default as Type16 } from '@/components/Form/FiltersType/Type16.vue'  | ||||
| export { default as Type17 } from '@/components/Form/FiltersType/Type17.vue'  | ||||
| export { default as Type18 } from '@/components/Form/FiltersType/Type18.vue'  | ||||
|   | ||||
							
								
								
									
										39
									
								
								src/components/Form/InputNumber.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/components/Form/InputNumber.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| <script setup lang="ts"> | ||||
|   const props = defineProps({ | ||||
|     placeholder: { | ||||
|         type: String, | ||||
|         default: "", | ||||
|     }, | ||||
|     disabled: { | ||||
|         type: Boolean, | ||||
|         default: false, | ||||
|     }, | ||||
|     readonly: { | ||||
|         type: Boolean, | ||||
|         default: false, | ||||
|     }, | ||||
|     value: { | ||||
|         type: Number, | ||||
|         default: "", | ||||
|     }, | ||||
|   }) | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|   <div class="relative w-full overflow-hidden rounded-lg bg-gray-200"> | ||||
|     <input | ||||
|       autocomplete="off" | ||||
|       type="number" | ||||
|       :value ="props.value" | ||||
|       :placeholder="placeholder" | ||||
|       :disabled="disabled" | ||||
|       :readonly="readonly" | ||||
|       inputmode="numeric" | ||||
|       pattern="[0-9.]*" | ||||
|        | ||||
|       oninput="this.value = this.value.replace(/[^0-9.]/g, '')" | ||||
|       onfocus="this.value = this.value.replace(/[^0-9.]/g, '')" | ||||
|       class="w-full px-4 py-2 text-sm leading-6 placeholder:text-gray-400 text-gray-900 border-0 border-transparent rounded-lg outline-0 bg-gray-200 focus:outline-0 focus:border-0 focus:ring-0" | ||||
|     /> | ||||
|   </div> | ||||
| </template> | ||||
| @@ -11,7 +11,11 @@ | ||||
|     readonly: { | ||||
|         type: Boolean, | ||||
|         default: false, | ||||
|     } | ||||
|     }, | ||||
|     value: { | ||||
|         type: Number, | ||||
|         default: "", | ||||
|     }, | ||||
|   }) | ||||
| </script> | ||||
|  | ||||
| @@ -20,6 +24,7 @@ | ||||
|     <input | ||||
|       autocomplete="off" | ||||
|       type="text" | ||||
|       :value ="props.value" | ||||
|       :placeholder="placeholder" | ||||
|       :disabled="disabled" | ||||
|       :readonly="readonly" | ||||
|   | ||||
| @@ -153,7 +153,7 @@ onMounted(() => { | ||||
|         console.log(error) | ||||
|     }) | ||||
|     filters.setConfig({ | ||||
|         type: 'type-1', | ||||
|         type: 'type-18', | ||||
|         reportButton: true | ||||
|     }) | ||||
| }) | ||||
|   | ||||
| @@ -183,8 +183,6 @@ const position = { of: '#data' }; | ||||
| const showIndicator = ref(true); | ||||
| const shading = ref(true); | ||||
| const showPane = ref(true); | ||||
|  | ||||
|  | ||||
| const data = ref<any[]>([]) | ||||
| const dataDetail = ref<any>({}) | ||||
| const showDetail = ref(false) | ||||
| @@ -230,8 +228,8 @@ query gangguan ($minJmlLapor: Int!, $maxJmlLapor: Int!, $dateFrom: Date!, $dateT | ||||
|   } | ||||
| }`; | ||||
|  const { onResult, onError, loading, refetch  } = useQuery(GET_GANGGUAN_MELAPOR_LEBIHDARI_SATU_KALI, { | ||||
|         minJmlLapor: 0, | ||||
|         maxJmlLapor: 0, | ||||
|         minJmlLapor: 1, | ||||
|         maxJmlLapor: 1, | ||||
|         dateFrom: new Date().toISOString().slice(0, 10), | ||||
|         dateTo: new Date().toISOString().slice(0, 10), | ||||
|         posko: "", | ||||
|   | ||||
							
								
								
									
										107
									
								
								src/components/SelectMulti.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/components/SelectMulti.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | ||||
| <script setup lang="ts"> | ||||
| interface DataItem { | ||||
|   id: number; | ||||
|   name: string; | ||||
| } | ||||
|  | ||||
| import { ref, computed, onMounted } from 'vue' | ||||
| import { | ||||
|   Combobox, | ||||
|   ComboboxInput, | ||||
|   ComboboxButton, | ||||
|   ComboboxOptions, | ||||
|   ComboboxOption, | ||||
|   TransitionRoot | ||||
| } from '@headlessui/vue' | ||||
| import { CheckIcon, ChevronUpDownIcon } from '@heroicons/vue/20/solid' | ||||
|  | ||||
| const props = defineProps({ | ||||
|   placeholder: { | ||||
|     type: String, | ||||
|     default: '' | ||||
|   }, | ||||
|   data: { | ||||
|     type: Array as () => DataItem[], | ||||
|     default: [] | ||||
|   } | ||||
| }) | ||||
| const emit = defineEmits(["update:selected"]) | ||||
|  | ||||
| const data = computed(() => [{ id: 0, name: props.placeholder }, ...props.data]); | ||||
|  | ||||
| let selected = ref<DataItem[]>([data.value[0]]) | ||||
| let query = ref('') | ||||
| let filteredData = computed(() => | ||||
|   query.value === '' | ||||
|     ? data.value | ||||
|     : data.value.filter((item: DataItem) => | ||||
|       item.name | ||||
|         .toLowerCase() | ||||
|         .replace(/\s+/g, '') | ||||
|         .includes(query.value.toLowerCase().replace(/\s+/g, '')) | ||||
|     ) | ||||
| ) | ||||
|  | ||||
| const show = ref(false) | ||||
|  const removeJenis = (item: DataItem) => { | ||||
|     selected.value = selected.value.filter((i) => i.id !== item.id) | ||||
|   } | ||||
| onMounted(() => { | ||||
| }) | ||||
|  | ||||
|  | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|   <Combobox @update:modelValue="value => emit('update:selected', value)" v-model="selected" v-slot="{ open }" multiple=""> | ||||
|     <div class="relative mt-1"> | ||||
|        | ||||
|       <div | ||||
|         class="relative w-full cursor-default overflow-hidden rounded-lg bg-gray-200 text-left focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-teal-300 sm:text-sm"> | ||||
|         <ComboboxInput class="w-full border-none py-2 pl-3 pr-10 bg-gray-200 text-sm leading-5 text-gray-900 focus:ring-0" | ||||
|           :displayValue="(item: any) => (show || open ? '' : item.name)" @change="query = $event.target.value" | ||||
|           @click="show = true" @blur="show = false" defaultValue="" /> | ||||
|  | ||||
|         <ComboboxButton id="Test" class="absolute inset-y-0 right-0 flex items-center pr-2"> | ||||
|           <ChevronUpDownIcon class="h-5 w-5 text-gray-400" aria-hidden="true" /> | ||||
|         </ComboboxButton> | ||||
|       </div> | ||||
|       <span class="block flex flex-wrap gap-2"> | ||||
|         <span v-if="selected.length == 0" class="p-0.5">Empty</span> | ||||
|         <span v-for="item in selected" :key="item.id" class="inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-700/10"> | ||||
|           <span>{{ item.name }}</span> | ||||
|           <svg class="h-4 w-4 cursor-pointer" fill="none" stroke="currentColor" viewBox="0 0 24 24" | ||||
|             xmlns="http://www.w3.org/2000/svg" @click.stop.prevent="removeJenis(item)"> | ||||
|             <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> | ||||
|           </svg> | ||||
|         </span> | ||||
|       </span> | ||||
|       <TransitionRoot :show="show || open" leave="transition ease-in duration-100" leaveFrom="opacity-100" | ||||
|         leaveTo="opacity-0" @after-leave="query = ''"> | ||||
|         <ComboboxOptions static | ||||
|           class="absolute mt-1 z-10 max-h-60 w-full overflow-auto rounded-md bg-gray-200 py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm"> | ||||
|           <div v-if="filteredData.length === 0 && query !== ''" | ||||
|             class="relative cursor-default select-none py-2 px-4 text-gray-700"> | ||||
|             Nothing found. | ||||
|           </div> | ||||
|  | ||||
|           <ComboboxOption v-for="item in filteredData" as="template" :key="item.id" :value="item" | ||||
|             v-slot="{ selected, active }"> | ||||
|             <li class="relative cursor-default select-none py-2 pl-10 pr-4" :class="{ | ||||
|               'bg-teal-600 text-white': active, | ||||
|               'text-gray-900': !active | ||||
|             }"> | ||||
|               <span class="block truncate" :class="{ 'font-medium': selected, 'font-normal': !selected }"> | ||||
|                 {{ item.name }} | ||||
|               </span> | ||||
|               <span v-if="selected" class="absolute inset-y-0 left-0 flex items-center pl-3" | ||||
|                 :class="{ 'text-white': active, 'text-teal-600': !active }"> | ||||
|                 <CheckIcon class="h-5 w-5" aria-hidden="true" /> | ||||
|               </span> | ||||
|             </li> | ||||
|           </ComboboxOption> | ||||
|         </ComboboxOptions> | ||||
|       </TransitionRoot> | ||||
|     </div> | ||||
|   </Combobox> | ||||
| </template> | ||||
| @@ -7,7 +7,7 @@ export const useDateStore = defineStore('date', () => { | ||||
|         dateValue.value = value | ||||
|     } | ||||
|     const getDateValue = () => { | ||||
|         return dateValue.value | ||||
|         return dateValue.value; | ||||
|     } | ||||
|     return { | ||||
|         setDateValue, | ||||
|   | ||||
| @@ -19,6 +19,7 @@ import { | ||||
|   Type15, | ||||
|   Type16, | ||||
|   Type17, | ||||
|   Type18 | ||||
| } from '@/components/Form/FiltersType' | ||||
|  | ||||
| const test1: { [key: string]: any } = { | ||||
| @@ -38,7 +39,8 @@ const test1: { [key: string]: any } = { | ||||
|   'type-14': Type14, | ||||
|   'type-15': Type15, | ||||
|   'type-16': Type16, | ||||
|   'type-17': Type17 | ||||
|   'type-17': Type17, | ||||
|   'type-18': Type18 | ||||
| } | ||||
|  | ||||
| const getFilters = (type: string): VueElement => { | ||||
|   | ||||
| @@ -2,20 +2,20 @@ import { ref } from 'vue' | ||||
| import { defineStore } from 'pinia' | ||||
|  | ||||
| export const useTotalDuration = defineStore('totalDuration', () => { | ||||
|     const totalMin = ref() | ||||
|     const totalMax = ref() | ||||
|     const setDataMin = (value: Number) => { | ||||
|         totalMax.value = value | ||||
|     } | ||||
|     const getDataMin = () => { | ||||
|         return totalMax.value | ||||
|     } | ||||
|     const setDataMax = (value: Number) => { | ||||
|     const totalMin = ref(1) | ||||
|     const totalMax = ref(1) | ||||
|     const setDataMin = (value: any) => { | ||||
|         totalMin.value = value | ||||
|     } | ||||
|     const getDataMax = () => { | ||||
|     const getDataMin = () => { | ||||
|         return totalMin.value | ||||
|     } | ||||
|     const setDataMax = (value: any) => { | ||||
|         totalMax.value = value | ||||
|     } | ||||
|     const getDataMax = () => { | ||||
|         return totalMax.value | ||||
|     } | ||||
|     return { | ||||
|         setDataMin, | ||||
|         getDataMin, | ||||
|   | ||||
| @@ -2,20 +2,20 @@ import { ref } from 'vue' | ||||
| import { defineStore } from 'pinia' | ||||
|  | ||||
| export const useTotalReport = defineStore('totalReport', () => { | ||||
|     const totalMin = ref() | ||||
|     const totalMax = ref() | ||||
|     const setDataMin = (value: Number) => { | ||||
|         totalMax.value = value | ||||
|     } | ||||
|     const getDataMin = () => { | ||||
|         return totalMax.value | ||||
|     } | ||||
|     const setDataMax = (value: Number) => { | ||||
|     const totalMin = ref(1) | ||||
|     const totalMax = ref(1) | ||||
|     const setDataMin = (value: any) => { | ||||
|         totalMin.value = value | ||||
|     } | ||||
|     const getDataMax = () => { | ||||
|     const getDataMin = () => { | ||||
|         return totalMin.value | ||||
|     } | ||||
|     const setDataMax = (value: any) => { | ||||
|         totalMax.value = value | ||||
|     } | ||||
|     const getDataMax = () => { | ||||
|         return totalMax.value | ||||
|     } | ||||
|     return { | ||||
|         setDataMin, | ||||
|         getDataMin, | ||||
|   | ||||
| @@ -6,6 +6,8 @@ const instance = axios.create({ | ||||
|  | ||||
|  | ||||
| const getUid = async () => await instance.get('/uid'); | ||||
| const getMedia = async() => await instance.get('/media'); | ||||
| const getJenisTransaksi = async() => await instance.get('/jenisTransaksi'); | ||||
| const getUp3 = async ( | ||||
|     uid: number, | ||||
| ) => await instance.get('/up3?uid=' + uid); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user