Update code: fixed bugs and added new features
This commit is contained in:
parent
ecc64c7b61
commit
2b40b2016b
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user