Update code: fixed bugs and added new features

This commit is contained in:
probdg 2024-02-03 16:32:05 +07:00
parent ecc64c7b61
commit 2b40b2016b
14 changed files with 275 additions and 33 deletions

View 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>

View File

@ -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>

View File

@ -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>

View File

@ -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'

View 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>

View File

@ -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"

View File

@ -153,7 +153,7 @@ onMounted(() => {
console.log(error)
})
filters.setConfig({
type: 'type-1',
type: 'type-18',
reportButton: true
})
})

View File

@ -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: "",

View 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>

View File

@ -7,7 +7,7 @@ export const useDateStore = defineStore('date', () => {
dateValue.value = value
}
const getDateValue = () => {
return dateValue.value
return dateValue.value;
}
return {
setDateValue,

View File

@ -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 => {

View File

@ -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,

View File

@ -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,

View File

@ -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);