feat(app): tests
This commit is contained in:
parent
eefc7ba4ac
commit
2b37e59afc
@ -26,6 +26,7 @@
|
|||||||
<link rel="stylesheet" href="/css/components/media.css">
|
<link rel="stylesheet" href="/css/components/media.css">
|
||||||
<link rel="stylesheet" href="/css/components/menu.css">
|
<link rel="stylesheet" href="/css/components/menu.css">
|
||||||
<link rel="stylesheet" href="/css/_flatpickr.css">
|
<link rel="stylesheet" href="/css/_flatpickr.css">
|
||||||
|
<link rel="stylesheet" href="/css/animation.css">
|
||||||
<title>LiveMonitor</title>
|
<title>LiveMonitor</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
92
live_monitor_vue/public/css/animation.css
Normal file
92
live_monitor_vue/public/css/animation.css
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/* Определение анимации */
|
||||||
|
@keyframes slide-left {
|
||||||
|
from {
|
||||||
|
transform: translateX(-100vw); /* Старт с -100% по оси X, чтобы меню было скрыто */
|
||||||
|
opacity: 0; /* Начальная прозрачность для плавного появления */
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translateX(0vw); /* Конечное положение: на месте */
|
||||||
|
opacity: 1; /* Полная видимость */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes appear-opacity {
|
||||||
|
from {
|
||||||
|
opacity: 0; /* Начальная прозрачность для плавного появления */
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1; /* Полная видимость */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.appear-opacity-100 {
|
||||||
|
animation: appear-opacity 0.1s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.appear-opacity-200 {
|
||||||
|
animation: appear-opacity 0.2s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.appear-opacity-300 {
|
||||||
|
animation: appear-opacity 0.3s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.appear-opacity-400 {
|
||||||
|
animation: appear-opacity 0.4s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.appear-opacity-500 {
|
||||||
|
animation: appear-opacity 0.5s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.appear-opacity-600 {
|
||||||
|
animation: appear-opacity 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.appear-opacity-700 {
|
||||||
|
animation: appear-opacity 0.7s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.appear-opacity-800 {
|
||||||
|
animation: appear-opacity 0.8s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.appear-opacity-900 {
|
||||||
|
animation: appear-opacity 0.9s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left-100 {
|
||||||
|
animation: slide-left 0.1s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left-200 {
|
||||||
|
animation: slide-left 0.2s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left-300 {
|
||||||
|
animation: slide-left 0.3s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left-400 {
|
||||||
|
animation: slide-left 0.4s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left-500 {
|
||||||
|
animation: slide-left 0.5s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left-600 {
|
||||||
|
animation: slide-left 0.6s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left-700 {
|
||||||
|
animation: slide-left 0.7s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left-800 {
|
||||||
|
animation: slide-left 0.8s ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-left-900 {
|
||||||
|
animation: slide-left 0.9s ease-out forwards;
|
||||||
|
}
|
||||||
@ -1,11 +1,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import MenuList from './MenuList.vue'
|
import MenuList from './MenuList/MenuList.vue'
|
||||||
import MobileMenu from './MobileMenu.vue'
|
import MobileMenu from './AppContainerMobileMenu.vue'
|
||||||
import LeftPanel from './AppContainerLeftPanel.vue'
|
import LeftPanel from './AppContainerLeftPanel.vue'
|
||||||
import Breadcrumbs from './AppContainerBreadcrumbs.vue'
|
import Breadcrumbs from './AppContainerBreadcrumbs.vue'
|
||||||
import RightPanel from './RightPanel.vue'
|
import RightPanel from './AppContainerRightPanel.vue'
|
||||||
import AppContainerHeader from './AppContainerHeader.vue'
|
import AppContainerHeader from './AppContainerHeader.vue'
|
||||||
import {mapGetters} from 'vuex'
|
import {mapGetters} from 'vuex'
|
||||||
|
import ServiceOfLayout from '@services/ServiceOfLayout'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AppContainer',
|
name: 'AppContainer',
|
||||||
@ -18,41 +19,91 @@ export default {
|
|||||||
AppContainerHeader
|
AppContainerHeader
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
return {
|
||||||
|
serviceOfLayout: null,
|
||||||
|
isOpenedMobileMenu: false,
|
||||||
|
routeName: ""
|
||||||
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters('layout', ["show_menu", 'is_enabled_menu']),
|
...mapGetters('layout', ["isShowMenu", 'isEnabledMenu']),
|
||||||
...mapGetters('auth', ['menuList']),
|
...mapGetters('auth', ['menuList', 'currentUser']),
|
||||||
|
menuListWithIndex() {
|
||||||
|
return this.menuList.map((el, index) => ({...el, index}))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch:{
|
||||||
|
$route (to){
|
||||||
|
this.routeName = to.name;
|
||||||
|
this.closeMobileMenu()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const store = this.$store
|
||||||
|
this.serviceOfLayout = new ServiceOfLayout(store)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
closeMobileMenu() {
|
||||||
|
this.isOpenedMobileMenu = false
|
||||||
|
},
|
||||||
|
openMobileMenu() {
|
||||||
|
this.isOpenedMobileMenu = true
|
||||||
|
},
|
||||||
|
setIsMobileMenuOpened(isOpened) {
|
||||||
|
if (this.serviceOfLayout) {
|
||||||
|
this.serviceOfLayout.setIsMobileMenuOpened(isOpened)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggleMenu() {
|
||||||
|
if (this.serviceOfLayout) {
|
||||||
|
this.serviceOfLayout.toggleMenu()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toggleMobileMenu() {
|
||||||
|
if (this.isOpenedMobileMenu) {
|
||||||
|
this.closeMobileMenu()
|
||||||
|
} else {
|
||||||
|
this.openMobileMenu()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="main w-full">
|
<div
|
||||||
|
v-if="serviceOfLayout"
|
||||||
|
class="main w-full"
|
||||||
|
>
|
||||||
<!-- BEGIN: TOP BAR -->
|
<!-- BEGIN: TOP BAR -->
|
||||||
<div
|
<div
|
||||||
id="menu"
|
id="menu"
|
||||||
class="top-bar-boxed w-full h-[59px] mt-[4px] z-[51] relative justify-center border-b border-white/[0.2] -mx-3 px-3 sm:pl-8 md:pt-0 mb-[4px]"
|
class="top-bar-boxed w-full h-[59px] mt-[4px] z-[51] relative justify-center border-b border-white/[0.2] -mx-3 px-3 sm:pl-8 md:pt-0 mb-[4px]"
|
||||||
>
|
>
|
||||||
<MobileMenu
|
<MobileMenu
|
||||||
v-if="false"
|
v-if="isOpenedMobileMenu"
|
||||||
current_menu_item=""
|
:menuListWithIndex="menuListWithIndex"
|
||||||
current_user=""
|
currentMenuItem="routeName"
|
||||||
:menu_list="menuList"
|
:currentUser="currentUser"
|
||||||
|
setIsMobileMenuOpened="setIsMobileMenuOpened"
|
||||||
|
:toggleMobileMenu="toggleMobileMenu"
|
||||||
/>
|
/>
|
||||||
<AppContainerHeader>
|
<AppContainerHeader>
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<LeftPanel />
|
<LeftPanel
|
||||||
|
:toggleMobileMenu="toggleMobileMenu"
|
||||||
|
/>
|
||||||
<Breadcrumbs
|
<Breadcrumbs
|
||||||
v-if="false"
|
v-if="false"
|
||||||
:breadcrumbs="[]"
|
:breadcrumbs="[]"
|
||||||
/>
|
/>
|
||||||
<RightPanel
|
<RightPanel
|
||||||
:current_user="''"
|
:current_user="''"
|
||||||
:page_title="''"
|
:pageTitle="''"
|
||||||
|
:toggleMenu="toggleMenu"
|
||||||
:notifications="[{from: 'Бот из LM', datetime: '10:00', message: 'Проведен редизайн приложения', readed: false}]"
|
:notifications="[{from: 'Бот из LM', datetime: '10:00', message: 'Проведен редизайн приложения', readed: false}]"
|
||||||
|
:currentUser="currentUser"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="sm:hidden flex items-center justify-between" />
|
<div class="sm:hidden flex items-center justify-between" />
|
||||||
@ -61,9 +112,11 @@ export default {
|
|||||||
<!-- END: TOP BAR -->
|
<!-- END: TOP BAR -->
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="wrapper-box">
|
<div class="wrapper-box">
|
||||||
<div v-if="show_menu && is_enabled_menu">
|
<div v-if="isShowMenu && isEnabledMenu">
|
||||||
<MenuList
|
<MenuList
|
||||||
:menu_list="menuList"
|
:isShowMenu="isShowMenu"
|
||||||
|
:menuListWithIndex="menuListWithIndex"
|
||||||
|
:routeName="routeName"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
|||||||
@ -9,8 +9,6 @@ export default {
|
|||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@ -1,8 +1,18 @@
|
|||||||
<script>
|
<script>
|
||||||
|
import { h } from 'vue'
|
||||||
|
import {createIcons, icons} from "lucide";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'AppContainerLeftPanel',
|
name: 'AppContainerLeftPanel',
|
||||||
components: {},
|
components: {
|
||||||
|
MobileMenuButton: h('div')
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
toggleMobileMenu: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {}
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
mobile_menu_opened: false
|
mobile_menu_opened: false
|
||||||
@ -10,25 +20,34 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
this.icons()
|
||||||
|
},
|
||||||
|
updated() {
|
||||||
|
this.icons()
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
}
|
icons() {
|
||||||
|
createIcons({ icons, nameAttr: "icon" })
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex items-center border-white/[0.2] border-r">
|
<div class="flex items-center border-white/[0.2] border-r">
|
||||||
<div
|
<mobile-menu-button
|
||||||
class="flex p-4 cursor-pointer flex md:hidden"
|
class="flex p-4 cursor-pointer md:hidden"
|
||||||
@click="mobile_menu_opened = !mobile_menu_opened"
|
@click="toggleMobileMenu()"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
icon="bar-chart-2"
|
icon="bar-chart-2"
|
||||||
class="w-6 h-6 text-white transform rotate-90"
|
class="w-6 h-6 text-white transform rotate-90"
|
||||||
/>
|
/>
|
||||||
</div>
|
</mobile-menu-button>
|
||||||
<router-link
|
<router-link
|
||||||
class="items-center relative -intro-x flex cursor-pointer p-4 hidden md:flex"
|
class="hidden md:flex items-center relative -intro-x cursor-pointer p-4 "
|
||||||
to="/?page=machines&mode=cards"
|
to="/?page=machines&mode=cards"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -0,0 +1,60 @@
|
|||||||
|
<script>
|
||||||
|
import MenuListItem from './MenuList/MenuListItem.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AppContainerMobileMenu',
|
||||||
|
components: {
|
||||||
|
MenuListItem
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
currentMenuItem: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
menuListWithIndex: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
toggleMobileMenu: {
|
||||||
|
type: Function,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
randomkey() {
|
||||||
|
return Math.random().toString(36).slice(4)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="mobile-menu--active appear-opacity-200 mobile-menu md:hidden">
|
||||||
|
<span
|
||||||
|
class="absolute top-[30px] right-0 z-40"
|
||||||
|
@click="toggleMobileMenu()"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
icon="x-circle"
|
||||||
|
class="w-8 h-8 text-white transform -rotate-90"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<div class="scrollable slide-left-400">
|
||||||
|
<ul class=" scrollable__content py-2">
|
||||||
|
<MenuListItem
|
||||||
|
v-for="{index, ...menuItem} in menuListWithIndex"
|
||||||
|
:key="randomkey(index)"
|
||||||
|
baseClass="menu"
|
||||||
|
:type="menuItem.type"
|
||||||
|
:menuItem="menuItem"
|
||||||
|
:currentMenuItem="currentMenuItem"
|
||||||
|
/>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@ -1,24 +1,30 @@
|
|||||||
<!-- eslint-disable vue/prop-name-casing -->
|
|
||||||
<script>
|
<script>
|
||||||
import {mapGetters, mapMutations} from 'vuex'
|
import {mapGetters} from 'vuex'
|
||||||
import { createIcons, icons } from "lucide";
|
import { createIcons, icons } from "lucide";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'RightPanel',
|
name: 'RightPanel',
|
||||||
components: {},
|
components: {},
|
||||||
props: {
|
props: {
|
||||||
// eslint-disable-next-line vue/prop-name-casing
|
pageTitle: {
|
||||||
page_title: {
|
|
||||||
type: String,
|
type: String,
|
||||||
default: ""
|
default: ""
|
||||||
|
},
|
||||||
|
toggleMenu: {
|
||||||
|
type: Function,
|
||||||
|
default: () => {}
|
||||||
|
},
|
||||||
|
notifications: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
currentUser: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return { }
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('auth', ['current_user'])
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.icons()
|
this.icons()
|
||||||
@ -27,11 +33,12 @@ export default {
|
|||||||
this.icons()
|
this.icons()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapMutations('layout', ["toggle_menu"]),
|
|
||||||
icons() {
|
icons() {
|
||||||
createIcons({ icons, "stroke-width": 1.5, nameAttr: "icon" })
|
createIcons({
|
||||||
|
icons, "stroke-width": 1.5, nameAttr: "icon"
|
||||||
|
})
|
||||||
},
|
},
|
||||||
rkey() {
|
randomkey() {
|
||||||
return Math.random().toString(36).slice(4)
|
return Math.random().toString(36).slice(4)
|
||||||
},
|
},
|
||||||
closeDropDown() {
|
closeDropDown() {
|
||||||
@ -46,9 +53,9 @@ export default {
|
|||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex items-center justify-end grow gapy-2 px-4 border-hide-600">
|
<div class="flex items-center justify-end grow px-4 border-hide-600">
|
||||||
<div class="">
|
<div class="">
|
||||||
{{ page_title }}
|
{{ pageTitle }}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
@ -66,7 +73,7 @@ export default {
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
style="font-size: 7px; font-weight: 900; top: 10px; left: 30px"
|
style="font-size: 7px; font-weight: 900; top: 10px; left: 30px"
|
||||||
class="h-[13px] w-[13px] bg-white rounded-full mr-8 transition absolute flex itens-center justify-center"
|
class="h-[13px] w-[13px] bg-white rounded-full mr-8 transition absolute flex items-center justify-center"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
style="line-height: 13px; font-weight: 900; font-size: 7px"
|
style="line-height: 13px; font-weight: 900; font-size: 7px"
|
||||||
@ -81,14 +88,17 @@ export default {
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-for="{from, datetime, message, readed} in notifications"
|
v-for="{from, datetime, message, readed} in notifications"
|
||||||
:key="rkey(message)"
|
:key="randomkey(message)"
|
||||||
class="cursor-pointer relative flex items-center "
|
class="cursor-pointer relative flex items-center "
|
||||||
>
|
>
|
||||||
<div :class="{'bg-gray-400 w-3 h-3 absolute right-0 bottom-0 rounded-full border-2 border-white dark:border-darkmode-600|, else: ~s|bg-success w-3 h-3 absolute right-0 bottom-0 rounded-full border-2 border-white dark:border-darkmode-600': readed}" />
|
<div
|
||||||
|
:class="{'bg-gray-400 w-3 h-3 absolute right-0 bottom-0 rounded-full border-2 border-white dark:border-darkmode-600': readed,
|
||||||
|
'bg-success w-3 h-3 absolute right-0 bottom-0 rounded-full border-2 border-white dark:border-darkmode-600': !readed}"
|
||||||
|
/>
|
||||||
<div class="ml-2 overflow-hidden">
|
<div class="ml-2 overflow-hidden">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<a
|
<a
|
||||||
href="javascript:;"
|
href="javascript:"
|
||||||
class="font-medium truncate mr-5"
|
class="font-medium truncate mr-5"
|
||||||
>{{ from }}</a>
|
>{{ from }}</a>
|
||||||
<div class="text-xs text-slate-400 ml-auto whitespace-nowrap">
|
<div class="text-xs text-slate-400 ml-auto whitespace-nowrap">
|
||||||
@ -120,7 +130,7 @@ export default {
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="cursor-pointer hidden md:flex border-white/[0.2] border-r p-4"
|
class="cursor-pointer hidden md:flex border-white/[0.2] border-r p-4"
|
||||||
@click="toggle_menu"
|
@click="toggleMenu"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
id="menu_library"
|
id="menu_library"
|
||||||
@ -146,13 +156,13 @@ export default {
|
|||||||
<ul class="dropdown-content before:block before:absolute before:bg-black before:inset-0 before:rounded-md before:z-[-1]">
|
<ul class="dropdown-content before:block before:absolute before:bg-black before:inset-0 before:rounded-md before:z-[-1]">
|
||||||
<li class="p-2">
|
<li class="p-2">
|
||||||
<div class="font-bold">
|
<div class="font-bold">
|
||||||
{{ current_user?.first_name || "" }} {{ current_user?.last_name || "" }}
|
{{ currentUser?.first_name || "" }} {{ currentUser?.last_name || "" }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="text-xs text-black/60 dark:text-slate-500"
|
class="text-xs text-black/60 dark:text-slate-500"
|
||||||
style="margin-top: -0.25rem;"
|
style="margin-top: -0.25rem;"
|
||||||
>
|
>
|
||||||
{{ current_user?.position || "позиция не указана" }}
|
{{ currentUser?.position || "позиция не указана" }}
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@ -1,119 +0,0 @@
|
|||||||
<!-- eslint-disable vue/prop-name-casing -->
|
|
||||||
<script>
|
|
||||||
import { cond, equals, T, always } from 'ramda'
|
|
||||||
import { createIcons, icons } from "lucide";
|
|
||||||
import MenuItemGroup from './MenuItemGroup.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'MenuItem',
|
|
||||||
components: {MenuItemGroup},
|
|
||||||
props: {
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
menu_item: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({
|
|
||||||
link: "/"
|
|
||||||
})
|
|
||||||
},
|
|
||||||
base_class: {
|
|
||||||
type: String,
|
|
||||||
default: ""
|
|
||||||
},
|
|
||||||
routeName: {
|
|
||||||
type: String,
|
|
||||||
default: ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
_base_class() {
|
|
||||||
return `${this.base_class}`
|
|
||||||
},
|
|
||||||
activeClass () {
|
|
||||||
return 'side-menu side-menu--active'
|
|
||||||
},
|
|
||||||
menuRouterName() {
|
|
||||||
return this.menu_item.router || ""
|
|
||||||
},
|
|
||||||
currentRouterName() {
|
|
||||||
return this.$router.currentRoute._value.name || ""
|
|
||||||
},
|
|
||||||
linkClass() {
|
|
||||||
const menuRouterName = this.menu_item.router || ""
|
|
||||||
if (menuRouterName === this.routeName)
|
|
||||||
return `${this._base_class} ${this._base_class}--active`
|
|
||||||
return this._base_class
|
|
||||||
},
|
|
||||||
_type() {
|
|
||||||
return cond([
|
|
||||||
[equals("simple_link"), (x) => x],
|
|
||||||
[equals("line"), (x) => x],
|
|
||||||
[equals("group"), (x) => x],
|
|
||||||
[T, () => "other"],
|
|
||||||
])(this.type)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.icons()
|
|
||||||
},
|
|
||||||
updated() {
|
|
||||||
console.log(123)
|
|
||||||
|
|
||||||
this.icons()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
icons() {
|
|
||||||
createIcons({ icons, "stroke-width": 1.5, nameAttr: "icon" })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<li v-if="_type == 'simple_link'">
|
|
||||||
<router-link
|
|
||||||
phx-hook="MenuLink"
|
|
||||||
:class="linkClass"
|
|
||||||
:to="menu_item.link"
|
|
||||||
>
|
|
||||||
<div :class="`${_base_class}__icon`">
|
|
||||||
<i :icon="menu_item?.icon" />
|
|
||||||
</div>
|
|
||||||
<div :class="`${_base_class}__title`">
|
|
||||||
{{ menu_item.show }}
|
|
||||||
</div>
|
|
||||||
</router-link>
|
|
||||||
</li>
|
|
||||||
<li v-if="_type == 'line'">
|
|
||||||
<hr class="m-4">
|
|
||||||
</li>
|
|
||||||
<MenuItemGroup
|
|
||||||
v-if="_type == 'group'"
|
|
||||||
:type="_type"
|
|
||||||
:base_class="base_class"
|
|
||||||
:menu_item="menu_item"
|
|
||||||
/>
|
|
||||||
<div v-if="_type == 'other'">
|
|
||||||
""
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- <router-link
|
|
||||||
v-if="type === 'link'"
|
|
||||||
class="flex p-2 rounded-md hover:bg-gray-100 flex items-center"
|
|
||||||
:class="{'bg-gray-200': pageName === name}"
|
|
||||||
:to="link"
|
|
||||||
>
|
|
||||||
<i :class="`ri-${icon} text-slate-600 mr-2 `" />
|
|
||||||
<span
|
|
||||||
v-if="isOpenMenu"
|
|
||||||
class="text-slate-700"
|
|
||||||
>{{ title }}</span>
|
|
||||||
</router-link> -->
|
|
||||||
@ -1,93 +0,0 @@
|
|||||||
<!-- eslint-disable vue/prop-name-casing -->
|
|
||||||
<script>
|
|
||||||
import { cond, equals, T } from 'ramda'
|
|
||||||
import { createIcons, icons } from "lucide";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'MenuItemCopy',
|
|
||||||
components: {},
|
|
||||||
props: {
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
menu_item: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({
|
|
||||||
link: "/"
|
|
||||||
})
|
|
||||||
},
|
|
||||||
base_class: {
|
|
||||||
type: String,
|
|
||||||
default: ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
_base_class() {
|
|
||||||
return `${this.base_class}`
|
|
||||||
},
|
|
||||||
activeClass () {
|
|
||||||
return 'side-menu side-menu--active'
|
|
||||||
},
|
|
||||||
menuRouterName() {
|
|
||||||
return this.menu_item.router || ""
|
|
||||||
},
|
|
||||||
currentRouterName() {
|
|
||||||
return this.$router.currentRoute._value.name || ""
|
|
||||||
},
|
|
||||||
linkClass() {
|
|
||||||
const menuRouterName = this.menu_item.router || ""
|
|
||||||
const currentRouterName = this.$router.currentRoute._value.name || Math.random()
|
|
||||||
if (menuRouterName === currentRouterName)
|
|
||||||
return `${this._base_class} ${this._base_class}--active`
|
|
||||||
return this._base_class
|
|
||||||
},
|
|
||||||
_type() {
|
|
||||||
return cond([
|
|
||||||
[equals("simple_link"), (x) => x],
|
|
||||||
[equals("line"), (x) => x],
|
|
||||||
[equals("group"), (x) => x],
|
|
||||||
[T, () => "other"],
|
|
||||||
])(this.type)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.icons()
|
|
||||||
},
|
|
||||||
updated() {
|
|
||||||
this.icons()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
icons() {
|
|
||||||
createIcons({ icons, "stroke-width": 1.5, nameAttr: "icon" })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<li v-if="_type == 'simple_link'">
|
|
||||||
<router-link
|
|
||||||
phx-hook="MenuLink"
|
|
||||||
:class="linkClass"
|
|
||||||
:to="menu_item.link"
|
|
||||||
>
|
|
||||||
<div :class="`${_base_class}__icon`">
|
|
||||||
<i :icon="menu_item?.icon" />
|
|
||||||
</div>
|
|
||||||
<div :class="`${_base_class}__title`">
|
|
||||||
{{ menu_item.show }}
|
|
||||||
</div>
|
|
||||||
</router-link>
|
|
||||||
</li>
|
|
||||||
<li v-if="_type == 'line'">
|
|
||||||
<hr class="m-4">
|
|
||||||
</li>
|
|
||||||
<div v-if="_type == 'other'">
|
|
||||||
""
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
<!-- eslint-disable vue/prop-name-casing -->
|
|
||||||
<script>
|
|
||||||
import MenuItem from './MenuItemCopy.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'MenuItemGroup',
|
|
||||||
components: {
|
|
||||||
MenuItem
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
base_class: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
menu_item: {
|
|
||||||
type: Object,
|
|
||||||
default: () => ({})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
open: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
containerClass() {
|
|
||||||
const menuRouterName = this.menu_item.router || ""
|
|
||||||
const currentRouterName = this.$router.currentRoute._value.name || Math.random()
|
|
||||||
if (menuRouterName === currentRouterName) return `${this.base_class} ${this.base_class}--active`
|
|
||||||
return `${this.base_class}`
|
|
||||||
},
|
|
||||||
itemClass() {
|
|
||||||
if (this.open) return `${this.base_class}__sub-icon transform rotate-180`
|
|
||||||
return `${this.base_class}__sub-icon`
|
|
||||||
},
|
|
||||||
listClass() {
|
|
||||||
if (this.open) return `${this.base_class}__sub-open`
|
|
||||||
return ""
|
|
||||||
},
|
|
||||||
menu_list_with_index() {
|
|
||||||
return this.menu_item.children.map((el, index) => ({...el, index}))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
toggle() {
|
|
||||||
this.open = !this.open
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<li>
|
|
||||||
<span
|
|
||||||
:class="containerClass"
|
|
||||||
@click="toggle"
|
|
||||||
>
|
|
||||||
<div :class="`${base_class}__icon`"> <i :icon="menu_item.icon" /> </div>
|
|
||||||
<div :class="`${base_class}__title`">
|
|
||||||
{{ menu_item.show }}
|
|
||||||
<div :class="itemClass"> <i icon="chevron-down" /> </div>
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
<ul :class="listClass">
|
|
||||||
<MenuItem
|
|
||||||
v-for="item in menu_item.children"
|
|
||||||
:key="JSON.stringify(item)"
|
|
||||||
:base_class="base_class"
|
|
||||||
:type="item.type"
|
|
||||||
:menu_item="item"
|
|
||||||
/>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</template>
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
<!-- eslint-disable vue/prop-name-casing -->
|
|
||||||
<script>
|
|
||||||
import {mapGetters} from 'vuex'
|
|
||||||
import MenuItem from './MenuItem.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'MenuList',
|
|
||||||
components: {MenuItem},
|
|
||||||
props: {
|
|
||||||
current_menu_item: {
|
|
||||||
type: String,
|
|
||||||
default: ""
|
|
||||||
},
|
|
||||||
menu_list: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
routeName: ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('', ['mobile_menu_opened', 'show_menu']),
|
|
||||||
menu_list_with_index() {
|
|
||||||
return this.menu_list.map((el, index) => ({...el, index}))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch:{
|
|
||||||
$route (to){
|
|
||||||
this.routeName = to.name;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
rkey() {
|
|
||||||
return Math.random().toString(36).slice(4)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<nav
|
|
||||||
x-show="show_menu"
|
|
||||||
class="side-nav"
|
|
||||||
>
|
|
||||||
<ul>
|
|
||||||
<MenuItem
|
|
||||||
v-for="{index, ...menu_item} in menu_list_with_index"
|
|
||||||
:id="`main_menu_item_component_${index}`"
|
|
||||||
:key="rkey(index)"
|
|
||||||
base_class="side-menu"
|
|
||||||
:type="menu_item.type"
|
|
||||||
:menu_item="menu_item"
|
|
||||||
:current_menu_item="current_menu_item"
|
|
||||||
:routeName="routeName"
|
|
||||||
/>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</template>
|
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
<!-- eslint-disable vue/prop-name-casing -->
|
||||||
|
<script>
|
||||||
|
import MenuListItem from './MenuListItem.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'MenuList',
|
||||||
|
components: {MenuListItem},
|
||||||
|
props: {
|
||||||
|
menuListWithIndex: {
|
||||||
|
type: [{
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
}],
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
isShowMenu: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
routeName: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
randomkey() {
|
||||||
|
return Math.random().toString(36).slice(4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<nav class="side-nav">
|
||||||
|
<ul>
|
||||||
|
<MenuListItem
|
||||||
|
v-for="{index, ...menuItem} in menuListWithIndex"
|
||||||
|
:id="`main_menu_item_component_${index}`"
|
||||||
|
:key="randomkey(index)"
|
||||||
|
baseClass="side-menu"
|
||||||
|
:type="menuItem.type"
|
||||||
|
:menuItem="menuItem"
|
||||||
|
:routeName="routeName"
|
||||||
|
/>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
<script>
|
||||||
|
import MenuListItemImplementation from './MenuListItemImplementation.vue'
|
||||||
|
import MenuListItemGroup from "@frames/AppContainer/MenuList/MenuListItemGroup.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'MenuListItem',
|
||||||
|
components: {MenuListItemGroup, MenuListItemImplementation},
|
||||||
|
//eslint-disable-next-line
|
||||||
|
props: ['type', 'menuItem', 'baseClass', 'routeName'],
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<MenuListItemImplementation
|
||||||
|
:type="type"
|
||||||
|
:menuItem="menuItem"
|
||||||
|
:baseClass="baseClass"
|
||||||
|
:routeName="routeName"
|
||||||
|
>
|
||||||
|
<MenuListItemGroup
|
||||||
|
v-if="type === 'group'"
|
||||||
|
:type="type"
|
||||||
|
:baseClass="baseClass"
|
||||||
|
:menuItem="menuItem"
|
||||||
|
:routeName="routeName"
|
||||||
|
/>
|
||||||
|
</MenuListItemImplementation>
|
||||||
|
</template>
|
||||||
|
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
<script>
|
||||||
|
import MenuListItemImplementation from './MenuListItemImplementation.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'MenuListItemCopy',
|
||||||
|
components: {MenuListItemImplementation},
|
||||||
|
//eslint-disable-next-line
|
||||||
|
props: ['type', 'menuItem', 'baseClass', 'routeName'],
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<MenuListItemImplementation
|
||||||
|
:type="type"
|
||||||
|
:menuItem="menuItem"
|
||||||
|
:baseClass="baseClass"
|
||||||
|
:routeName="routeName"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
<!-- eslint-disable vue/prop-name-casing -->
|
||||||
|
<script>
|
||||||
|
import MenuItem from './MenuListItemCopy.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'MenuItemGroup',
|
||||||
|
components: {
|
||||||
|
MenuItem
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
baseClass: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
menuItem: {
|
||||||
|
type: {
|
||||||
|
show: String,
|
||||||
|
children: Array,
|
||||||
|
router: String
|
||||||
|
},
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
routeName: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
open: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
containerClass() {
|
||||||
|
const routeName = this.routeName
|
||||||
|
const menuRouterName = this.menuItem.router || ""
|
||||||
|
if (menuRouterName === routeName) return `${this.baseClass} ${this.baseClass}--active`
|
||||||
|
return `${this.baseClass}`
|
||||||
|
},
|
||||||
|
itemClass() {
|
||||||
|
if (this.open) return `${this.baseClass}__sub-icon transform rotate-180`
|
||||||
|
return `${this.baseClass}__sub-icon`
|
||||||
|
},
|
||||||
|
listClass() {
|
||||||
|
if (this.open) return `${this.baseClass}__sub-open`
|
||||||
|
return ""
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggle() {
|
||||||
|
this.open = !this.open
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<li>
|
||||||
|
<span
|
||||||
|
:class="containerClass"
|
||||||
|
@click="toggle"
|
||||||
|
>
|
||||||
|
<div :class="`${baseClass}__icon`"> <i :icon="menuItem.icon" /> </div>
|
||||||
|
<div :class="`${baseClass}__title`">
|
||||||
|
{{ menuItem.show }}
|
||||||
|
<div :class="itemClass"> <i icon="chevron-down" /> </div>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
<ul :class="listClass">
|
||||||
|
<MenuItem
|
||||||
|
v-for="item in menuItem.children"
|
||||||
|
:key="JSON.stringify(item)"
|
||||||
|
:baseClass="baseClass"
|
||||||
|
:type="item.type"
|
||||||
|
:menuItem="item"
|
||||||
|
/>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,89 @@
|
|||||||
|
<script>
|
||||||
|
import { cond, equals, T } from 'ramda'
|
||||||
|
import { createIcons, icons } from "lucide";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'MenuItem',
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
menuItem: {
|
||||||
|
type: {
|
||||||
|
line: String,
|
||||||
|
icon: String,
|
||||||
|
|
||||||
|
},
|
||||||
|
default: () => ({
|
||||||
|
link: "/"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
baseClass: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
routeName: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
linkClass() {
|
||||||
|
const menuRouterName = this.menuItem.router || ""
|
||||||
|
if (menuRouterName === this.routeName)
|
||||||
|
return `${this.baseClass} ${this.baseClass}--active`
|
||||||
|
return this.baseClass
|
||||||
|
},
|
||||||
|
_type() {
|
||||||
|
return cond([
|
||||||
|
[equals("simple_link"), (x) => x],
|
||||||
|
[equals("line"), (x) => x],
|
||||||
|
[equals("group"), (x) => x],
|
||||||
|
[T, () => "other"],
|
||||||
|
])(this.type)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.icons()
|
||||||
|
},
|
||||||
|
updated() {
|
||||||
|
this.icons()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
icons() {
|
||||||
|
createIcons({ icons, nameAttr: "icon" })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<li v-if="_type === 'simple_link'">
|
||||||
|
<router-link
|
||||||
|
phx-hook="MenuLink"
|
||||||
|
:class="linkClass"
|
||||||
|
:to="menuItem.link"
|
||||||
|
>
|
||||||
|
<div :class="`${baseClass}__icon`">
|
||||||
|
<i :icon="menuItem?.icon" />
|
||||||
|
</div>
|
||||||
|
<div :class="`${baseClass}__title`">
|
||||||
|
{{ menuItem.show }}
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
|
</li>
|
||||||
|
<li v-if="_type === 'line'">
|
||||||
|
<hr class="m-4">
|
||||||
|
</li>
|
||||||
|
<slot />
|
||||||
|
<div v-if="_type === 'other'">
|
||||||
|
""
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
<script>
|
|
||||||
import MenuItem from './MenuItem.vue'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'MobileMenu',
|
|
||||||
components: {
|
|
||||||
MenuItem
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
// eslint-disable-next-line vue/prop-name-casing
|
|
||||||
current_menu_item: {
|
|
||||||
type: String,
|
|
||||||
default: ""
|
|
||||||
},
|
|
||||||
// eslint-disable-next-line vue/prop-name-casing
|
|
||||||
menu_list: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
menu_list_with_index() {
|
|
||||||
return this.menu_list.map((el, index) => ({...el, index}))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
rkey() {
|
|
||||||
return Math.random().toString(36).slice(4)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div x-bind:class="mobile_menu_opened ? 'mobile-menu--active mobile-menu md:hidden' : 'mobile-menu md:hidden'">
|
|
||||||
<div class="scrollable">
|
|
||||||
<span
|
|
||||||
class="mobile-menu-toggler"
|
|
||||||
@click="mobile_menu_opened = !mobile_menu_opened"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
icon="x-circle"
|
|
||||||
class="w-8 h-8 text-white transform -rotate-90"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<ul class="scrollable__content py-2">
|
|
||||||
<MenuItem
|
|
||||||
v-for="{index, ...menu_item} in menu_list_with_index"
|
|
||||||
:id="`main_menu_item_component_${index}`"
|
|
||||||
:key="rkey(index)"
|
|
||||||
base_class="menu"
|
|
||||||
:type="menu_item.type"
|
|
||||||
:menu_item="menu_item"
|
|
||||||
:current_menu_item="current_menu_item"
|
|
||||||
/>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "PacksContainer",
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="grid grid-cols-12 gap-6 col-span-12 h-full">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "PacksContainerBody"
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="">
|
||||||
|
ComponentTemplate
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "PacksContainerControl",
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<form
|
||||||
|
phx-submit="fetch_pack"
|
||||||
|
class="rounded-md bg-light px-4 pt-4 pb-6 gap-2 shadow lg:col-span-4 xl:col-span-3 2xl:col-span-2 col-span-12"
|
||||||
|
autocomplete="off"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
@ -1,3 +1,64 @@
|
|||||||
|
<script>
|
||||||
|
import ButtonModal from '@molecules/ButtonModal/ButtonModal.vue'
|
||||||
|
import Datepicker from "@molecules/VDatepicker/VDatepicker.vue"
|
||||||
|
import {mapGetters, mapMutations, mapActions} from 'vuex'
|
||||||
|
import Tabulator from "@molecules/VTabulator/VTabulator.vue"
|
||||||
|
import Spinner from "@molecules/VSpinner/VSpinner.vue"
|
||||||
|
import MachinesModal from "@molecules/MachinesModal/MachinesModal.vue"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'LastPacks',
|
||||||
|
components: {
|
||||||
|
Datepicker,
|
||||||
|
ButtonModal,
|
||||||
|
Tabulator,
|
||||||
|
Spinner,
|
||||||
|
MachinesModal
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
packNum: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters('last_packs', ['dtStart', 'dtFinish', 'imei', 'pageState', 'packsData']),
|
||||||
|
tabulatorOtps() {
|
||||||
|
return {
|
||||||
|
dataSource: this.packsData,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: "Нормер пакета",
|
||||||
|
field: "pack_number",
|
||||||
|
width: 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Количество записей",
|
||||||
|
field: "count",
|
||||||
|
width: 150
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Последняя дата пакета",
|
||||||
|
field: "pack_dt",
|
||||||
|
width: 150,
|
||||||
|
render: "{{ dt_format (dt_shift pack_dt 3 'hour') }}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
height: "550px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations('last_packs', [
|
||||||
|
"setDtStart",
|
||||||
|
"setDtFinish",
|
||||||
|
"setImei"
|
||||||
|
]),
|
||||||
|
...mapActions('last_packs', ['uploadData'])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="grid grid-cols-12 gap-6 col-span-12 h-full">
|
<div class="grid grid-cols-12 gap-6 col-span-12 h-full">
|
||||||
<form
|
<form
|
||||||
@ -99,64 +160,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
|
||||||
import ButtonModal from '@molecules/ButtonModal/ButtonModal.vue'
|
|
||||||
import Datepicker from "@molecules/VDatepicker/VDatepicker.vue"
|
|
||||||
import {mapGetters, mapMutations, mapActions} from 'vuex'
|
|
||||||
import Tabulator from "@molecules/VTabulator/VTabulator.vue"
|
|
||||||
import Spinner from "@molecules/VSpinner/VSpinner.vue"
|
|
||||||
import MachinesModal from "@molecules/MachinesModal/MachinesModal.vue"
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'LastPacks',
|
|
||||||
components: {
|
|
||||||
Datepicker,
|
|
||||||
ButtonModal,
|
|
||||||
Tabulator,
|
|
||||||
Spinner,
|
|
||||||
MachinesModal
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
packNum: null,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters('last_packs', ['dtStart', 'dtFinish', 'imei', 'pageState', 'packsData']),
|
|
||||||
tabulatorOtps() {
|
|
||||||
return {
|
|
||||||
dataSource: this.packsData,
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
title: "Нормер пакета",
|
|
||||||
field: "pack_number",
|
|
||||||
width: 150
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Количество записей",
|
|
||||||
field: "count",
|
|
||||||
width: 150
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Последняя дата пакета",
|
|
||||||
field: "pack_dt",
|
|
||||||
width: 150,
|
|
||||||
render: "{{ dt_format (dt_shift pack_dt 3 'hour') }}"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
height: "550px"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
...mapMutations('last_packs', [
|
|
||||||
"setDtStart",
|
|
||||||
"setDtFinish",
|
|
||||||
"setImei"
|
|
||||||
]),
|
|
||||||
...mapActions('last_packs', ['uploadData'])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|||||||
43
live_monitor_vue/src/services/ServiceOfLayout.js
Normal file
43
live_monitor_vue/src/services/ServiceOfLayout.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
class ServiceOfLayout {
|
||||||
|
constructor(store) {
|
||||||
|
this.store = store
|
||||||
|
}
|
||||||
|
|
||||||
|
getHeight() {
|
||||||
|
return this.store.getters['layout/height']
|
||||||
|
}
|
||||||
|
getWidth() {
|
||||||
|
return this.store.getters['layout/width']
|
||||||
|
}
|
||||||
|
getIsOpenMenu() {
|
||||||
|
return this.store.getters['layout/isOpenMenu']
|
||||||
|
}
|
||||||
|
getIsShowMenu() {
|
||||||
|
return this.store.getters['layout/isShowMenu']
|
||||||
|
}
|
||||||
|
getIsEnabledMenu() {
|
||||||
|
return this.store.getters['layout/isEnabledMenu']
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsShowMenu(upd) {
|
||||||
|
this.store.dispatch('layout/setIsShowMenu', upd)
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsMobileMenuOpened(upd) {
|
||||||
|
this.store.dispatch('layout/setIsMobileMenuOpened', upd)
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsOpenMenu(upd) {
|
||||||
|
this.store.dispatch('layout/setIsOpenMenu', upd)
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsEnabledMenu(upd) {
|
||||||
|
this.store.dispatch('layout/setIsEnabledMenu', upd)
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleMenu() {
|
||||||
|
this.store.dispatch('layout/toggleMenu')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ServiceOfLayout
|
||||||
@ -6,7 +6,7 @@ import axios from 'axios';
|
|||||||
import {orisMenu} from './menuList'
|
import {orisMenu} from './menuList'
|
||||||
|
|
||||||
const initState = {
|
const initState = {
|
||||||
current_user: null,
|
currentUser: null,
|
||||||
errorMsg: null,
|
errorMsg: null,
|
||||||
token: null,
|
token: null,
|
||||||
inited: false,
|
inited: false,
|
||||||
@ -17,7 +17,7 @@ const state = {
|
|||||||
...initState
|
...initState
|
||||||
};
|
};
|
||||||
|
|
||||||
const current_user = (token) => ({
|
const setCurrentUser = (token) => ({
|
||||||
position: "",
|
position: "",
|
||||||
first_name: "Сергей",
|
first_name: "Сергей",
|
||||||
last_name: "Шлыков",
|
last_name: "Шлыков",
|
||||||
@ -31,17 +31,17 @@ const getters = {
|
|||||||
login: (state) => state.login,
|
login: (state) => state.login,
|
||||||
password: (state) => state.password,
|
password: (state) => state.password,
|
||||||
my_comp: (state) => state.my_comp,
|
my_comp: (state) => state.my_comp,
|
||||||
current_user: (state) => state.current_user,
|
currentUser: (state) => state.currentUser,
|
||||||
menuList: () => orisMenu,
|
menuList: () => orisMenu,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
initAuth: (state, token) => {
|
initAuth: (state, token) => {
|
||||||
state.current_user = current_user(token)
|
state.currentUser = setCurrentUser(token)
|
||||||
state.token = token;
|
state.token = token;
|
||||||
state.inited = true
|
state.inited = true
|
||||||
},
|
},
|
||||||
set_my_comp: (state, upd) => state.my_comp,
|
set_my_comp: (state) => state.my_comp,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
|
|
||||||
|
|
||||||
const orisMenu = [
|
const orisMenu = [
|
||||||
{
|
{
|
||||||
type: "simple_link",
|
type: "simple_link",
|
||||||
icon: "home",
|
icon: "home",
|
||||||
show: "Главная",
|
show: "Главная",
|
||||||
link: "/",
|
link: "/",
|
||||||
router: "main"
|
router: "machines"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: "simple_link",
|
type: "simple_link",
|
||||||
|
|||||||
@ -1,58 +1,94 @@
|
|||||||
|
import {initScreenListener, disableScreenListener} from "./stateHelpers.js";
|
||||||
|
|
||||||
|
const initState = {
|
||||||
|
height: 0,
|
||||||
|
width: 0,
|
||||||
|
isOpenMenu: false,
|
||||||
|
isOpenedMobileMenu: false,
|
||||||
|
isEnabledMenu: true,
|
||||||
|
isShowMenu: true,
|
||||||
|
initedScreenListener: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
height: 0,
|
...initState
|
||||||
width: 0,
|
|
||||||
inited: false,
|
|
||||||
isOpenMenu: false,
|
|
||||||
mobile_menu_opened: false,
|
|
||||||
show_menu: true,
|
|
||||||
is_enabled_menu: true
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getters = {
|
const getters = {
|
||||||
height: (state) => state.height,
|
height: (state) => state.height,
|
||||||
width: (state) => state.width,
|
width: (state) => state.width,
|
||||||
isOpenMenu: (state) => state.isOpenMenu,
|
isOpenMenu: (state) => state.isOpenMenu,
|
||||||
menuWidth: (state) => null,
|
isShowMenu: (state) => state.isShowMenu,
|
||||||
show_menu: (state) => state.show_menu,
|
isOpenedMobileMenu: (state) => state.isOpenedMobileMenu,
|
||||||
is_enabled_menu: (state) => state.is_enabled_menu,
|
isEnabledMenu: (state) => state.isEnabledMenu,
|
||||||
|
initedScreenListener: (state) => state.initedScreenListener,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
enableScreenListener: (state) => {
|
enableScreenListener: (state) => {
|
||||||
state.height = window.innerHeight
|
const inited = state.initedScreenListener
|
||||||
state.width = window.innerWidth
|
if (!inited) {
|
||||||
const acc = !!state.inited
|
initScreenListener(state)
|
||||||
if (!acc) {
|
state.initedScreenListener = true
|
||||||
window.addEventListener("resize", (e) => {
|
|
||||||
state.height= e.target.innerHeight
|
|
||||||
state.width = e.target.innerWidth
|
|
||||||
});
|
|
||||||
state.inited = true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toggle_menu: (state) => {
|
disableScreenListener: (state) => {
|
||||||
state.show_menu = !state.show_menu
|
disableScreenListener(state)
|
||||||
},
|
},
|
||||||
set_mobile_menu_opened: (state, upd) => {
|
toggleMenu: (state) => {
|
||||||
state.mobile_menu_opened = upd
|
state.isShowMenu = !state.isShowMenu
|
||||||
},
|
},
|
||||||
set_show_menu: (state, upd) => {
|
saveIsMobileMenuOpened: (state, upd) => {
|
||||||
state.show_menu = upd
|
state.isOpenedMobileMenu = upd
|
||||||
|
},
|
||||||
|
saveIsShowMenu: (state, upd) => {
|
||||||
|
state.isShowMenu = upd
|
||||||
|
},
|
||||||
|
resetStore: (state) => {
|
||||||
|
for (let key in state) {
|
||||||
|
state[key] = initState[key]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
saveIsEnabledMenu: (state, upd) => {
|
||||||
|
state.isEnabledMenu = upd
|
||||||
|
},
|
||||||
|
saveIsOpenMenu: (state, upd) => {
|
||||||
|
state.isOpenMenu = upd
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
initScreenSizeRecalc: ({commit}) => {
|
initScreenSizeListener: ({commit}) => {
|
||||||
commit("enableScreenListener")
|
commit("enableScreenListener")
|
||||||
},
|
},
|
||||||
|
disableScreenListener: ({commit}) => {
|
||||||
|
commit("disableScreenListener")
|
||||||
|
},
|
||||||
|
resetStore: ({commit}) => {
|
||||||
|
commit("resetStore")
|
||||||
|
},
|
||||||
|
toggleMenu: ({commit}) => {
|
||||||
|
commit("toggleMenu")
|
||||||
|
},
|
||||||
|
setIsShowMenu: ({commit}, upd) => {
|
||||||
|
commit("saveIsShowMenu", upd)
|
||||||
|
},
|
||||||
|
setIsMobileMenuOpened: ({commit}, upd) => {
|
||||||
|
commit("saveIsMobileMenuOpened", upd)
|
||||||
|
},
|
||||||
|
setIsEnabledMenu: ({commit}, upd) => {
|
||||||
|
commit("saveIsEnabledMenu", upd)
|
||||||
|
},
|
||||||
|
setIsOpenMenu: ({commit}, upd) => {
|
||||||
|
commit("saveIsOpenMenu", upd)
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const store = {
|
export const store = {
|
||||||
namespaced: true,
|
namespaced: true,
|
||||||
state,
|
state,
|
||||||
getters,
|
getters,
|
||||||
mutations,
|
mutations,
|
||||||
actions,
|
actions,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,126 +0,0 @@
|
|||||||
const orisMenu = [
|
|
||||||
{
|
|
||||||
type: "simple_link",
|
|
||||||
icon: "home",
|
|
||||||
show: "Главная",
|
|
||||||
link: "/",
|
|
||||||
router: "main"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "simple_link",
|
|
||||||
icon: "book-marked",
|
|
||||||
show: "Последние пакеты",
|
|
||||||
link: "/html/last_packs",
|
|
||||||
router: "last_packs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "simple_link",
|
|
||||||
icon: "box",
|
|
||||||
show: "Коммуникационный",
|
|
||||||
link: "/html/controll_com_service",
|
|
||||||
router: "comm"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "simple_link",
|
|
||||||
icon: "book-key",
|
|
||||||
show: "Последние пакеты(по номеру)",
|
|
||||||
link: "/html/last_packs_by_pack",
|
|
||||||
router: "last_pack_number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "simple_link",
|
|
||||||
icon: "beaker",
|
|
||||||
show: "Топливо",
|
|
||||||
link: "/html/live_fuel",
|
|
||||||
router: "fuel"
|
|
||||||
},
|
|
||||||
{type: "simple_link", icon: "timer", show: "Крон", link: "/html/cron", router: "cron"},
|
|
||||||
{
|
|
||||||
type: "group",
|
|
||||||
show: "Справочники",
|
|
||||||
icon: "book",
|
|
||||||
children: [
|
|
||||||
{type: "simple_link", icon: "book-open", show: "ICCID", link: "/html/fetch_iccid"},
|
|
||||||
{
|
|
||||||
type: "simple_link",
|
|
||||||
icon: "book-open",
|
|
||||||
show: "Устройства",
|
|
||||||
link: "/html/fetch_askr_devices"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "group",
|
|
||||||
show: "Пакеты",
|
|
||||||
icon: "cast",
|
|
||||||
children:
|
|
||||||
[
|
|
||||||
{
|
|
||||||
type: "simple_link",
|
|
||||||
icon: "curly-braces",
|
|
||||||
show: "Свободный поиск",
|
|
||||||
link: "/html/free_packs"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{type: "line"},
|
|
||||||
{
|
|
||||||
type: "group",
|
|
||||||
show: "Логи",
|
|
||||||
icon: "fingerprint",
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
type: "simple_link",
|
|
||||||
icon: "code",
|
|
||||||
show: "Файлы логов",
|
|
||||||
link: "/html/file_viewer/logs"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "simple_link",
|
|
||||||
icon: "code",
|
|
||||||
show: "Файлы машин",
|
|
||||||
link: "/html/file_viewer/machine_data"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{type: "line"},
|
|
||||||
{
|
|
||||||
type: "group",
|
|
||||||
show: "Работоспособность сервсисов",
|
|
||||||
icon: "cloud-cog",
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
type: "simple_link",
|
|
||||||
icon: "cpu",
|
|
||||||
show: "ДИАП",
|
|
||||||
link: "/admin_panel/services/diap"
|
|
||||||
},
|
|
||||||
{type: "simple_link", icon: "table", show: "Сервисы", link: "/html/communications"},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "group",
|
|
||||||
show: "Админка",
|
|
||||||
icon: "hand-metal",
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
type: "simple_link",
|
|
||||||
icon: "haze",
|
|
||||||
show: "Сервис управления",
|
|
||||||
link: "/admin_panel/auth_service"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: "simple_link",
|
|
||||||
icon: "line-chart",
|
|
||||||
show: "Анализ топлива",
|
|
||||||
link: "/admin_panel/fuel_analyzer"
|
|
||||||
},
|
|
||||||
{type: "simple_link", icon: "newspaper", show: "Обновления", link: "/html/updates"},
|
|
||||||
{type: "simple_link", icon: "boxes", show: "Пакеты", link: "/admin_panel/packs"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{type: "line"},
|
|
||||||
{type: "simple_link", icon: "newspaper", show: "Обновления", link: "/html/updates", router: "news"},
|
|
||||||
]
|
|
||||||
|
|
||||||
export {orisMenu}
|
|
||||||
19
live_monitor_vue/src/store/modules/layout/stateHelpers.js
Normal file
19
live_monitor_vue/src/store/modules/layout/stateHelpers.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
const initScreenListener = (state) => {
|
||||||
|
state.height = window.innerHeight
|
||||||
|
state.width = window.innerWidth
|
||||||
|
window.addEventListener("resize", (e) => {
|
||||||
|
state.height= e.target.innerHeight
|
||||||
|
state.width = e.target.innerWidth
|
||||||
|
});
|
||||||
|
return "ok"
|
||||||
|
}
|
||||||
|
|
||||||
|
const disableScreenListener = (state) => {
|
||||||
|
window.removeEventListener("resize", () => {
|
||||||
|
state.height = null
|
||||||
|
state.width = null
|
||||||
|
});
|
||||||
|
return "ok"
|
||||||
|
}
|
||||||
|
|
||||||
|
export { initScreenListener, disableScreenListener }
|
||||||
@ -7,7 +7,7 @@
|
|||||||
&.mobile-menu--active {
|
&.mobile-menu--active {
|
||||||
&:before {
|
&:before {
|
||||||
content: "";
|
content: "";
|
||||||
@apply visible opacity-100;
|
@apply visible opacity-100 h-[110vh];
|
||||||
}
|
}
|
||||||
.scrollable {
|
.scrollable {
|
||||||
@apply ml-0 overflow-y-auto;
|
@apply ml-0 overflow-y-auto;
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import {test, describe, expect} from 'vitest'
|
import {test, describe, expect} from 'vitest'
|
||||||
import { mount} from '@vue/test-utils'
|
import { mount} from '@vue/test-utils'
|
||||||
import Button from '@atoms/VButton.vue';
|
import VButton from '@atoms/VButton.vue';
|
||||||
|
|
||||||
describe('Accordion', () => {
|
describe('VButton', () => {
|
||||||
test('Accordion mounted', () => {
|
test('VButton mounted', () => {
|
||||||
const wrapper = mount(Button)
|
const wrapper = mount(VButton)
|
||||||
expect(wrapper.exists()).toBe(true)
|
expect(wrapper.exists()).toBe(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
import {test, describe, expect, } from 'vitest'
|
||||||
|
import { shallowMount} from '@vue/test-utils'
|
||||||
|
import AppContainer from '@frames/AppContainer/AppContainer.vue';
|
||||||
|
import {createStore} from "vuex";
|
||||||
|
import { store as layout } from '@/store/modules/layout';
|
||||||
|
import { store as auth } from '@/store/modules/auth';
|
||||||
|
|
||||||
|
describe('AppContainer', () => {
|
||||||
|
const store = createStore({
|
||||||
|
modules: {
|
||||||
|
layout,
|
||||||
|
auth
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
test('AppContainer mounted', () => {
|
||||||
|
const wrapper = shallowMount(AppContainer,
|
||||||
|
{
|
||||||
|
global: {
|
||||||
|
mocks: {
|
||||||
|
$store: store,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
)
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import {test, describe, expect, } from 'vitest'
|
||||||
|
import { shallowMount} from '@vue/test-utils'
|
||||||
|
import AppContainerBreadcrumbs from '@frames/AppContainer/AppContainerBreadcrumbs.vue';
|
||||||
|
|
||||||
|
describe('AppContainerBreadcrumbs', () => {
|
||||||
|
test('AppContainerBreadcrumbs mounted', () => {
|
||||||
|
const wrapper = shallowMount(AppContainerBreadcrumbs)
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import {test, describe, expect, } from 'vitest'
|
||||||
|
import { shallowMount} from '@vue/test-utils'
|
||||||
|
import AppContainerHeader from '@frames/AppContainer/AppContainerHeader.vue';
|
||||||
|
|
||||||
|
describe('AppContainerHeader', () => {
|
||||||
|
test('AppContainerHeader mounted', () => {
|
||||||
|
const wrapper = shallowMount(AppContainerHeader)
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
import {test, describe, expect, } from 'vitest'
|
||||||
|
import { shallowMount} from '@vue/test-utils'
|
||||||
|
import AppContainerLeftPanel from '@frames/AppContainer/AppContainerLeftPanel.vue';
|
||||||
|
import Router from "@router"
|
||||||
|
|
||||||
|
describe('AppContainerLeftPanel', () => {
|
||||||
|
test('AppContainerLeftPanel mounted', () => {
|
||||||
|
const wrapper = shallowMount(AppContainerLeftPanel,
|
||||||
|
{
|
||||||
|
global: {
|
||||||
|
plugins: [Router]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
import {test, describe, expect, } from 'vitest'
|
||||||
|
import { shallowMount} from '@vue/test-utils'
|
||||||
|
import AppContainerMobileMenu from '@frames/AppContainer/AppContainerMobileMenu.vue';
|
||||||
|
|
||||||
|
describe('AppContainerMobileMenu', () => {
|
||||||
|
test('AppContainerMobileMenu mounted', () => {
|
||||||
|
const wrapper = shallowMount(AppContainerMobileMenu, {
|
||||||
|
props: {
|
||||||
|
isOpenedMobileMenu: false,
|
||||||
|
setIsMobileMenuOpened: () => {},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
import {test, describe, expect, } from 'vitest'
|
||||||
|
import { shallowMount} from '@vue/test-utils'
|
||||||
|
import AppContainerRightPanel from '@frames/AppContainer/AppContainerRightPanel.vue';
|
||||||
|
import Router from "@router"
|
||||||
|
|
||||||
|
describe('AppContainerRightPanel', () => {
|
||||||
|
test('AppContainerRightPanel mounted', () => {
|
||||||
|
const wrapper = shallowMount(AppContainerRightPanel, {
|
||||||
|
props: {
|
||||||
|
currentUser: {
|
||||||
|
id: 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
global: {
|
||||||
|
plugins: [Router]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
import {test, describe, expect, } from 'vitest'
|
||||||
|
import { shallowMount} from '@vue/test-utils'
|
||||||
|
import MenuList from '@frames/AppContainer/MenuList/MenuList.vue';
|
||||||
|
|
||||||
|
describe('MenuList', () => {
|
||||||
|
|
||||||
|
test('MenuList mounted', () => {
|
||||||
|
const wrapper = shallowMount(MenuList, {
|
||||||
|
props: {
|
||||||
|
routeName: ""
|
||||||
|
}
|
||||||
|
})
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
import {test, describe, expect, } from 'vitest'
|
||||||
|
import { shallowMount} from '@vue/test-utils'
|
||||||
|
import MenuListItem from '@frames/AppContainer/MenuList/MenuListItem.vue';
|
||||||
|
|
||||||
|
describe('MenuListItem', () => {
|
||||||
|
|
||||||
|
test('MenuListItem mounted', () => {
|
||||||
|
const wrapper = shallowMount(MenuListItem)
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import {test, describe, expect, } from 'vitest'
|
||||||
|
import { shallowMount} from '@vue/test-utils'
|
||||||
|
import MenuListItemCopy from '@frames/AppContainer/MenuList/MenuListItemCopy.vue';
|
||||||
|
|
||||||
|
describe('MenuListItemCopy', () => {
|
||||||
|
test('MenuListItemCopy mounted', () => {
|
||||||
|
const wrapper = shallowMount(MenuListItemCopy)
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import {test, describe, expect, } from 'vitest'
|
||||||
|
import { shallowMount} from '@vue/test-utils'
|
||||||
|
import MenuListItemGroup from '@frames/AppContainer/MenuList/MenuListItemGroup.vue';
|
||||||
|
|
||||||
|
describe('MenuListItemGroup', () => {
|
||||||
|
test('MenuListItemGroup mounted', () => {
|
||||||
|
const wrapper = shallowMount(MenuListItemGroup)
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
import {test, describe, expect, } from 'vitest'
|
||||||
|
import { shallowMount} from '@vue/test-utils'
|
||||||
|
import MenuListItemImplementation from '@frames/AppContainer/MenuList/MenuListItemImplementation.vue';
|
||||||
|
import Router from "@router"
|
||||||
|
|
||||||
|
describe('MenuListItemImplementation', () => {
|
||||||
|
|
||||||
|
test('MenuListItemImplementation mounted', () => {
|
||||||
|
const wrapper = shallowMount(MenuListItemImplementation,
|
||||||
|
{
|
||||||
|
global: {
|
||||||
|
plugins: [Router]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import {test, describe, expect} from 'vitest'
|
||||||
|
import { mount} from '@vue/test-utils'
|
||||||
|
import PacksContainer from '@frames/PacksContainer/PacksContainer.vue';
|
||||||
|
|
||||||
|
describe('PacksContainer', () => {
|
||||||
|
test('PacksContainer mounted', () => {
|
||||||
|
const wrapper = mount(PacksContainer)
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import {test, describe, expect} from 'vitest'
|
||||||
|
import { mount} from '@vue/test-utils'
|
||||||
|
import PacksContainerBody from '@frames/PacksContainer/PacksContainerBody.vue';
|
||||||
|
|
||||||
|
describe('PacksContainerBody', () => {
|
||||||
|
test('PacksContainerBody mounted', () => {
|
||||||
|
const wrapper = mount(PacksContainerBody)
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
import {test, describe, expect} from 'vitest'
|
||||||
|
import { mount} from '@vue/test-utils'
|
||||||
|
import PacksContainerControl from '@frames/PacksContainer//PacksContainerControl.vue';
|
||||||
|
|
||||||
|
describe('PacksContainerControl', () => {
|
||||||
|
test('PacksContainerControl mounted', () => {
|
||||||
|
const wrapper = mount(PacksContainerControl)
|
||||||
|
expect(wrapper.exists()).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
51
live_monitor_vue/tests/services/ServiceOfLayout.test.js
Normal file
51
live_monitor_vue/tests/services/ServiceOfLayout.test.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import {expect, describe, test, beforeEach} from 'vitest'
|
||||||
|
import ServiceOfLayout from "@services/ServiceOfLayout.js"
|
||||||
|
import { createStore } from "vuex"
|
||||||
|
import { store as layout } from '@/store/modules/layout';
|
||||||
|
|
||||||
|
describe('test ServiceOfLayout', () => {
|
||||||
|
const store = createStore({
|
||||||
|
modules: {
|
||||||
|
layout
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
store.dispatch('layout/resetStore')
|
||||||
|
})
|
||||||
|
|
||||||
|
const serviceOfLayout = new ServiceOfLayout(store)
|
||||||
|
|
||||||
|
test('test ServiceOfLayout exist', async () => {
|
||||||
|
expect(serviceOfLayout).toBeTruthy()
|
||||||
|
expect(serviceOfLayout.getHeight()).toBe(0)
|
||||||
|
expect(serviceOfLayout.getWidth()).toBe(0)
|
||||||
|
expect(serviceOfLayout.getIsOpenMenu()).toBe(false)
|
||||||
|
expect(serviceOfLayout.getIsEnabledMenu()).toBe(true)
|
||||||
|
expect(serviceOfLayout.getIsShowMenu()).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test toggleMenu', async () => {
|
||||||
|
serviceOfLayout.toggleMenu()
|
||||||
|
const result = store.getters['layout/isShowMenu']
|
||||||
|
expect(result).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('setIsShowMenu', async () => {
|
||||||
|
serviceOfLayout.setIsShowMenu(false)
|
||||||
|
const result = serviceOfLayout.getIsShowMenu()
|
||||||
|
expect(result).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('setIsOpenMenu', async () => {
|
||||||
|
serviceOfLayout.setIsOpenMenu(true)
|
||||||
|
const result = serviceOfLayout.getIsOpenMenu()
|
||||||
|
expect(result).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('setIsEnabledMenu', async () => {
|
||||||
|
serviceOfLayout.setIsEnabledMenu(false)
|
||||||
|
const result = serviceOfLayout.getIsEnabledMenu()
|
||||||
|
expect(result).toBe(false)
|
||||||
|
})
|
||||||
|
})
|
||||||
53
live_monitor_vue/tests/store/layout.test.js
Normal file
53
live_monitor_vue/tests/store/layout.test.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import {expect, describe, test, beforeEach} from 'vitest'
|
||||||
|
import { createStore } from "vuex"
|
||||||
|
import { store as layout } from '@/store/modules/layout';
|
||||||
|
|
||||||
|
describe('test of layout store', () => {
|
||||||
|
const store = createStore({
|
||||||
|
modules: {
|
||||||
|
layout
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
store.dispatch('layout/resetStore')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test layout store exist', async () => {
|
||||||
|
expect(store).toBeTruthy()
|
||||||
|
expect(store.getters['layout/isOpenedMobileMenu']).toBe(false)
|
||||||
|
expect(store.getters['layout/isEnabledMenu']).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test toggleMenu', () => {
|
||||||
|
store.dispatch('layout/toggleMenu')
|
||||||
|
const result = store.getters['layout/isShowMenu']
|
||||||
|
expect(result).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test setIsShowMenu', () => {
|
||||||
|
store.dispatch('layout/setIsShowMenu', false)
|
||||||
|
const result = store.getters['layout/isShowMenu']
|
||||||
|
expect(result).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test setIsMobileMenuOpened', () => {
|
||||||
|
store.dispatch('layout/setIsMobileMenuOpened', true)
|
||||||
|
const result = store.getters['layout/isOpenedMobileMenu']
|
||||||
|
expect(result).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test resetStore', () => {
|
||||||
|
store.dispatch('layout/resetStore')
|
||||||
|
const result = store.getters['layout/isShowMenu']
|
||||||
|
expect(result).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('test initScreenSizeListener', () => {
|
||||||
|
store.dispatch('layout/initScreenSizeListener')
|
||||||
|
const result = store.getters['layout/initedScreenListener']
|
||||||
|
expect(result).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
Loading…
x
Reference in New Issue
Block a user