Merge branch 'development' of github.com:defuj/eis into dev-bagus

This commit is contained in:
kur0nek-o 2023-10-27 11:07:47 +07:00
commit 53e05e9891
7 changed files with 150 additions and 80 deletions

View File

@ -1607,6 +1607,10 @@ select {
--tw-divide-opacity: 0.1; --tw-divide-opacity: 0.1;
} }
.divide-opacity-100 > :not([hidden]) ~ :not([hidden]) {
--tw-divide-opacity: 1;
}
.overflow-auto { .overflow-auto {
overflow: auto; overflow: auto;
} }
@ -1885,8 +1889,13 @@ select {
--tw-bg-opacity: 0.8; --tw-bg-opacity: 0.8;
} }
<<<<<<< HEAD
.bg-none { .bg-none {
background-image: none; background-image: none;
=======
.bg-opacity-100 {
--tw-bg-opacity: 1;
>>>>>>> 28382959d66e99e037740e0f946d7fa2ff14e3f5
} }
.fill-gray-500 { .fill-gray-500 {
@ -2392,6 +2401,11 @@ select {
color: rgb(153 153 0 / var(--tw-text-opacity)); color: rgb(153 153 0 / var(--tw-text-opacity));
} }
.text-gray-200 {
--tw-text-opacity: 1;
color: rgb(229 231 235 / var(--tw-text-opacity));
}
.text-opacity-40 { .text-opacity-40 {
--tw-text-opacity: 0.4; --tw-text-opacity: 0.4;
} }
@ -3302,6 +3316,10 @@ select {
display: none; display: none;
} }
.md\:h-16 {
height: 4rem;
}
.md\:w-1\/2 { .md\:w-1\/2 {
width: 50%; width: 50%;
} }
@ -3358,6 +3376,16 @@ select {
padding-bottom: 0px; padding-bottom: 0px;
} }
.md\:px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.md\:py-6 {
padding-top: 1.5rem;
padding-bottom: 1.5rem;
}
.md\:pl-4 { .md\:pl-4 {
padding-left: 1rem; padding-left: 1rem;
} }
@ -3398,6 +3426,10 @@ select {
margin-top: 3rem; margin-top: 3rem;
} }
.lg\:mt-6 {
margin-top: 1.5rem;
}
.lg\:block { .lg\:block {
display: block; display: block;
} }
@ -3449,6 +3481,21 @@ select {
padding-right: 2rem; padding-right: 2rem;
} }
.lg\:px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.lg\:py-6 {
padding-top: 1.5rem;
padding-bottom: 1.5rem;
}
.lg\:text-3xl {
font-size: 1.875rem;
line-height: 2.25rem;
}
.lg\:text-xs { .lg\:text-xs {
font-size: 0.75rem; font-size: 0.75rem;
line-height: 1rem; line-height: 1rem;

View File

@ -1,6 +1,6 @@
<template> <template>
<TransitionRoot :show="command.open" as="template" @after-leave="onQueryChange('')" appear> <TransitionRoot :show="command.open" as="template" @after-leave="onQueryChange('')" appear>
<Dialog as="div" class="relative z-10" @close="onClose"> <Dialog as="div" class="relative z-10" @close="command.closeCommand">
<TransitionChild as="template" enter="ease-out duration-300" enter-from="opacity-0" enter-to="opacity-100" <TransitionChild as="template" enter="ease-out duration-300" enter-from="opacity-0" enter-to="opacity-100"
leave="ease-in duration-200" leave-from="opacity-100" leave-to="opacity-0"> leave="ease-in duration-200" leave-from="opacity-100" leave-to="opacity-0">
<div class="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-25 backdrop-blur" /> <div class="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-25 backdrop-blur" />
@ -10,8 +10,9 @@
<TransitionChild as="template" enter="ease-out duration-300" enter-from="opacity-0 scale-95" <TransitionChild as="template" enter="ease-out duration-300" enter-from="opacity-0 scale-95"
enter-to="opacity-100 scale-100" leave="ease-in duration-200" leave-from="opacity-100 scale-100" enter-to="opacity-100 scale-100" leave="ease-in duration-200" leave-from="opacity-100 scale-100"
leave-to="opacity-0 scale-95"> leave-to="opacity-0 scale-95">
<!-- max-w-2xl mx-auto overflow-hidden transition-all transform bg-white bg-opacity-80 divide-y divide-gray-500 shadow-2xl divide-opacity-10 rounded-xl ring-0 ring-black ring-opacity-5 -->
<DialogPanel <DialogPanel
class="max-w-2xl mx-auto overflow-hidden transition-all transform bg-white divide-y divide-gray-500 shadow-2xl divide-opacity-10 rounded-xl bg-opacity-80 ring-0 ring-black ring-opacity-5"> class="max-w-2xl mx-auto overflow-hidden transition-all transform bg-white bg-opacity-100 divide-y divide-gray-500 shadow-2xl divide-opacity-10 rounded-xl ring-0 ring-black ring-opacity-5">
<Combobox> <Combobox>
<div class="relative"> <div class="relative">
<MagnifyingGlassIcon <MagnifyingGlassIcon
@ -29,10 +30,10 @@
class="px-3 mt-4 mb-2 text-xs font-semibold text-gray-900"> class="px-3 mt-4 mb-2 text-xs font-semibold text-gray-900">
Terakhir Diakses Terakhir Diakses
</h2> </h2>
<ul class="text-sm text-gray-700"> <!-- <ul class="text-sm text-gray-700">
<ComboboxOption as="template" v-for="menu in query === '' ? recent : filteredMenus" <ComboboxOption as="template" v-for="menu in query === '' ? recent : filteredMenus"
:key="menu.path" v-slot="{ active }"> :key="menu.path" v-slot="{ active }">
<li @click="openMenu(menu)" <li @click="command.openMenu(menu)"
:class="['flex flex-row cursor-pointer select-none items-center rounded-md px-3 py-2', active && 'bg-gray-900 bg-opacity-5 text-gray-900']"> :class="['flex flex-row cursor-pointer select-none items-center rounded-md px-3 py-2', active && 'bg-gray-900 bg-opacity-5 text-gray-900']">
<component v-if="menu.path.includes('/gangguan/')" :is="navigationIcon[0]" <component v-if="menu.path.includes('/gangguan/')" :is="navigationIcon[0]"
alt="icon" alt="icon"
@ -73,6 +74,55 @@
Buka Buka
</span> </span>
</li>
</ComboboxOption>
</ul> -->
<ul class="text-sm text-gray-700">
<ComboboxOption as="template" v-for="menu in query === '' ? recent : filteredMenus"
:key="menu.path" v-slot="{ active }">
<li @click="command.openMenu(menu)"
:class="['flex flex-row cursor-pointer select-none items-center rounded-md px-3 py-2', active && 'bg-primary-500 text-white']">
<component v-if="menu.path.includes('/gangguan/')" :is="navigationIcon[0]"
alt="icon"
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
<component v-else-if="menu.path.includes('/keluhan/')"
:is="navigationIcon[1]" alt="icon"
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
<component v-else-if="menu.path.includes('/monalisa/')"
:is="navigationIcon[2]" alt="icon"
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
<component v-else-if="menu.path.includes('/check-in-out/')"
:is="navigationIcon[3]" alt="icon"
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
<component v-else-if="menu.path.includes('/anomali-pengaduan/')"
:is="navigationIcon[4]" alt="icon"
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
<component v-else-if="menu.path.includes('/ctt-kwh-periksa/')"
:is="navigationIcon[5]" alt="icon"
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
<component v-else-if="menu.path.includes('/material/')"
:is="navigationIcon[6]" alt="icon"
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
<component v-else-if="menu.path.includes('/transaksi/')"
:is="navigationIcon[7]" alt="icon"
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
<component v-else :is="navigationIcon[8]" alt="icon"
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
<div class="flex flex-col flex-1 ml-3 space-y-1">
<span
:class="[active ? 'text-white' : 'text-gray-800', 'text-sm font-medium line-clamp-1']">
{{ menu.name }}
</span>
<span
:class="[active ? 'text-white' : 'text-gray-500', 'text-xs line-clamp-1']">
{{ menu.path.replace('/home/', '') }}
</span>
</div>
<span v-if="active" class="flex-none ml-3 text-gray-200">
Buka
</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
</ul> </ul>
@ -97,9 +147,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, watch } from 'vue' import { computed, ref } from 'vue'
import { MagnifyingGlassIcon } from '@heroicons/vue/20/solid' import { MagnifyingGlassIcon } from '@heroicons/vue/20/solid'
import { DocumentTextIcon } from '@heroicons/vue/24/outline'
import { import {
Combobox, Combobox,
ComboboxInput, ComboboxInput,
@ -110,14 +159,11 @@ import {
TransitionChild, TransitionChild,
TransitionRoot, TransitionRoot,
} from '@headlessui/vue' } from '@headlessui/vue'
import { useRouter, type RouteRecordRaw } from 'vue-router' import { routes } from '@/router'
import { routes, extractLeafRoutes } from '@/router'
import { useCommandPalattesStore } from '@/stores/command' import { useCommandPalattesStore } from '@/stores/command'
import { navigationIcon } from '@/utils/route' import { navigationIcon } from '@/utils/route'
const command = useCommandPalattesStore() const command = useCommandPalattesStore()
const route = useRouter()
const recent = computed(() => query.value === '' ? command.readRecent() : []) const recent = computed(() => query.value === '' ? command.readRecent() : [])
const query = ref('') const query = ref('')
const filteredMenus = computed(() => const filteredMenus = computed(() =>
@ -125,7 +171,6 @@ const filteredMenus = computed(() =>
? [] ? []
: command.searchRoutesByName(routes, query.value) : command.searchRoutesByName(routes, query.value)
) )
const onClose = () => command.open = false
let debounceTimeout: ReturnType<typeof setTimeout> | null = null; let debounceTimeout: ReturnType<typeof setTimeout> | null = null;
const onQueryChange = (value: string) => { const onQueryChange = (value: string) => {
@ -142,10 +187,4 @@ const onQueryChange = (value: string) => {
}, 300); }, 300);
} }
const openMenu = (menu: RouteRecordRaw) => {
command.addRecent(menu)
route.push(menu.path)
onClose()
}
</script> </script>

View File

@ -24,19 +24,9 @@ watch(route, (to, _) => {
closeSideBar() closeSideBar()
}) })
// onMounted(() => { onMounted(() => {
// menu.menuSelected = router.currentRoute.value.fullPath menu.expandCurrentActiveMenu()
})
// if (menu.menuSelected !== '/' && menu.menuSelected !== '/home' && menu.menuSelected.includes('/home')) {
// const result = splitRoutePath(menu.menuSelected)
// for (const route of result) {
// if (route !== '/home') {
// menu.toggleSidebarMenu(route, true)
// }
// }
// }
// })
const isMenu = (name: string) => { const isMenu = (name: string) => {
return menu.menuSelected === name return menu.menuSelected === name
@ -75,7 +65,7 @@ const closeSideBar = () => menu.toggleSidebar()
</TransitionChild> </TransitionChild>
<div class="flex items-center flex-shrink-0 px-4"> <div class="flex items-center flex-shrink-0 px-4">
<RouterLink to="/"> <RouterLink to="/">
<img class="w-auto h-16" :src="IconApp" alt="PLN" /> <img class="w-auto h-12 md:h-16" :src="IconApp" alt="PLN" />
</RouterLink> </RouterLink>
</div> </div>
<div class="flex-1 h-0 mt-5 overflow-y-auto"> <div class="flex-1 h-0 mt-5 overflow-y-auto">

View File

@ -1,6 +1,6 @@
<template> <template>
<main class="flex-1 px-4 overflow-y-auto bg-white md:mr-3 sm:px-3 md:px-4 rounded-t-2xl md:rounded-t-3xl no-scroll-bar"> <main class="flex-1 px-4 overflow-y-auto bg-white md:mr-3 sm:px-3 md:px-6 rounded-t-2xl md:rounded-t-3xl no-scroll-bar">
<div v-if="route.path !== '/home'" class="pt-4 max-w-7xl"> <div v-if="route.path !== '/home'" class="mt-4 lg:mt-6 max-w-7xl">
<h1 class="text-xl font-medium md:text-3xl text-dark">{{ currentRouteName }}</h1> <h1 class="text-xl font-medium md:text-3xl text-dark">{{ currentRouteName }}</h1>
</div> </div>
<div class="mt-2 sm:mt-4 dx-viewport"> <div class="mt-2 sm:mt-4 dx-viewport">

View File

@ -16,7 +16,7 @@
</h2> </h2>
<div class="flex flex-col w-full space-y-3" v-for="menu in query === '' ? recent : filteredMenus" <div class="flex flex-col w-full space-y-3" v-for="menu in query === '' ? recent : filteredMenus"
:key="menu.path"> :key="menu.path">
<div @click="openMenu(menu)" class="group"> <div @click="command.openMenu(menu)" class="group">
<div <div
class="flex flex-row items-center justify-between px-3 py-2 rounded-md cursor-pointer select-none group-hover:bg-primary-500 group-hover:text-white group-hover:bg-opacity-80"> class="flex flex-row items-center justify-between px-3 py-2 rounded-md cursor-pointer select-none group-hover:bg-primary-500 group-hover:text-white group-hover:bg-opacity-80">
<component v-if="menu.path.includes('/gangguan/')" :is="navigationIcon[0]" alt="icon" <component v-if="menu.path.includes('/gangguan/')" :is="navigationIcon[0]" alt="icon"
@ -63,17 +63,15 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { readData, writeData } from '@/utils/storage'
import { MagnifyingGlassIcon } from '@heroicons/vue/20/solid'; import { MagnifyingGlassIcon } from '@heroicons/vue/20/solid';
import { computed, onMounted, ref, watch } from 'vue' import { computed, ref } from 'vue'
import { useCommandPalattesStore } from '@/stores/command' import { useCommandPalattesStore } from '@/stores/command'
import { IconApp } from '@/utils/icons' import { IconApp } from '@/utils/icons'
import { useRouter, type RouteRecordRaw } from 'vue-router' import { type RouteRecordRaw } from 'vue-router'
import { routes, extractLeafRoutes } from '@/router' import { routes, extractLeafRoutes } from '@/router'
import { navigationIcon } from '@/utils/route'; import { navigationIcon } from '@/utils/route';
const command = useCommandPalattesStore() const command = useCommandPalattesStore()
const route = useRouter()
const recent = computed(() => query.value === '' ? command.readRecent() : []) const recent = computed(() => query.value === '' ? command.readRecent() : [])
const query = ref('') const query = ref('')
@ -87,27 +85,5 @@ const filteredMenus = computed(() =>
? [] ? []
: searchRoutesByName(routes, query.value) : searchRoutesByName(routes, query.value)
) )
const onClose = () => command.open = false
let debounceTimeout: ReturnType<typeof setTimeout> | null = null;
const onQueryChange = (value: string) => {
if (debounceTimeout) {
clearTimeout(debounceTimeout);
}
debounceTimeout = setTimeout(() => {
// check if value is empty or only spaces
if (value.trim() === '') {
query.value = ''
return
}
query.value = value
}, 300);
}
const openMenu = (menu: RouteRecordRaw) => {
command.addRecent(menu)
route.push(menu.path)
onClose()
}
</script> </script>

View File

@ -1,12 +1,14 @@
import { ref } from 'vue' import { ref } from 'vue'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import type { RouteRecordRaw } from 'vue-router' import { useRouter, type RouteRecordRaw } from 'vue-router'
import { readDataJson, writeDataJson } from '@/utils/storage' import { readDataJson, writeDataJson } from '@/utils/storage'
import { extractLeafRoutes } from '@/router' import { extractLeafRoutes } from '@/router'
import { useMenuStore } from '@/stores/menu'
export const useCommandPalattesStore = defineStore('command_palettes', () => { export const useCommandPalattesStore = defineStore('command_palettes', () => {
const open = ref(false) const open = ref(false)
const route = useRouter()
const menu = useMenuStore()
const controlStatus = ref(false) const controlStatus = ref(false)
const keyFStatus = ref(false) const keyFStatus = ref(false)
@ -82,6 +84,19 @@ export const useCommandPalattesStore = defineStore('command_palettes', () => {
return matchingRoutes return matchingRoutes
} }
const openMenu = (routeTarget: RouteRecordRaw) => {
addRecent(routeTarget)
route.push(routeTarget.path)
closeCommand()
setTimeout(() => {
menu.expandCurrentActiveMenu()
}, 200);
}
const closeCommand = () => {
open.value = false
}
return { return {
open, open,
showCommandPalettes, showCommandPalettes,
@ -91,6 +106,8 @@ export const useCommandPalattesStore = defineStore('command_palettes', () => {
addRecent, addRecent,
readRecent, readRecent,
searchRoutesByName, searchRoutesByName,
searchRoutesPath searchRoutesPath,
openMenu,
closeCommand
} }
}) })

View File

@ -17,7 +17,7 @@ export const useMenuStore = defineStore('menu', () => {
const menuSelected = ref(route.fullPath) const menuSelected = ref(route.fullPath)
const toggleSidebar = () => (sidebarOpen.value = !sidebarOpen.value) const toggleSidebar = () => (sidebarOpen.value = !sidebarOpen.value)
const toggleSidebarMenu = (path: string, newExpanded: boolean): void => { const toggleSidebarMenu = (path: string, newExpanded: boolean): void => {
// console.log('expanded', path); console.log('expanded', path);
const toggleItemExpanded = (items: MenuItemModel[]): void => { const toggleItemExpanded = (items: MenuItemModel[]): void => {
for (const item of items) { for (const item of items) {
@ -40,22 +40,6 @@ export const useMenuStore = defineStore('menu', () => {
} }
const toggleSidebarDesktop = () => (sidebarShowed.value = !sidebarShowed.value) const toggleSidebarDesktop = () => (sidebarShowed.value = !sidebarShowed.value)
onMounted(() => {
const menuData = convertRouteToMenu(routes.at(0)?.children || [])
navigation.value = menuData
menuSelected.value = router.currentRoute.value.fullPath
if (menuSelected.value !== '/' && menuSelected.value !== '/home' && menuSelected.value.includes('/home')) {
const result = splitRoutePath(menuSelected.value)
for (const route of result) {
if (route !== '/home') {
toggleSidebarMenu(route, true)
}
}
}
})
watch(router, (value) => { watch(router, (value) => {
if (value.currentRoute.value.fullPath === '/' || value.currentRoute.value.fullPath === '/home') { if (value.currentRoute.value.fullPath === '/' || value.currentRoute.value.fullPath === '/home') {
for (const item of navigation.value) { for (const item of navigation.value) {
@ -79,7 +63,24 @@ export const useMenuStore = defineStore('menu', () => {
} }
}) })
const expandCurrentActiveMenu = (): void => {
const menuData = convertRouteToMenu(routes.at(0)?.children || [])
navigation.value = menuData
menuSelected.value = router.currentRoute.value.fullPath
if (menuSelected.value !== '/' && menuSelected.value !== '/home' && menuSelected.value.includes('/home')) {
const result = splitRoutePath(menuSelected.value)
for (const route of result) {
if (route !== '/home') {
toggleSidebarMenu(route, true)
}
}
}
}
return { return {
expandCurrentActiveMenu,
navigation, navigation,
toggleSidebar, toggleSidebar,
sidebarOpen, sidebarOpen,