Merge branch 'dev-bagus' of github.com:defuj/eis into dev-bagus
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
npm-debug.log
|
2
.env.development
Normal file → Executable file
@ -2,3 +2,5 @@ VITE_BASE_URL=http://localhost:5173
|
||||
VITE_BASE_DIRECTORY=/
|
||||
VITE_APP_VERSION=0.0.1
|
||||
VITE_APP_NAME='Executive Information System'
|
||||
VITE_APP_GRAPHQL_ENDPOINT=http://192.168.191.163:32169/graphql
|
||||
VITE_APP_REST_ENDPOINT=http://192.168.191.163:32180
|
2
.env.production
Normal file → Executable file
@ -2,3 +2,5 @@ VITE_BASE_URL=https://api.domain.com/v1/
|
||||
VITE_BASE_DIRECTORY=/
|
||||
VITE_APP_VERSION=0.0.1
|
||||
VITE_APP_NAME='Executive Information System'
|
||||
VITE_APP_GRAPHQL_ENDPOINT=http://10.1.50.173:32180/graphql
|
||||
VITE_APP_REST_ENDPOINT=http://10.1.50.173:32181
|
0
.eslintrc.cjs
Normal file → Executable file
11
.github/workflows/docker-image-development.yml
vendored
Normal file → Executable file
@ -2,19 +2,16 @@ name: Publish Docker Image Development
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "development" ]
|
||||
branches: ['development']
|
||||
pull_request:
|
||||
branches: [ "development" ]
|
||||
branches: ['development']
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{github.event.head_commit.message}} == *'build image'*
|
||||
|
||||
steps:
|
||||
|
||||
- name: Docker Hub Login
|
||||
env:
|
||||
DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}}
|
||||
@ -24,5 +21,5 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build the Docker image
|
||||
run: |
|
||||
docker build . -t defuj/apkt-eis:v1.0.0-dev
|
||||
docker push defuj/apkt-eis:v1.0.0-dev
|
||||
docker build . --file Dockerfile --tag defuj/apkt-eis:v0.0.10-vm
|
||||
docker push defuj/apkt-eis:v0.0.10-vm
|
||||
|
3
.github/workflows/docker-image-release.yml
vendored
@ -23,8 +23,7 @@ jobs:
|
||||
|
||||
- name: Build the Docker image
|
||||
run: |
|
||||
docker build . -t defuj/apkt-eis
|
||||
docker image tag defuj/apkt-eis defuj/apkt-eis:v1.0.1-release
|
||||
docker build . --file Dockerfile --tag defuj/apkt-eis:v1.0.1-release
|
||||
docker push defuj/apkt-eis:v1.0.1-release
|
||||
|
||||
|
||||
|
1
.gitignore
vendored
Normal file → Executable file
@ -11,6 +11,7 @@ lerna-debug.log*
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
build
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
0
.prettierrc.json
Normal file → Executable file
@ -1,553 +0,0 @@
|
||||
[
|
||||
"-left-2",
|
||||
"-mr-1",
|
||||
"-mr-12",
|
||||
"-translate-x-full",
|
||||
"-translate-y-2/4",
|
||||
"2xl:text-sm",
|
||||
"absolute",
|
||||
"animate-spin",
|
||||
"auto-cols-auto",
|
||||
"backdrop-blur",
|
||||
"bg-black",
|
||||
"bg-gray-100",
|
||||
"bg-gray-200",
|
||||
"bg-gray-50",
|
||||
"bg-gray-500",
|
||||
"bg-gray-600",
|
||||
"bg-gray-900",
|
||||
"bg-indigo-600",
|
||||
"bg-layout",
|
||||
"bg-none",
|
||||
"bg-opacity-100",
|
||||
"bg-opacity-25",
|
||||
"bg-opacity-5",
|
||||
"bg-opacity-60",
|
||||
"bg-opacity-75",
|
||||
"bg-opacity-80",
|
||||
"bg-primary-100",
|
||||
"bg-primary-400",
|
||||
"bg-primary-50",
|
||||
"bg-primary-500",
|
||||
"bg-red-100",
|
||||
"bg-red-600",
|
||||
"bg-secondary-100",
|
||||
"bg-teal-600",
|
||||
"bg-vtd-primary-100",
|
||||
"bg-vtd-primary-500",
|
||||
"bg-vtd-primary-600",
|
||||
"bg-white",
|
||||
"bg-yellow-100",
|
||||
"bg-yellow-600",
|
||||
"block",
|
||||
"blur",
|
||||
"border",
|
||||
"border-0",
|
||||
"border-b",
|
||||
"border-b-0",
|
||||
"border-black/[.1]",
|
||||
"border-gray-300",
|
||||
"border-gray-600",
|
||||
"border-none",
|
||||
"border-primary-500",
|
||||
"border-r",
|
||||
"border-solid",
|
||||
"border-t",
|
||||
"border-transparent",
|
||||
"bottom-0",
|
||||
"col-span-7",
|
||||
"cursor-default",
|
||||
"cursor-pointer",
|
||||
"dark:bg-opacity-50",
|
||||
"dark:focus:bg-opacity-50",
|
||||
"dark:focus:border-vtd-primary-500",
|
||||
"dark:focus:ring-opacity-20",
|
||||
"dark:focus:ring-opacity-25",
|
||||
"dark:focus:text-vtd-primary-300",
|
||||
"dark:hover:text-vtd-primary-300",
|
||||
"dark:text-opacity-70",
|
||||
"dark:text-vtd-primary-400",
|
||||
"delay-300",
|
||||
"disabled:bg-primary-200",
|
||||
"disabled:bg-primary-300",
|
||||
"disabled:bg-primary-400",
|
||||
"disabled:border-primary-300",
|
||||
"disabled:cursor-not-allowed",
|
||||
"disabled:text-primary-300",
|
||||
"disabled:text-primary-400",
|
||||
"divide-gray-500",
|
||||
"divide-opacity-10",
|
||||
"divide-y",
|
||||
"duration-100",
|
||||
"duration-150",
|
||||
"duration-200",
|
||||
"duration-300",
|
||||
"duration-500",
|
||||
"duration-75",
|
||||
"ease-in",
|
||||
"ease-in-out",
|
||||
"ease-linear",
|
||||
"ease-out",
|
||||
"fill-gray-500",
|
||||
"fill-gray-600",
|
||||
"fill-green-600",
|
||||
"fill-primary-300",
|
||||
"fill-primary-500",
|
||||
"fill-red-600",
|
||||
"fill-white",
|
||||
"filter",
|
||||
"fixed",
|
||||
"flex",
|
||||
"flex-1",
|
||||
"flex-col",
|
||||
"flex-grow",
|
||||
"flex-none",
|
||||
"flex-row",
|
||||
"flex-shrink-0",
|
||||
"flex-wrap",
|
||||
"focus-visible:outline",
|
||||
"focus-visible:outline-2",
|
||||
"focus-visible:outline-indigo-600",
|
||||
"focus-visible:outline-offset-2",
|
||||
"focus-visible:ring-2",
|
||||
"focus-visible:ring-offset-2",
|
||||
"focus-visible:ring-offset-teal-300",
|
||||
"focus-visible:ring-opacity-75",
|
||||
"focus-visible:ring-white",
|
||||
"focus:bg-vtd-primary-50",
|
||||
"focus:border-0",
|
||||
"focus:border-vtd-primary-300",
|
||||
"focus:outline-0",
|
||||
"focus:outline-none",
|
||||
"focus:ring",
|
||||
"focus:ring-0",
|
||||
"focus:ring-2",
|
||||
"focus:ring-indigo-500",
|
||||
"focus:ring-inset",
|
||||
"focus:ring-offset-0",
|
||||
"focus:ring-offset-2",
|
||||
"focus:ring-opacity-10",
|
||||
"focus:ring-primary-500",
|
||||
"focus:ring-vtd-primary-500",
|
||||
"focus:ring-white",
|
||||
"focus:text-gray-500",
|
||||
"focus:text-vtd-primary-600",
|
||||
"font-bold",
|
||||
"font-light",
|
||||
"font-medium",
|
||||
"font-normal",
|
||||
"font-semibold",
|
||||
"gap-1",
|
||||
"gap-3",
|
||||
"gap-x-1",
|
||||
"gap-x-1.5",
|
||||
"gap-x-2",
|
||||
"gap-x-6",
|
||||
"gap-y-0",
|
||||
"gap-y-0.5",
|
||||
"gap-y-1",
|
||||
"grid",
|
||||
"grid-cols-2",
|
||||
"grid-cols-7",
|
||||
"grid-flow-col",
|
||||
"group-hover:bg-opacity-80",
|
||||
"group-hover:bg-primary-500",
|
||||
"group-hover:block",
|
||||
"group-hover:fill-primary-500",
|
||||
"group-hover:fill-white",
|
||||
"group-hover:text-gray-500",
|
||||
"group-hover:text-primary-500",
|
||||
"group-hover:text-white",
|
||||
"grow",
|
||||
"h-0",
|
||||
"h-10",
|
||||
"h-11",
|
||||
"h-12",
|
||||
"h-16",
|
||||
"h-4",
|
||||
"h-5",
|
||||
"h-6",
|
||||
"h-7",
|
||||
"h-8",
|
||||
"h-9",
|
||||
"h-[2.7rem]",
|
||||
"h-[56px]",
|
||||
"h-[66px]",
|
||||
"h-[calc(100%-64px)]",
|
||||
"h-[calc(90vh-24px)]",
|
||||
"h-fit",
|
||||
"h-full",
|
||||
"h-screen-80",
|
||||
"hidden",
|
||||
"hover:bg-gray-50",
|
||||
"hover:bg-indigo-500",
|
||||
"hover:bg-indigo-700",
|
||||
"hover:bg-primary-100",
|
||||
"hover:bg-primary-200",
|
||||
"hover:bg-primary-600",
|
||||
"hover:bg-red-500",
|
||||
"hover:bg-vtd-primary-700",
|
||||
"hover:bg-yellow-500",
|
||||
"hover:border-primary-500",
|
||||
"hover:text-primary-500",
|
||||
"hover:text-vtd-primary-700",
|
||||
"inline-block",
|
||||
"inline-flex",
|
||||
"inset-0",
|
||||
"inset-y-0",
|
||||
"italic",
|
||||
"items-center",
|
||||
"items-start",
|
||||
"justify-between",
|
||||
"justify-center",
|
||||
"justify-end",
|
||||
"justify-start",
|
||||
"leading-5",
|
||||
"leading-6",
|
||||
"leading-7",
|
||||
"leading-none",
|
||||
"leading-relaxed",
|
||||
"left-0",
|
||||
"left-4",
|
||||
"left-auto",
|
||||
"lg:block",
|
||||
"lg:border-b-0",
|
||||
"lg:border-r",
|
||||
"lg:flex-nowrap",
|
||||
"lg:grid-cols-3",
|
||||
"lg:h-10",
|
||||
"lg:mb-0",
|
||||
"lg:mr-1",
|
||||
"lg:mt-12",
|
||||
"lg:mt-6",
|
||||
"lg:mx-0",
|
||||
"lg:px-8",
|
||||
"lg:text-xs",
|
||||
"lg:w-10",
|
||||
"lg:w-80",
|
||||
"line-clamp-1",
|
||||
"max-h-0",
|
||||
"max-h-60",
|
||||
"max-h-[1000px]",
|
||||
"max-h-[calc(100vh-140px)]",
|
||||
"max-w-2xl",
|
||||
"max-w-7xl",
|
||||
"max-w-sm",
|
||||
"max-w-xs",
|
||||
"mb-2",
|
||||
"mb-3",
|
||||
"mb-4",
|
||||
"mb-6",
|
||||
"mb-8",
|
||||
"md:bg-primary-500",
|
||||
"md:block",
|
||||
"md:fixed",
|
||||
"md:flex",
|
||||
"md:flex-col",
|
||||
"md:h-16",
|
||||
"md:hidden",
|
||||
"md:inset-y-0",
|
||||
"md:ml-6",
|
||||
"md:ml-80",
|
||||
"md:mr-3",
|
||||
"md:mr-6",
|
||||
"md:mt-8",
|
||||
"md:p-20",
|
||||
"md:pl-4",
|
||||
"md:pl-80",
|
||||
"md:px-6",
|
||||
"md:py-0",
|
||||
"md:rounded-t-3xl",
|
||||
"md:text-2xl",
|
||||
"md:text-3xl",
|
||||
"md:w-1/2",
|
||||
"md:w-80",
|
||||
"md:w-[300px]",
|
||||
"md:w-[440px]",
|
||||
"me-1",
|
||||
"min-h-full",
|
||||
"min-h-screen",
|
||||
"ml-1",
|
||||
"ml-2",
|
||||
"ml-3",
|
||||
"ml-4",
|
||||
"mr-1",
|
||||
"mr-2",
|
||||
"mt-0",
|
||||
"mt-0.5",
|
||||
"mt-1",
|
||||
"mt-1.5",
|
||||
"mt-10",
|
||||
"mt-2",
|
||||
"mt-3",
|
||||
"mt-3.5",
|
||||
"mt-4",
|
||||
"mt-5",
|
||||
"mt-6",
|
||||
"mx-2",
|
||||
"mx-3",
|
||||
"mx-auto",
|
||||
"my-1",
|
||||
"my-auto",
|
||||
"object-contain",
|
||||
"opacity-0",
|
||||
"opacity-100",
|
||||
"opacity-25",
|
||||
"opacity-30",
|
||||
"opacity-40",
|
||||
"opacity-50",
|
||||
"opacity-75",
|
||||
"order-last",
|
||||
"ordinal",
|
||||
"origin-top-left",
|
||||
"outline",
|
||||
"outline-0",
|
||||
"overflow-auto",
|
||||
"overflow-hidden",
|
||||
"overflow-y-auto",
|
||||
"p-1",
|
||||
"p-1.5",
|
||||
"p-2",
|
||||
"p-4",
|
||||
"pb-4",
|
||||
"peer-checked:text-primary-500",
|
||||
"pl-1",
|
||||
"pl-10",
|
||||
"pl-11",
|
||||
"pl-2",
|
||||
"pl-3",
|
||||
"place-items-center",
|
||||
"placeholder-gray-500",
|
||||
"placeholder:text-gray-400",
|
||||
"placeholder:text-sm",
|
||||
"pointer-events-auto",
|
||||
"pointer-events-none",
|
||||
"pr-10",
|
||||
"pr-12",
|
||||
"pr-2",
|
||||
"pr-4",
|
||||
"pr-5",
|
||||
"pr-7",
|
||||
"pt-0",
|
||||
"pt-0.5",
|
||||
"pt-2",
|
||||
"pt-5",
|
||||
"px-0",
|
||||
"px-0.5",
|
||||
"px-1",
|
||||
"px-1.5",
|
||||
"px-2",
|
||||
"px-3",
|
||||
"px-3.5",
|
||||
"px-4",
|
||||
"px-6",
|
||||
"py-0",
|
||||
"py-1",
|
||||
"py-1.5",
|
||||
"py-14",
|
||||
"py-2",
|
||||
"py-2.5",
|
||||
"py-24",
|
||||
"py-3",
|
||||
"py-4",
|
||||
"py-6",
|
||||
"relative",
|
||||
"right-0",
|
||||
"right-auto",
|
||||
"ring-0",
|
||||
"ring-1",
|
||||
"ring-black",
|
||||
"ring-gray-300",
|
||||
"ring-inset",
|
||||
"ring-opacity-5",
|
||||
"rotate-180",
|
||||
"rounded",
|
||||
"rounded-2xl",
|
||||
"rounded-b-2xl",
|
||||
"rounded-full",
|
||||
"rounded-l-full",
|
||||
"rounded-lg",
|
||||
"rounded-md",
|
||||
"rounded-r-full",
|
||||
"rounded-t-2xl",
|
||||
"rounded-xl",
|
||||
"scale-100",
|
||||
"scale-95",
|
||||
"scroll-py-2",
|
||||
"select-none",
|
||||
"shadow",
|
||||
"shadow-2xl",
|
||||
"shadow-gray-50",
|
||||
"shadow-lg",
|
||||
"shadow-md",
|
||||
"shadow-sm",
|
||||
"shadow-xl",
|
||||
"shrink",
|
||||
"sm:border",
|
||||
"sm:border-b",
|
||||
"sm:border-t-0",
|
||||
"sm:col-start-1",
|
||||
"sm:col-start-2",
|
||||
"sm:flex",
|
||||
"sm:flex-1",
|
||||
"sm:flex-nowrap",
|
||||
"sm:flex-row-reverse",
|
||||
"sm:font-medium",
|
||||
"sm:gap-3",
|
||||
"sm:grid",
|
||||
"sm:grid-cols-2",
|
||||
"sm:grid-cols-3",
|
||||
"sm:grid-flow-row-dense",
|
||||
"sm:h-10",
|
||||
"sm:hidden",
|
||||
"sm:items-center",
|
||||
"sm:items-start",
|
||||
"sm:justify-between",
|
||||
"sm:justify-start",
|
||||
"sm:leading-4",
|
||||
"sm:max-w-lg",
|
||||
"sm:max-w-sm",
|
||||
"sm:mb-0",
|
||||
"sm:mb-1",
|
||||
"sm:mb-1.5",
|
||||
"sm:ml-2",
|
||||
"sm:ml-3",
|
||||
"sm:ml-4",
|
||||
"sm:mr-2",
|
||||
"sm:mt-0",
|
||||
"sm:mt-1",
|
||||
"sm:mt-2",
|
||||
"sm:mt-2.5",
|
||||
"sm:mt-4",
|
||||
"sm:mt-5",
|
||||
"sm:mt-6",
|
||||
"sm:mx-0",
|
||||
"sm:mx-1",
|
||||
"sm:my-8",
|
||||
"sm:order-none",
|
||||
"sm:overflow-visible",
|
||||
"sm:p-0",
|
||||
"sm:p-6",
|
||||
"sm:pb-4",
|
||||
"sm:pr-6",
|
||||
"sm:px-14",
|
||||
"sm:px-2",
|
||||
"sm:px-3",
|
||||
"sm:px-4",
|
||||
"sm:py-32",
|
||||
"sm:py-4",
|
||||
"sm:relative",
|
||||
"sm:rounded-lg",
|
||||
"sm:scale-100",
|
||||
"sm:scale-95",
|
||||
"sm:shadow-sm",
|
||||
"sm:space-x-10",
|
||||
"sm:space-x-4",
|
||||
"sm:space-x-5",
|
||||
"sm:space-x-reverse",
|
||||
"sm:space-y-0",
|
||||
"sm:static",
|
||||
"sm:text-5xl",
|
||||
"sm:text-left",
|
||||
"sm:text-sm",
|
||||
"sm:translate-y-0",
|
||||
"sm:w-10",
|
||||
"sm:w-auto",
|
||||
"sm:w-full",
|
||||
"sm:z-auto",
|
||||
"space-x-1",
|
||||
"space-x-1.5",
|
||||
"space-y-1",
|
||||
"space-y-2",
|
||||
"space-y-3",
|
||||
"space-y-4",
|
||||
"sr-only",
|
||||
"static",
|
||||
"sticky",
|
||||
"stroke-white",
|
||||
"text-2xl",
|
||||
"text-3xl",
|
||||
"text-[8px]",
|
||||
"text-aside",
|
||||
"text-base",
|
||||
"text-blue-400",
|
||||
"text-center",
|
||||
"text-dark",
|
||||
"text-gray-200",
|
||||
"text-gray-300",
|
||||
"text-gray-400",
|
||||
"text-gray-500",
|
||||
"text-gray-600",
|
||||
"text-gray-700",
|
||||
"text-gray-800",
|
||||
"text-gray-900",
|
||||
"text-green-400",
|
||||
"text-green-600",
|
||||
"text-indigo-600",
|
||||
"text-left",
|
||||
"text-lg",
|
||||
"text-opacity-40",
|
||||
"text-orange-400",
|
||||
"text-orange-600",
|
||||
"text-primary-50",
|
||||
"text-primary-500",
|
||||
"text-primary-800",
|
||||
"text-red-400",
|
||||
"text-red-600",
|
||||
"text-slate-600",
|
||||
"text-slate-900",
|
||||
"text-sm",
|
||||
"text-start",
|
||||
"text-teal-600",
|
||||
"text-vtd-primary-500",
|
||||
"text-vtd-primary-600",
|
||||
"text-white",
|
||||
"text-xl",
|
||||
"text-xs",
|
||||
"text-yellow-700",
|
||||
"top-0",
|
||||
"top-1/2",
|
||||
"top-3",
|
||||
"top-3.5",
|
||||
"top-full",
|
||||
"tracking-tight",
|
||||
"tracking-wide",
|
||||
"transform",
|
||||
"transition",
|
||||
"transition-all",
|
||||
"transition-colors",
|
||||
"transition-opacity",
|
||||
"transition-transform",
|
||||
"translate-x-0",
|
||||
"translate-x-4",
|
||||
"translate-y-0",
|
||||
"translate-y-3",
|
||||
"translate-y-4",
|
||||
"truncate",
|
||||
"uppercase",
|
||||
"visible",
|
||||
"w-0",
|
||||
"w-1/2",
|
||||
"w-10",
|
||||
"w-12",
|
||||
"w-14",
|
||||
"w-16",
|
||||
"w-4",
|
||||
"w-5",
|
||||
"w-56",
|
||||
"w-6",
|
||||
"w-8",
|
||||
"w-80",
|
||||
"w-9",
|
||||
"w-[170px]",
|
||||
"w-[2.7rem]",
|
||||
"w-[266px]",
|
||||
"w-auto",
|
||||
"w-full",
|
||||
"whitespace-nowrap",
|
||||
"whitespace-pre-wrap",
|
||||
"z-10",
|
||||
"z-20",
|
||||
"z-40",
|
||||
"z-50"
|
||||
]
|
0
.vscode/extensions.json
vendored
Normal file → Executable file
27
Dockerfile
Normal file → Executable file
@ -1,13 +1,20 @@
|
||||
FROM node:lts-alpine as build-stage
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
# syntax=docker/dockerfile:1
|
||||
# build stage
|
||||
# FROM node:lts-alpine as builder
|
||||
# WORKDIR /apkt
|
||||
# COPY package*.json ./
|
||||
# RUN npm install && npm install npm-run-all -g
|
||||
# COPY . .
|
||||
# RUN npm run build
|
||||
# # production stage
|
||||
# FROM nginx:stable-alpine
|
||||
# COPY --from=builder /apkt/dist /usr/share/nginx/html
|
||||
# COPY --from=builder /apkt/nginx.conf /etc/nginx/nginx.conf
|
||||
# EXPOSE 32166
|
||||
# CMD ["nginx", "-g", "daemon off;"]
|
||||
|
||||
# tahap produksi
|
||||
FROM nginx:stable-alpine as production-stage
|
||||
COPY --from=build-stage /app/dist /usr/share/nginx/html
|
||||
COPY --from=build-stage /app/nginx.conf /etc/nginx/nginx.conf
|
||||
FROM nginx:stable-alpine
|
||||
COPY /dist /usr/share/nginx/html
|
||||
COPY /nginx.conf /etc/nginx/nginx.conf
|
||||
EXPOSE 32166
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
76
README.md
Normal file → Executable file
@ -1,52 +1,26 @@
|
||||
# Executive Information System
|
||||
# TABLE MENU DOCUMENTATION
|
||||
## Monalisa
|
||||
### Gangguan > Rekapitulasi
|
||||
| CODE | MENU | FILE |
|
||||
| ------- | ---------------------------------------- | ------------ |
|
||||
| MON0001 | Jumlah Kali Gangguan | Table_36.vue |
|
||||
| MON0002 | Dispacthing Time (DT) Gangguan | Table_37.vue |
|
||||
| MON0003 | Recovery Time (RCT) Gangguan | Table_38.vue |
|
||||
| MON0004 | Response Time (RPT) Gangguan | Table_39.vue |
|
||||
| MON0005 | Jumlah dan Durasi RPT RCT Gangguan | Table_40.vue |
|
||||
| MON0006 | Rekapitulasi Gangguan Per Jenis Gangguan | Table_41.vue |
|
||||
| MON0007 | Rekapitulasi Lapor Ulang Gangguan | Table_42.vue |
|
||||
| MON0008 | Rekapitulasi ENS Gangguan | Table_43.vue |
|
||||
| MON0009 | Rekapitulasi Gangguan Belum Selesai | Table_44.vue |
|
||||
| MON0010 | Jumlah Kali Keluhan | Table_45.vue |
|
||||
| MON0011 | Recovery Time (RCT) Keluhan | Table_46.vue |
|
||||
| MON0012 | Response Time (RPT) Keluhan | Table_47.vue |
|
||||
| MON0013 | Jumlah dan Durasi RPT RCT Keluhan | Table_48.vue |
|
||||
| MON0014 | Rekapitulasi Gangguan Per Jenis Keluhan | Table_49.vue |
|
||||
| MON0015 | Rekapitulasi Lapor Ulang Keluhan | Table_50.vue |
|
||||
| MON0016 | Rekapitulasi Gangguan Belum Selesai | Table_51.vue |
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
||||
|
||||
## Type Support for `.vue` Imports in TS
|
||||
|
||||
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
|
||||
|
||||
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
|
||||
|
||||
1. Disable the built-in TypeScript Extension
|
||||
1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
|
||||
2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
|
||||
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
|
||||
|
||||
## Customize configuration
|
||||
|
||||
See [Vite Configuration Reference](https://vitejs.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Type-Check, Compile and Minify for Production
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Run Unit Tests with [Vitest](https://vitest.dev/)
|
||||
|
||||
```sh
|
||||
npm run test:unit
|
||||
```
|
||||
|
||||
### Lint with [ESLint](https://eslint.org/)
|
||||
|
||||
```sh
|
||||
npm run lint
|
||||
```
|
||||
### Keluhan > Rekapitulasi
|
||||
| CODE | MENU | FILE |
|
||||
| ------- | ------------------- | ------------ |
|
||||
| MON0010 | Jumlah Kali Keluhan | Table_45.vue |
|
@ -14,7 +14,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: apkt-eis
|
||||
image: defuj/apkt-eis:v1.0.1-dev
|
||||
image: defuj/apkt-eis:v0.0.10-vm
|
||||
ports:
|
||||
- containerPort: 80
|
||||
---
|
||||
|
0
index.html
Normal file → Executable file
0
nginx.conf
Normal file → Executable file
13325
package-lock.json
generated
Normal file → Executable file
39
package.json
Normal file → Executable file
@ -11,31 +11,37 @@
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
|
||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
||||
"format": "prettier --write src/",
|
||||
"prepare": "tw-patch install"
|
||||
"format": "prettier --write src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.8.8",
|
||||
"@apollo/client": "^3.8.10",
|
||||
"@apollo/link-context": "^2.0.0-beta.3",
|
||||
"@flavorly/vanilla-components": "^0.7.65",
|
||||
"@headlessui/tailwindcss": "^0.2.0",
|
||||
"@headlessui/vue": "^1.7.16",
|
||||
"@headlessui/vue": "^1.7.19",
|
||||
"@heroicons/vue": "^2.0.18",
|
||||
"@lottiefiles/lottie-player": "^2.0.2",
|
||||
"@lottiefiles/lottie-player": "^2.0.4",
|
||||
"@phosphor-icons/vue": "^2.1.6",
|
||||
"@types/qs": "^6.9.9",
|
||||
"@types/uuid": "^9.0.2",
|
||||
"@vue/apollo-option": "^4.0.0-beta.12",
|
||||
"devextreme": "23.1.5",
|
||||
"devextreme-vue": "23.1.5",
|
||||
"@types/qs": "^6.9.12",
|
||||
"@types/uuid": "^9.0.8",
|
||||
"@types/vue-select": "^3.16.8",
|
||||
"@vue/apollo-components": "^4.0.0",
|
||||
"@vue/apollo-composable": "^4.0.1",
|
||||
"@vue/apollo-option": "^4.0.0",
|
||||
"axios": "^1.6.7",
|
||||
"devextreme": "23.2.4",
|
||||
"devextreme-vue": "23.2.4",
|
||||
"dotenv": "^16.3.1",
|
||||
"encrypt-storage": "^2.12.16",
|
||||
"encrypt-storage": "^2.12.22",
|
||||
"exceljs": "^4.4.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"graphql": "^16.8.1",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"jspdf": "^2.5.1",
|
||||
"jspdf-autotable": "^3.8.2",
|
||||
"pinia": "^2.1.3",
|
||||
"qs": "^6.11.2",
|
||||
"uuid": "^9.0.0",
|
||||
"uuid": "^9.0.1",
|
||||
"vue": "^3.3.4",
|
||||
"vue-router": "^4.2.2",
|
||||
"vue-tailwind-datepicker": "^1.6.1"
|
||||
@ -44,7 +50,7 @@
|
||||
"@rushstack/eslint-patch": "^1.5.1",
|
||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"@tailwindcss/forms": "^0.5.6",
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@tailwindcss/typography": "^0.5.10",
|
||||
"@tsconfig/node18": "^2.0.1",
|
||||
"@types/file-saver": "^2.0.6",
|
||||
@ -60,15 +66,12 @@
|
||||
"eslint": "^8.39.0",
|
||||
"eslint-plugin-vue": "^9.11.0",
|
||||
"jsdom": "^22.1.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss": "^8.4.24",
|
||||
"prettier": "^3.0.3",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"tailwindcss-patch": "^2.2.2",
|
||||
"typescript": "~5.2.2",
|
||||
"unplugin-tailwindcss-mangle": "^2.2.2",
|
||||
"vite": "^4.3.9",
|
||||
"vitest": "^0.34.6",
|
||||
"vue-tsc": "^1.6.5"
|
||||
"vitest": "^1.3.1",
|
||||
"vue-tsc": "^2.0.5"
|
||||
}
|
||||
}
|
0
postcss.config.js
Normal file → Executable file
0
public/assets/css/loader.css
Normal file → Executable file
0
public/assets/images/favicon.ico
Normal file → Executable file
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
0
public/assets/images/pln.ico
Normal file → Executable file
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
0
src/App.vue
Normal file → Executable file
0
src/assets/css/base.css
Normal file → Executable file
46
src/assets/css/devextreme.custom.css
Normal file
@ -0,0 +1,46 @@
|
||||
.dx-datagrid-total-footer{
|
||||
background-color: #035b71 !important;
|
||||
}
|
||||
.dx-datagrid-total-footer .dx-row.dx-footer-row{
|
||||
background-color: #035b71 !important;
|
||||
}
|
||||
.dx-datagrid-total-footer > td{
|
||||
background-color: #035b71 !important;
|
||||
}
|
||||
.dx-row.dx-datagrid-group-footer > td{
|
||||
background-color: #e6eff1 !important;
|
||||
}
|
||||
.dx-datagrid-rowsview .dx-row.dx-group-row {
|
||||
background-color: #F7F7F7 !important;
|
||||
}
|
||||
.dx-datagrid-group-footer{
|
||||
background-color: #e6eff1 !important;
|
||||
}
|
||||
.dx-pager .dx-page-sizes .dx-selection, .dx-pager .dx-pages .dx-selection{
|
||||
background-color: #035b71 !important;
|
||||
}
|
||||
.dx-datagrid-headers .dx-datagrid-table .dx-row > td{
|
||||
font-size: 12px !important;
|
||||
}
|
||||
.dx-datagrid .dx-row > td{
|
||||
font-size: 12px !important;
|
||||
}
|
||||
.dx-toolbar .dx-toolbar-items-container{
|
||||
height: 56px !important;
|
||||
}
|
||||
.dx-texteditor-input{
|
||||
border: 1px solid #d1d5db !important;
|
||||
border-radius: 8px !important;
|
||||
}
|
||||
.dx-texteditor.dx-editor-filled::after{
|
||||
border: none !important;
|
||||
}
|
||||
.dx-texteditor.dx-state-active::before, .dx-texteditor.dx-state-focused::before{
|
||||
border: none !important;
|
||||
}
|
||||
.dx-button-has-icon .dx-icon{
|
||||
font-size: 24px !important;
|
||||
}
|
||||
.dx-list-item-icon{
|
||||
font-size: 24px !important;
|
||||
}
|
23
src/assets/css/main.css
Normal file → Executable file
@ -2,25 +2,4 @@
|
||||
@import 'devextreme/dist/css/dx.material.blue.light.compact.css';
|
||||
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;700&display=swap');
|
||||
@import './style.css';
|
||||
|
||||
.dx-datagrid-total-footer{
|
||||
background-color: #035b71 !important;
|
||||
}
|
||||
.dx-datagrid-total-footer .dx-row.dx-footer-row{
|
||||
background-color: #035b71 !important;
|
||||
}
|
||||
.dx-datagrid-total-footer > td{
|
||||
background-color: #035b71 !important;
|
||||
}
|
||||
.dx-row.dx-datagrid-group-footer > td{
|
||||
background-color: #e6eff1 !important;
|
||||
}
|
||||
.dx-datagrid-rowsview .dx-row.dx-group-row {
|
||||
background-color: #F7F7F7 !important;
|
||||
}
|
||||
.dx-datagrid-group-footer{
|
||||
background-color: #e6eff1 !important;
|
||||
}
|
||||
.dx-pager .dx-page-sizes .dx-selection, .dx-pager .dx-pages .dx-selection{
|
||||
background-color: #035b71 !important;
|
||||
}
|
||||
@import './devextreme.custom.css';
|
3003
src/assets/css/style.css
Normal file → Executable file
18
src/assets/css/tailwind.css
Normal file → Executable file
@ -26,8 +26,11 @@
|
||||
@apply flex-shrink-0 block px-4 py-2 border-b bg-primary-500 border-gray-50;
|
||||
}
|
||||
/* Aside */
|
||||
.aside-text{
|
||||
@apply text-xs;
|
||||
}
|
||||
.aside-single-item {
|
||||
@apply w-full flex items-center pl-2 pr-4 py-2 text-xs rounded-xl;
|
||||
@apply aside-text w-full flex items-center pl-2 pr-4 py-2 rounded-xl;
|
||||
}
|
||||
.aside-single-item-active {
|
||||
@apply aside-single-item bg-primary-500 text-white font-bold;
|
||||
@ -47,4 +50,17 @@
|
||||
.custom-table-column {
|
||||
@apply !align-middle text-sm font-medium text-primary-800;
|
||||
}
|
||||
.filter-input-label {
|
||||
@apply block mb-2 text-xs font-semibold text-gray-800 sm:mb-0;
|
||||
}
|
||||
.rich-select-trigger{
|
||||
@apply bg-gray-200 border-none 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 relative flex items-center justify-between w-full focus:z-10 cursor-pointer text-sm transition duration-100 ease-in-out disabled:opacity-50 disabled:cursor-not-allowed px-4 py-2.5;
|
||||
}
|
||||
.rich-select-search-input{
|
||||
@apply inline-block 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 w-full text-sm px-4 py-2.5 text-gray-700 placeholder-gray-500/60 border-0 rounded-lg bg-gray-200;
|
||||
}
|
||||
.rich-select-selected-highlighted-option{
|
||||
@apply font-semibold bg-teal-600 focus:outline-none text-white;
|
||||
}
|
||||
|
||||
}
|
||||
|
0
src/assets/icons/dot-outline.svg
Normal file → Executable file
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
0
src/assets/icons/gauge.svg
Normal file → Executable file
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
0
src/assets/icons/lightning-slash.svg
Normal file → Executable file
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
0
src/assets/icons/monitor.svg
Normal file → Executable file
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
0
src/assets/icons/plugs.svg
Normal file → Executable file
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
0
src/assets/icons/smiley-sad.svg
Normal file → Executable file
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
0
src/assets/icons/swap.svg
Normal file → Executable file
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
0
src/assets/images/hero.png
Normal file → Executable file
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
0
src/assets/images/pln-with-text.png
Normal file → Executable file
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
0
src/assets/images/pln.png
Normal file → Executable file
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
9
src/components/Button.vue → src/components/Buttons/Button.vue
Normal file → Executable file
@ -6,10 +6,6 @@ const props = defineProps({
|
||||
type: String as () => 'button' | 'submit' | 'reset',
|
||||
default: 'button'
|
||||
},
|
||||
onClick: {
|
||||
type: Function as unknown as () => (payload: MouseEvent) => void,
|
||||
default: () => {}
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
default: ''
|
||||
@ -47,12 +43,15 @@ const buttonStyle = computed(() => {
|
||||
return 'bg-none text-primary-500 border border-transparent hover:border-primary-500 rounded-lg disabled:border-primary-300 disabled:text-primary-300'
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['on:click'])
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button
|
||||
:type="type"
|
||||
@click="onClick"
|
||||
@click="emit('on:click')"
|
||||
:disabled="isLoading ? true : disabled"
|
||||
:class="['px-3 py-2 text-sm font-semibold', buttonStyle, className]"
|
||||
>
|
0
src/components/Buttons/ButtonDropdown.vue
Normal file → Executable file
1
src/components/Buttons/ButtonPrimary.vue
Normal file → Executable file
@ -1,4 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import * as LottiePlayer from "@lottiefiles/lottie-player";
|
||||
defineProps({
|
||||
type: {
|
||||
type: String as () => "button" | "submit" | "reset",
|
||||
|
32
src/components/CommandPalettes.vue
Normal file → Executable file
@ -80,48 +80,50 @@
|
||||
<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']">
|
||||
<li @click="command.openMenu(menu)" class="group">
|
||||
<div class="flex flex-row items-center justify-between px-3 py-2 rounded-md cursor-pointer select-none lex 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"
|
||||
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
|
||||
:class="['w-8 h-8 fill-gray-600 group-hover:fill-white flex']" />
|
||||
<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']" />
|
||||
:class="['w-8 h-8 fill-gray-600 group-hover:fill-white flex']" />
|
||||
<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']" />
|
||||
:class="['w-8 h-8 fill-gray-600 group-hover:fill-white flex']" />
|
||||
<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']" />
|
||||
:class="['w-8 h-8 fill-gray-600 group-hover:fill-white flex']" />
|
||||
<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']" />
|
||||
:class="['w-8 h-8 fill-gray-600 group-hover:fill-white flex']" />
|
||||
<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']" />
|
||||
:class="['w-8 h-8 fill-gray-600 group-hover:fill-white flex']" />
|
||||
<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']" />
|
||||
:class="['w-8 h-8 fill-gray-600 group-hover:fill-white flex']" />
|
||||
<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']" />
|
||||
:class="['w-8 h-8 fill-gray-600 group-hover:fill-white flex']" />
|
||||
<component v-else :is="navigationIcon[8]" alt="icon"
|
||||
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
|
||||
:class="['w-8 h-8 fill-gray-600 group-hover:fill-white flex']" />
|
||||
|
||||
<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']">
|
||||
class="w-full text-sm font-medium text-gray-800 text-start group-hover:text-white line-clamp-1">
|
||||
{{ menu.name }}
|
||||
</span>
|
||||
<span
|
||||
:class="[active ? 'text-white' : 'text-gray-500', 'text-xs line-clamp-1']">
|
||||
class="w-full text-xs text-gray-500 text-start group-hover:text-white line-clamp-1">
|
||||
{{ menu.path.replace('/home/', '') }}
|
||||
</span>
|
||||
</div>
|
||||
<span v-if="active" class="flex-none ml-3 text-gray-200">
|
||||
<span class="hidden ml-3 text-sm text-gray-500 group-hover:block group-hover:text-white">
|
||||
Buka
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
</li>
|
||||
</ComboboxOption>
|
||||
@ -146,7 +148,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import { MagnifyingGlassIcon } from '@heroicons/vue/20/solid'
|
||||
import {
|
||||
Combobox,
|
||||
|
51
src/components/DatePicker.vue
Normal file → Executable file
@ -1,34 +1,47 @@
|
||||
<script setup lang="ts">
|
||||
import { PhCalendarBlank } from '@phosphor-icons/vue';
|
||||
import { ref } from 'vue'
|
||||
import { PhCalendarBlank } from '@phosphor-icons/vue'
|
||||
import { ref, watch } from 'vue'
|
||||
import VueTailwindDatepicker from 'vue-tailwind-datepicker'
|
||||
|
||||
|
||||
const dateValue = ref('')
|
||||
const formatter = ref({
|
||||
date: 'DD MMM YYYY',
|
||||
month: 'MMM'
|
||||
date: 'DD-MM-YYYY',
|
||||
month: 'MMMM'
|
||||
})
|
||||
const emit = defineEmits(['update:dateValue'])
|
||||
|
||||
const customShortcuts = () => {
|
||||
return [
|
||||
{
|
||||
label: 'Last 15 Days',
|
||||
atClick: () => {
|
||||
const date = new Date()
|
||||
return [new Date(date.setDate(date.getDate() - 15)), new Date()]
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Last Years',
|
||||
atClick: () => {
|
||||
const date = new Date()
|
||||
return [new Date(date.setFullYear(date.getFullYear() - 1)), new Date()]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
watch(dateValue, (newValue) => {
|
||||
emit('update:dateValue', newValue)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex">
|
||||
<vue-tailwind-datepicker
|
||||
v-model="dateValue"
|
||||
:formatter="formatter"
|
||||
separator=" s/d "
|
||||
:shortcuts="false"
|
||||
:auto-apply="false"
|
||||
as-single
|
||||
use-range
|
||||
v-slot="{ value, placeholder }"
|
||||
>
|
||||
<vue-tailwind-datepicker v-model="dateValue" :formatter="formatter" separator=" s/d " :shortcuts="customShortcuts"
|
||||
:auto-apply="true" as-single use-range v-slot="{ value, placeholder }">
|
||||
<div class="flex">
|
||||
<div class="flex-1">
|
||||
<button
|
||||
type="button"
|
||||
class="w-full flex items-center justify-between 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"
|
||||
>
|
||||
<button type="button"
|
||||
class="flex items-center justify-between w-full px-4 py-2 text-sm leading-6 text-gray-900 bg-gray-200 border-0 border-transparent rounded-lg placeholder:text-gray-400 outline-0 focus:outline-0 focus:border-0 focus:ring-0">
|
||||
<span class="text-gray-900">
|
||||
{{ value || placeholder }}
|
||||
</span>
|
||||
|
0
src/components/Dialogs/ActionDialog.vue
Normal file → Executable file
13
src/components/Dialogs/DetailDialog.vue
Normal file → Executable file
@ -5,7 +5,7 @@ import {
|
||||
DialogTitle,
|
||||
TransitionChild,
|
||||
TransitionRoot
|
||||
} from '@headlessui/vue'
|
||||
} from '@headlessui/vue';
|
||||
defineProps({
|
||||
open: {
|
||||
type: Boolean,
|
||||
@ -15,6 +15,10 @@ defineProps({
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
fullWidth: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
const emit = defineEmits(['onClose'])
|
||||
const handleOnClose = () => {
|
||||
@ -38,12 +42,13 @@ const handleOnClose = () => {
|
||||
leave-from="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave-to="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95">
|
||||
<DialogPanel
|
||||
:class="['sm:max-w-lg relative overflow-hidden text-left transition-all transform bg-gray-50 rounded-2xl sm:my-8 sm:w-full']">
|
||||
:class="[fullWidth ? 'sm:max-w-full' : 'sm:max-w-lg sm:my-8', 'relative overflow-hidden text-left transition-all transform bg-gray-50 rounded-2xl sm:w-full']">
|
||||
<!-- Body Section -->
|
||||
<div class="px-4 py-4 bg-gray-50">
|
||||
<div class="flex flex-col items-start">
|
||||
<div class="items-start">
|
||||
<div class="flex items-start justify-between w-full">
|
||||
<DialogTitle as="h3" class="flex-1 text-2xl font-semibold leading-6 text-gray-900">
|
||||
<DialogTitle as="h3"
|
||||
class="flex-1 text-2xl font-semibold leading-6 text-gray-900">
|
||||
{{ title }}
|
||||
</DialogTitle>
|
||||
<div class="flex items-center ml-3 h-7">
|
||||
|
34
src/components/Form/Filters.vue
Normal file → Executable file
@ -1,13 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
// components
|
||||
import Button from '@/components/Button.vue';
|
||||
|
||||
// icons
|
||||
import {
|
||||
PhArrowsCounterClockwise,
|
||||
PhFileText,
|
||||
PhMagnifyingGlass
|
||||
} from '@phosphor-icons/vue';
|
||||
import Button from '@/components/Buttons/Button.vue';
|
||||
import { PhArrowsCounterClockwise, PhFileText, PhMagnifyingGlass } from '@phosphor-icons/vue';
|
||||
|
||||
defineProps({
|
||||
reportButton: {
|
||||
@ -15,30 +8,31 @@
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['runSearch', 'resetForm', 'runReport'])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="filters rounded-2xl">
|
||||
|
||||
<form class="filter-body bg-gray-50 mx-auto space-y-3 p-4 rounded-t-2xl">
|
||||
<form class="p-4 mx-auto space-y-3 filter-body bg-gray-50 rounded-t-2xl">
|
||||
<slot></slot>
|
||||
</form>
|
||||
|
||||
<div class="filter-footer rounded-b-2xl px-4 py-3 bg-primary-50 flex justify-end">
|
||||
<div class="filter-buttons flex gap-3 flex-wrap">
|
||||
<Button label="Ulangi" style-type="outline" class-name="bg-white">
|
||||
<PhArrowsCounterClockwise size="18" class="ml-1" weight="regular" />
|
||||
<div class="flex justify-end px-4 py-3 filter-footer rounded-b-2xl bg-primary-50">
|
||||
<div class="flex flex-wrap gap-3 filter-buttons">
|
||||
<Button @on:click="() => emit('resetForm')" label="Ulangi" style-type="outline" class-name="bg-white !text-xs">
|
||||
<PhArrowsCounterClockwise size="16" class="ml-1" weight="regular" />
|
||||
</Button>
|
||||
|
||||
<Button v-if="reportButton" label="Lihat Laporan" style-type="outline" class-name="bg-white">
|
||||
<PhFileText size="18" class="ml-1" weight="regular" />
|
||||
<Button v-if="reportButton" label="Lihat Laporan" style-type="outline" class-name="bg-white !text-xs"
|
||||
@on:click="() => emit('runReport')">
|
||||
<PhFileText size="16" class="ml-1" weight="regular" />
|
||||
</Button>
|
||||
|
||||
<Button label="Cari Data">
|
||||
<PhMagnifyingGlass size="18" class="ml-1" weight="regular" />
|
||||
<Button @on:click="() => emit('runSearch')" label="Cari Data" class-name="!text-xs">
|
||||
<PhMagnifyingGlass size="16" class="ml-1" weight="regular" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
89
src/components/Form/FiltersType/Type1.vue
Normal file → Executable file
@ -1,32 +1,87 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import Select from '@/components/Select.vue';
|
||||
import DatePicker from '@/components/DatePicker.vue';
|
||||
import {
|
||||
selectedUid,
|
||||
selectedUp3Posko,
|
||||
selectedPosko,
|
||||
itemsUid,
|
||||
itemsUp3,
|
||||
itemsPosko,
|
||||
fetchUid
|
||||
} from './reference';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah'
|
||||
const up3placeholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan'
|
||||
const poskoPlaceholder = 'Semua Posko'
|
||||
const up3 = ref({ id: 0, name: up3placeholder })
|
||||
const uid = ref({ id: 0, name: uidPlaceholder })
|
||||
const posko = ref({ id: 0, name: poskoPlaceholder })
|
||||
const emit = defineEmits(['update:filters'])
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: up3.value,
|
||||
posko: posko.value,
|
||||
periode: ''
|
||||
})
|
||||
|
||||
watch(data.value, (value) => {
|
||||
emit('update:filters', value)
|
||||
})
|
||||
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value
|
||||
selectedUid(value)
|
||||
up3.value = { id: 0, name: up3placeholder }
|
||||
data.value.uid = value
|
||||
}
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
up3.value = value
|
||||
selectedUp3Posko(value)
|
||||
console.log(itemsPosko)
|
||||
posko.value = { id: 0, name: poskoPlaceholder }
|
||||
data.value.up3 = value
|
||||
}
|
||||
|
||||
const setPosko = (value: any) => {
|
||||
posko.value = value
|
||||
selectedPosko(value)
|
||||
data.value.posko = value
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchUid()
|
||||
emit('update:filters', data.value)
|
||||
})
|
||||
</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>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Induk Distribusi/Wilayah"/>
|
||||
<Select @update:selected="setUid($event)" :data="itemsUid" :placeholder="uidPlaceholder" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :selected="up3" :placeholder="up3placeholder" />
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Posko:</label>
|
||||
|
||||
<Select placeholder="Semua Posko" />
|
||||
<Select @update:selected="setPosko($event)" :data="itemsPosko" :selected="posko"
|
||||
:placeholder="poskoPlaceholder" />
|
||||
</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 class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
<DatePicker @update:date-value="(value) => (data.periode = value)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
92
src/components/Form/FiltersType/Type10.vue
Normal file → Executable file
@ -1,44 +1,94 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import {
|
||||
selectedUid,
|
||||
selectedUp3Ulp,
|
||||
selectedUlp,
|
||||
fetchUid,
|
||||
itemsUid,
|
||||
itemsUp3,
|
||||
itemsUlp
|
||||
} from './reference'
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import InputNumber from '@/components/Form/InputNumber.vue'
|
||||
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah'
|
||||
const up3Placeholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan'
|
||||
const ulpPlaceholder = 'Semua Unit Layanan Pelanggan'
|
||||
const up3 = ref({ id: 0, name: up3Placeholder })
|
||||
const uid = ref({ id: 0, name: uidPlaceholder })
|
||||
const ulp = ref({ id: 0, name: ulpPlaceholder })
|
||||
const emit = defineEmits(['update:filters'])
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: up3.value,
|
||||
ulp: ulp.value,
|
||||
periode: '',
|
||||
minJmlLapor: 1,
|
||||
maxJmlLapor: 1
|
||||
})
|
||||
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value
|
||||
selectedUid(value)
|
||||
up3.value = { id: 0, name: up3Placeholder }
|
||||
data.value.uid = value
|
||||
}
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
up3.value = value
|
||||
selectedUp3Ulp(value)
|
||||
ulp.value = { id: 0, name: ulpPlaceholder }
|
||||
data.value.up3 = value
|
||||
}
|
||||
|
||||
const setUlp = (value: any) => {
|
||||
ulp.value = value
|
||||
selectedUlp(value)
|
||||
data.value.ulp = value
|
||||
}
|
||||
onMounted(() => {
|
||||
emit('update:filters', data.value)
|
||||
fetchUid()
|
||||
})
|
||||
</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>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Induk Distribusi/Wilayah"/>
|
||||
<Select @update:selected="setUid($event)" :data="itemsUid" :placeholder="uidPlaceholder" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :selected="up3" :placeholder="up3Placeholder" />
|
||||
</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 Layanan Pelanggan:</label
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Layanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Layanan Pelanggan" />
|
||||
<Select @update:selected="setUlp($event)" :data="itemsUlp" :selected="ulp" :placeholder="ulpPlaceholder" />
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
<DatePicker @update:date-value="(value) => (data.periode = value)" />
|
||||
</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">Lapor Ulang:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Lapor Ulang:</label>
|
||||
|
||||
<div class="grid grid-flow-col auto-cols-auto gap-x-1.5">
|
||||
<Select placeholder="1" />
|
||||
<div class="flex flex-1 justify-between gap-x-1.5">
|
||||
<InputNumber @update:time-value="(value) => (data.minJmlLapor = value)" class="flex flex-1" />
|
||||
<small class="flex items-center">s/d</small>
|
||||
<Select placeholder="2" />
|
||||
<InputNumber @update:time-value="(value) => (data.maxJmlLapor = value)" class="flex flex-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
190
src/components/Form/FiltersType/Type11.vue
Normal file → Executable file
@ -1,47 +1,191 @@
|
||||
<script setup lang="ts">
|
||||
interface SlaOption {
|
||||
id: number
|
||||
name: string
|
||||
min: string
|
||||
max: string
|
||||
}
|
||||
|
||||
import { onMounted, ref } from 'vue'
|
||||
import {
|
||||
selectedUid,
|
||||
selectedUp3Ulp,
|
||||
selectedUlp,
|
||||
fetchUid,
|
||||
itemsUid,
|
||||
itemsUp3,
|
||||
itemsUlp
|
||||
} from './reference'
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import InputWithSuffix from '@/components/Form/InputWithSuffix.vue'
|
||||
|
||||
const props = defineProps({
|
||||
slaOptions: {
|
||||
type: Array as () => SlaOption[],
|
||||
default: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Dibawah / Sesuai SLA (<= 45 menit)',
|
||||
min: '1',
|
||||
max: '45'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'Melebihi SLA (> 45 menit)',
|
||||
min: '46',
|
||||
max: `${99999 * 60 * 24}`
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const sla = props.slaOptions.map((item: any) => {
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name
|
||||
}
|
||||
})
|
||||
|
||||
const totalMin = ref('1 Menit')
|
||||
const totalMax = ref('5 Menit')
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah'
|
||||
const up3Placeholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan'
|
||||
const ulpPlaceholder = 'Semua Unit Layanan Pelanggan'
|
||||
const up3 = ref({ id: 0, name: up3Placeholder })
|
||||
const uid = ref({ id: 0, name: uidPlaceholder })
|
||||
const ulp = ref({ id: 0, name: ulpPlaceholder })
|
||||
const emit = defineEmits(['update:filters'])
|
||||
const isHidden = ref(false)
|
||||
|
||||
const setDataMin = (value: any) => (totalMin.value = value)
|
||||
const getDataMin = () => totalMin.value
|
||||
const setDataMax = (value: any) => (totalMax.value = value)
|
||||
const getDataMax = () => totalMax.value
|
||||
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: up3.value,
|
||||
ulp: ulp.value,
|
||||
periode: '',
|
||||
minTime: getDataMin().split(' ')[0],
|
||||
maxTime: getDataMax().split(' ')[0]
|
||||
})
|
||||
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value
|
||||
selectedUid(value)
|
||||
up3.value = { id: 0, name: up3Placeholder }
|
||||
data.value.uid = value
|
||||
}
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
up3.value = value
|
||||
selectedUp3Ulp(value)
|
||||
ulp.value = { id: 0, name: ulpPlaceholder }
|
||||
data.value.up3 = value
|
||||
}
|
||||
|
||||
const setUlp = (value: any) => {
|
||||
ulp.value = value
|
||||
selectedUlp(value)
|
||||
data.value.ulp = value
|
||||
}
|
||||
|
||||
const setMin = (value: any) => {
|
||||
console.log(value)
|
||||
data.value.minTime = value
|
||||
setDataMin(value)
|
||||
}
|
||||
const setMax = (value: any) => {
|
||||
data.value.maxTime = value
|
||||
setDataMax(value)
|
||||
}
|
||||
|
||||
const triggerInput = ref(false)
|
||||
const changeDuration = (value: any) => {
|
||||
if (value.id === 0) {
|
||||
setMin('1')
|
||||
setMax('5')
|
||||
|
||||
triggerInput.value = false
|
||||
isHidden.value = false
|
||||
} else if (value.id === 1) {
|
||||
setMin(props.slaOptions[0].min)
|
||||
setMax(props.slaOptions[0].max)
|
||||
|
||||
triggerInput.value = true
|
||||
isHidden.value = true
|
||||
} else {
|
||||
setMin(props.slaOptions[1].min)
|
||||
setMax(props.slaOptions[1].max)
|
||||
|
||||
triggerInput.value = true
|
||||
isHidden.value = true
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emit('update:filters', data.value)
|
||||
fetchUid()
|
||||
})
|
||||
</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>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Induk Distribusi/Wilayah"/>
|
||||
<Select @update:selected="setUid($event)" :data="itemsUid" :placeholder="uidPlaceholder" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
<Select
|
||||
@update:selected="setUp3($event)"
|
||||
:data="itemsUp3"
|
||||
:selected="up3"
|
||||
:placeholder="up3Placeholder"
|
||||
/>
|
||||
</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 Layanan Pelanggan:</label
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Layanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Layanan Pelanggan" />
|
||||
<Select
|
||||
@update:selected="setUlp($event)"
|
||||
:data="itemsUlp"
|
||||
:placeholder="ulpPlaceholder"
|
||||
:selected="ulp"
|
||||
/>
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
<DatePicker @update:date-value="(value) => (data.periode = value)" />
|
||||
</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">Durasi:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Durasi:</label>
|
||||
|
||||
<div class="flex flex-col gap-y-1">
|
||||
<Select placeholder="Durasi Menit" />
|
||||
<div class="flex flex-col gap-y-2">
|
||||
<Select @update:selected="changeDuration($event)" :data="sla" placeholder="Durasi Menit" />
|
||||
|
||||
<div class="grid grid-flow-col auto-cols-auto gap-x-1.5">
|
||||
<Select placeholder="1" />
|
||||
<div class="flex flex-1 justify-between gap-x-1.5" :class="[isHidden ? 'hidden' : '']">
|
||||
<InputWithSuffix
|
||||
:value="`${data.minTime} Menit`"
|
||||
@update:text="setMin($event)"
|
||||
class="flex flex-1"
|
||||
/>
|
||||
<small class="flex items-center">s/d</small>
|
||||
<Select placeholder="2" />
|
||||
<InputWithSuffix
|
||||
:value="`${data.maxTime} Menit`"
|
||||
@update:text="setMax($event)"
|
||||
class="flex flex-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
123
src/components/Form/FiltersType/Type12.vue
Normal file → Executable file
@ -1,49 +1,124 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import Select from '@/components/Select.vue';
|
||||
import DatePicker from '@/components/DatePicker.vue';
|
||||
import InputWithSuffix from '../InputWithSuffix.vue';
|
||||
import { selectedUid, selectedUp3Ulp, selectedUlp, fetchUid, itemsUid, itemsUp3, itemsUlp } from './reference';
|
||||
import { onMounted, ref } from 'vue';
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah';
|
||||
const up3Placeholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan';
|
||||
const ulpPlaceholder = 'Semua Unit Layanan Pelanggan';
|
||||
const uppp = ref({ id: 0, name: up3Placeholder });
|
||||
const uid = ref({ id: 0, name: uidPlaceholder });
|
||||
const ulp = ref({ id: 0, name: ulpPlaceholder });
|
||||
const emit = defineEmits(['update:filters'])
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: uppp.value,
|
||||
ulp: ulp.value,
|
||||
periode: '',
|
||||
minDurasiResponseTime: 1,
|
||||
maxDurasiResponseTime: 1
|
||||
})
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value;
|
||||
selectedUid(value);
|
||||
uppp.value = { id: 0, name: up3Placeholder };
|
||||
data.value.uid = value;
|
||||
};
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
uppp.value = value;
|
||||
selectedUp3Ulp(value);
|
||||
ulp.value = { id: 0, name: ulpPlaceholder };
|
||||
data.value.up3 = value;
|
||||
};
|
||||
|
||||
const setUlp = (value: any) => {
|
||||
ulp.value = value;
|
||||
selectedUlp(value);
|
||||
data.value.ulp = value;
|
||||
};
|
||||
const triggerInput = ref(false)
|
||||
const sla = [
|
||||
{
|
||||
id: 0,
|
||||
name: 'Durasi Menit'
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
name: 'Dibawah / Sesuai SLA (<= 45 menit)'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'Melebihi SLA (> 45 menit)'
|
||||
}
|
||||
];
|
||||
const changeDuration = (value: any) => {
|
||||
if (value.id === 0) {
|
||||
console.log('Durasi Menit')
|
||||
data.value.minDurasiResponseTime = 0
|
||||
data.value.maxDurasiResponseTime = 5
|
||||
triggerInput.value = false
|
||||
} else if (value.id === 1) {
|
||||
data.value.minDurasiResponseTime = 0
|
||||
data.value.maxDurasiResponseTime = 45
|
||||
console.log('Dibawah / Sesuai SLA (<= 45 menit)')
|
||||
triggerInput.value = true
|
||||
} else {
|
||||
data.value.minDurasiResponseTime = 46
|
||||
data.value.maxDurasiResponseTime = 99999 * 60 * 24
|
||||
triggerInput.value = true
|
||||
console.log('Melebihi SLA (> 45 menit)')
|
||||
}
|
||||
|
||||
}
|
||||
onMounted(() => {
|
||||
emit('update:filters', data.value)
|
||||
fetchUid()
|
||||
})
|
||||
</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>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Induk Distribusi/Wilayah"/>
|
||||
<Select @update:selected="setUid($event)" :data="itemsUid" :placeholder="uidPlaceholder" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :placeholder="up3Placeholder" />
|
||||
</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 Layanan Pelanggan:</label
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Layanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Layanan Pelanggan" />
|
||||
<Select @update:selected="setUlp($event)" :data="itemsUlp" :placeholder="ulpPlaceholder" />
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
<DatePicker @update:date-value="(value) => data.periode = value" />
|
||||
</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">Durasi:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Durasi:</label>
|
||||
|
||||
<div class="flex flex-col gap-y-1">
|
||||
<Select placeholder="Durasi Menit" />
|
||||
<Select @update:selected="changeDuration($event)" :data="sla" placeholder="Durasi Menit" />
|
||||
|
||||
<div class="grid grid-flow-col auto-cols-auto gap-x-1.5">
|
||||
<InputWithSuffix />
|
||||
<div class="flex flex-1 justify-between gap-x-1.5">
|
||||
<InputWithSuffix @update:minute-value="(value: any) => data.minDurasiResponseTime = value" @value="data.minDurasiResponseTime" :disabled=triggerInput
|
||||
class="flex flex-1" />
|
||||
<small class="flex items-center">s/d</small>
|
||||
<InputWithSuffix />
|
||||
<InputWithSuffix @update:minute-value="(value: any) => data.maxDurasiResponseTime = value" @value="data.maxDurasiResponseTime"
|
||||
:disabled="triggerInput" class="flex flex-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
94
src/components/Form/FiltersType/Type13.vue
Normal file → Executable file
@ -2,40 +2,92 @@
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import InlineRadioGroup from '@/components/Form/InlineRadioGroup.vue'
|
||||
import {
|
||||
selectedUid,
|
||||
selectedUp3Ulp,
|
||||
selectedUlp,
|
||||
fetchUid,
|
||||
itemsUid,
|
||||
itemsUp3,
|
||||
itemsUlp
|
||||
} from './reference'
|
||||
import { onMounted, ref } from 'vue'
|
||||
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah'
|
||||
const up3Placeholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan'
|
||||
const ulpPlaceholder = 'Semua Unit Layanan Pelanggan'
|
||||
const up3 = ref({ id: 0, name: up3Placeholder })
|
||||
const uid = ref({ id: 0, name: uidPlaceholder })
|
||||
const ulp = ref({ id: 0, name: ulpPlaceholder })
|
||||
const emit = defineEmits(['update:filters'])
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: up3.value,
|
||||
ulp: ulp.value,
|
||||
periode: '',
|
||||
groupBy: false
|
||||
})
|
||||
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value
|
||||
selectedUid(value)
|
||||
up3.value = { id: 0, name: up3Placeholder }
|
||||
data.value.uid = value
|
||||
}
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
up3.value = value
|
||||
selectedUp3Ulp(value)
|
||||
ulp.value = { id: 0, name: ulpPlaceholder }
|
||||
data.value.up3 = value
|
||||
}
|
||||
|
||||
const setUlp = (value: any) => {
|
||||
ulp.value = value
|
||||
selectedUlp(value)
|
||||
data.value.ulp = value
|
||||
|
||||
console.log('data.value', data.value)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emit('update:filters', data.value)
|
||||
fetchUid()
|
||||
})
|
||||
</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>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Induk Distribusi/Wilayah"/>
|
||||
<Select @update:selected="setUid($event)" :data="itemsUid" :placeholder="uidPlaceholder" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :selected="up3" :placeholder="up3Placeholder" />
|
||||
</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 Layanan Pelanggan:</label
|
||||
>
|
||||
|
||||
<Select placeholder="Semua Unit Layanan Pelanggan" />
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Layanan Pelanggan:</label>
|
||||
<Select @update:selected="setUlp($event)" :data="itemsUlp" :selected="ulp" :placeholder="ulpPlaceholder" />
|
||||
</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 class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
<DatePicker @update:date-value="(value) => (data.periode = value)" />
|
||||
</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">Group By Kode Unit Distribusi:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Group By Kode Unit Distribusi:</label>
|
||||
|
||||
<InlineRadioGroup :radio-items="[{id: 1, title: 'Tidak', checked: true}, {id: 2, title: 'Ya, Grupkan'}]" />
|
||||
<InlineRadioGroup @update:group-value="(value) => (data.groupBy = value.id === 2)" :radio-items="[
|
||||
{ id: 1, title: 'Tidak' },
|
||||
{ id: 2, title: 'Ya, Grupkan' }
|
||||
]" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
76
src/components/Form/FiltersType/Type14.vue
Normal file → Executable file
@ -1,34 +1,72 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import Select from '@/components/Select.vue';
|
||||
import DatePicker from '@/components/DatePicker.vue';
|
||||
import { selectedUid, selectedUp3Posko, selectedPosko, fetchUid, itemsUid, itemsUp3, itemsPosko } from './reference';
|
||||
import { onMounted, ref } from 'vue';
|
||||
const uidPlaceholder = 'Semua Distribusi/Wilayah';
|
||||
const up3Placeholder = 'Semua Area';
|
||||
const poskoPlaceholder = 'Semua Unit Layanan Pelanggan';
|
||||
const up3 = ref({ id: 0, name: up3Placeholder });
|
||||
const uid = ref({ id: 0, name: uidPlaceholder });
|
||||
const posko = ref({ id: 0, name: poskoPlaceholder });
|
||||
const emit = defineEmits(['update:filters'])
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: up3.value,
|
||||
posko: posko.value,
|
||||
periode: '',
|
||||
})
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value;
|
||||
selectedUid(value);
|
||||
up3.value = { id: 0, name: up3Placeholder };
|
||||
data.value.uid = value;
|
||||
};
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
up3.value = value;
|
||||
selectedUp3Posko(value);
|
||||
posko.value = { id: 0, name: poskoPlaceholder };
|
||||
data.value.up3 = value;
|
||||
};
|
||||
|
||||
const setPosko = (value: any) => {
|
||||
posko.value = value;
|
||||
selectedPosko(value);
|
||||
data.value.posko = value;
|
||||
};
|
||||
onMounted(() => {
|
||||
emit('update:filters', data.value)
|
||||
fetchUid()
|
||||
})
|
||||
</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">Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Distribusi/Wilayah"/>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Distribusi/Wilayah:</label>
|
||||
<Select :data="itemsUid" @update:selected="setUid($event)" :placeholder="uidPlaceholder" :selected="uid" />
|
||||
</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"
|
||||
>Area:</label
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Area:</label>
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :selected="up3" :placeholder="up3Placeholder" />
|
||||
|
||||
<Select placeholder="Semua Area" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Posko:</label>
|
||||
<Select @update:selected="setPosko($event)" :data="itemsPosko" :selected="posko"
|
||||
:placeholder="poskoPlaceholder" />
|
||||
|
||||
<Select 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">Periode Tanggal:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
<DatePicker @update:date-value="(value) => data.periode = value" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
69
src/components/Form/FiltersType/Type15.vue
Normal file → Executable file
@ -2,24 +2,75 @@
|
||||
import InputWithFilter from '../InputWithFilter.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import InlineRadioGroup from '@/components/Form/InlineRadioGroup.vue'
|
||||
import { onMounted, ref } from 'vue'
|
||||
const type = ref('Gangguan')
|
||||
const keyword = ref('')
|
||||
const reportType = [
|
||||
{ id: 1, title: 'Nomor Laporan' },
|
||||
{ id: 2, title: 'Nama Pelapor' },
|
||||
{ id: 3, title: 'No Telepon' },
|
||||
{ id: 4, title: 'Alamat' },
|
||||
{ id: 5, title: 'Pembuat' }
|
||||
]
|
||||
const searchBy = ref<any>(reportType[0].title)
|
||||
const emit = defineEmits(['update:filters'])
|
||||
|
||||
const data = ref({
|
||||
type: type.value,
|
||||
keyword: keyword.value,
|
||||
searchBy: searchBy.value,
|
||||
periode: ''
|
||||
})
|
||||
|
||||
const changeKeyword = (value: string) => {
|
||||
keyword.value = value
|
||||
data.value.keyword = value
|
||||
}
|
||||
|
||||
const changeReportTypeSelected = (id: any) => {
|
||||
searchBy.value = reportType.find((item) => item.id == id)?.title
|
||||
data.value.searchBy = searchBy.value
|
||||
}
|
||||
|
||||
const setPengaduan = (value: any) => {
|
||||
type.value = value.title
|
||||
data.value.type = value.title
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emit('update:filters', data.value)
|
||||
})
|
||||
</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">Jenis Pengaduan:</label>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Jenis Pengaduan:</label>
|
||||
|
||||
<InlineRadioGroup :radio-items="[{id: 1, title: 'Gangguan', checked: true}, {id: 2, title: 'Keluhan'}]" />
|
||||
<InlineRadioGroup
|
||||
@update:group-value="setPengaduan"
|
||||
:radio-items="[
|
||||
{ id: 1, title: 'Gangguan', checked: true },
|
||||
{ id: 2, title: 'Keluhan' }
|
||||
]"
|
||||
/>
|
||||
</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">Cari Report Number:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Cari Report Number:</label>
|
||||
|
||||
<InputWithFilter placeholder="cari report" :filters="[{id: 1, title: 'Nama Pelapor'}]" />
|
||||
<InputWithFilter
|
||||
placeholder="Cari Report"
|
||||
:filters="reportType"
|
||||
@update:keyword="changeKeyword"
|
||||
@update:filters="changeReportTypeSelected"
|
||||
/>
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2" v-if="searchBy != 'Nomor Laporan'">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
<DatePicker @update:date-value="(value) => (data.periode = value)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
105
src/components/Form/FiltersType/Type16.vue
Normal file → Executable file
@ -1,38 +1,105 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import Select from '@/components/Select.vue';
|
||||
import DatePicker from '@/components/DatePicker.vue';
|
||||
import {
|
||||
selectedUid,
|
||||
selectedUp3Posko,
|
||||
selectedPosko,
|
||||
fetchUid,
|
||||
fetchMedia,
|
||||
itemsUid,
|
||||
itemsUp3,
|
||||
itemsPosko,
|
||||
itemsMedia
|
||||
} from './reference';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah'
|
||||
const up3Placeholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan'
|
||||
const poskoPlaceholder = 'Semua Posko'
|
||||
const mediaPlaceholder = 'Semua Media'
|
||||
const up3 = ref({ id: 0, name: up3Placeholder })
|
||||
const uid = ref({ id: 0, name: uidPlaceholder })
|
||||
const posko = ref({ id: 0, name: poskoPlaceholder })
|
||||
const media = ref({ id: '', name: mediaPlaceholder })
|
||||
const emit = defineEmits(['update:filters'])
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: up3.value,
|
||||
posko: posko.value,
|
||||
media: media.value,
|
||||
periode: ''
|
||||
})
|
||||
|
||||
watch(data.value, (value) => {
|
||||
emit('update:filters', value)
|
||||
})
|
||||
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value
|
||||
selectedUid(value)
|
||||
up3.value = { id: 0, name: up3Placeholder }
|
||||
data.value.uid = value
|
||||
}
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
up3.value = value
|
||||
selectedUp3Posko(value)
|
||||
posko.value = { id: 0, name: poskoPlaceholder }
|
||||
data.value.up3 = value
|
||||
}
|
||||
|
||||
const setPosko = (value: any) => {
|
||||
posko.value = value
|
||||
selectedPosko(value)
|
||||
data.value.posko = value
|
||||
}
|
||||
|
||||
const setMedia = (value: any) => {
|
||||
media.value = value
|
||||
data.value.media = value
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emit('update:filters', data.value)
|
||||
fetchUid()
|
||||
fetchMedia()
|
||||
})
|
||||
</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>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Induk Distribusi/Wilayah"/>
|
||||
<Select :data="itemsUid" @update:selected="setUid($event)" :placeholder="uidPlaceholder" :selected="uid" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
<Select :data="itemsUp3" @update:selected="setUp3($event)" :placeholder="up3Placeholder" :selected="up3" />
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Posko:</label>
|
||||
|
||||
<Select placeholder="Semua Posko" />
|
||||
<Select :data="itemsPosko" @update:selected="setPosko($event)" :placeholder="poskoPlaceholder"
|
||||
:selected="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">Media:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Media:</label>
|
||||
|
||||
<Select placeholder="Semua Media" />
|
||||
<Select :selected="media" @update:selected="setMedia($event)" :placeholder="mediaPlaceholder"
|
||||
:data="itemsMedia" />
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
<DatePicker @update:date-value="(value) => (data.periode = value)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
37
src/components/Form/FiltersType/Type17.vue
Normal file → Executable file
@ -1,18 +1,23 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import InputWithFilter from '../InputWithFilter.vue'
|
||||
import Select from '@/components/Select.vue';
|
||||
import DatePicker from '@/components/DatePicker.vue';
|
||||
import InputWithFilter from '../InputWithFilter.vue';
|
||||
import { ref } from 'vue';
|
||||
const data = ref({
|
||||
periode: '',
|
||||
})
|
||||
</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">Periode Tanggal:</label>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
<DatePicker @update:date-value="(value) => data.periode = value" />
|
||||
</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 PLN:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit PLN:</label>
|
||||
|
||||
<div class="flex flex-col gap-y-1">
|
||||
<Select placeholder="Pilih Unit" />
|
||||
@ -24,23 +29,23 @@
|
||||
</div>
|
||||
</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">Status:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Status:</label>
|
||||
|
||||
<Select placeholder="Pilih Status" />
|
||||
</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"
|
||||
>SLA:</label
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">SLA:</label>
|
||||
|
||||
<Select placeholder="Pilih Durasi SLA" />
|
||||
</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">Pencarian:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Pencarian:</label>
|
||||
|
||||
<InputWithFilter placeholder="cari report" :filters="[{ id: 1, title: 'Pilih Jenis' }]" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
68
src/components/Form/FiltersType/Type18.vue
Executable file
@ -0,0 +1,68 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue';
|
||||
import SelectMulti from '@/components/SelectMulti.vue';
|
||||
|
||||
import DatePicker from '@/components/DatePicker.vue';
|
||||
import { selectedUid, selectedUp3Posko, selectedPosko, fetchUid, itemsUid, itemsUp3, itemsPosko } from './reference';
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah';
|
||||
const up3Placeholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan';
|
||||
const poskoPlaceholder = 'Semua Posko';
|
||||
const up3 = ref({ id: 0, name: up3Placeholder });
|
||||
const uid = ref({ id: 0, name: uidPlaceholder });
|
||||
const posko = ref({ id: 0, name: poskoPlaceholder });
|
||||
const emit = defineEmits(['update:filters'])
|
||||
const jenisTransakasi = [
|
||||
{ id: 1, value: 'Koreksi Transaksi Individual', label: 'Koreksi Transaksi Individual' },
|
||||
{ id: 2, value: 'Cleansing Traksaksi TM', label: 'Cleansing Traksaksi TM', },
|
||||
{ id: 3, value: 'Koreksi Transaksi TM', label: 'Koreksi Transaksi TM', },
|
||||
{ id: 4, value: 'Koreksi Kode Gangguan dan Anev', label: 'Koreksi Kode Gangguan dan Anev' },
|
||||
]
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: up3.value,
|
||||
posko: posko.value,
|
||||
periode: '',
|
||||
jenisTransaksi: [],
|
||||
group: 1
|
||||
})
|
||||
onMounted(() => {
|
||||
emit('update:filters', data.value)
|
||||
fetchUid()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select @update:selected="selectedUid($event)" :data="itemsUid"
|
||||
placeholder="Semua Unit Induk Distribusi/Wilayah" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select @update:selected="selectedUp3Posko($event)" :data="itemsUp3" :selected="up3"
|
||||
placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Posko:</label>
|
||||
|
||||
<Select @update:selected="selectedPosko($event)" :data="itemsPosko" :selected="posko" placeholder="Semua Posko" />
|
||||
</div>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Jenis Transaksi:</label>
|
||||
|
||||
<SelectMulti :tags="jenisTransakasi" placeholder="Semua Jenis Transaksi" useLabel label="Jenis Transaksi" />
|
||||
</div>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
<DatePicker @update:date-value="(value) => data.periode = value" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
137
src/components/Form/FiltersType/Type2.vue
Normal file → Executable file
@ -1,42 +1,137 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import Select from '@/components/Select.vue';
|
||||
import {
|
||||
selectedUid,
|
||||
selectedUp3Ulp,
|
||||
fetchRegional,
|
||||
fetchUid, itemsUid,
|
||||
itemsUp3,
|
||||
itemsUlp,
|
||||
itemsRegional,
|
||||
months,
|
||||
years
|
||||
} from './reference';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { getMonthName } from '@/utils/texts';
|
||||
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah'
|
||||
const up3Placholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan'
|
||||
const ulpPlaceholder = 'Semua Unit Layanan Pelanggan'
|
||||
const regionalPlaceholder = 'Semua Regional'
|
||||
const bulanPlaceholder = getMonthName(new Date().getMonth())
|
||||
const tahunPlaceholder = new Date().getFullYear().toString()
|
||||
const bulanSelected = new Date().getMonth()
|
||||
const tahunSelected = new Date().getFullYear()
|
||||
const uppp = ref({ id: 0, name: up3Placholder })
|
||||
const uid = ref({ id: 0, name: uidPlaceholder })
|
||||
const ulp = ref({ id: 0, name: ulpPlaceholder })
|
||||
const bulan = ref({ id: bulanSelected, name: bulanPlaceholder })
|
||||
const tahun = ref({ id: tahunSelected, name: tahunPlaceholder })
|
||||
const regional = ref({ id: 0, name: regionalPlaceholder })
|
||||
const emit = defineEmits(['update:filters'])
|
||||
// Find index of January
|
||||
const bulanIndex = months.findIndex((month) => month.id === bulan.value.id)
|
||||
console.log(bulanSelected)
|
||||
// Remove January if found
|
||||
if (bulanIndex !== -1) {
|
||||
months.splice(bulanIndex, 1)
|
||||
}
|
||||
// Find index of current year
|
||||
const tahunIndex = years.value.findIndex((year) => year.id === tahun.value.id)
|
||||
if (tahunIndex !== -1) {
|
||||
years.value.splice(tahunIndex, 1)
|
||||
}
|
||||
|
||||
const data = ref({
|
||||
regional: regional.value,
|
||||
uid: uid.value,
|
||||
up3: uppp.value,
|
||||
ulp: ulp.value,
|
||||
periode: '',
|
||||
bulan: bulan.value,
|
||||
tahun: tahun.value
|
||||
})
|
||||
|
||||
const setRegional = (value: any) => {
|
||||
regional.value = value
|
||||
fetchUid()
|
||||
// harusnya fetchUidWithRegional(value);
|
||||
selectedUid(value)
|
||||
uid.value = { id: 0, name: uidPlaceholder }
|
||||
data.value.regional = value
|
||||
}
|
||||
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value
|
||||
selectedUid(value)
|
||||
uppp.value = { id: 0, name: up3Placholder }
|
||||
data.value.uid = value
|
||||
}
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
uppp.value = value
|
||||
selectedUp3Ulp(value)
|
||||
ulp.value = { id: 0, name: ulpPlaceholder }
|
||||
data.value.up3 = value
|
||||
}
|
||||
|
||||
const setUlp = (value: any) => {
|
||||
ulp.value = value
|
||||
selectedUp3Ulp(value)
|
||||
data.value.ulp = value
|
||||
}
|
||||
|
||||
const setMonth = (value: any) => {
|
||||
bulan.value = value
|
||||
data.value.bulan = value
|
||||
console.log(data.value)
|
||||
}
|
||||
|
||||
const setYear = (value: any) => {
|
||||
tahun.value = value
|
||||
data.value.tahun = value
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emit('update:filters', data.value)
|
||||
fetchRegional()
|
||||
})
|
||||
</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">Regional:</label>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Regional:</label>
|
||||
|
||||
<Select placeholder="Semua Regional"/>
|
||||
<Select @update:selected="setRegional($event)" :data="itemsRegional" :placeholder="regionalPlaceholder" />
|
||||
</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 Induk Distribusi/Wilayah:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Induk Distribusi/Wilayah"/>
|
||||
<Select @update:selected="setUid($event)" :data="itemsUid" :selected="uid" :placeholder="uidPlaceholder" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
<Select @update:selected="setUp3($event)" :selected="uppp" :data="itemsUp3" :placeholder="up3Placholder" />
|
||||
</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 Layanan Pelanggan:</label
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Layanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Layanan Pelanggan" />
|
||||
<Select @update:selected="setUlp($event)" :data="itemsUlp" :selected="ulp" :placeholder="ulpPlaceholder" />
|
||||
</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</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode</label>
|
||||
|
||||
<div class="grid grid-cols-2 gap-x-2">
|
||||
<Select placeholder="Juli" />
|
||||
<Select placeholder="2023" />
|
||||
<Select @update:selected="setMonth($event)" :data="months" :placeholder="bulanPlaceholder" />
|
||||
<Select @update:selected="setYear($event)" :data="years" :placeholder="tahunPlaceholder" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
90
src/components/Form/FiltersType/Type3.vue
Normal file → Executable file
@ -1,34 +1,88 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import Select from '@/components/Select.vue';
|
||||
import DatePicker from '@/components/DatePicker.vue';
|
||||
import {
|
||||
selectedUid,
|
||||
selectedUp3Ulp,
|
||||
selectedUlp,
|
||||
fetchUid,
|
||||
itemsUid,
|
||||
itemsUp3,
|
||||
itemsUlp
|
||||
} from './reference';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah'
|
||||
const up3Placeholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan'
|
||||
const ulpPlaceholder = 'Semua Unit Layanan Pelanggan'
|
||||
const up3 = ref({ id: 0, name: up3Placeholder })
|
||||
const uid = ref({ id: 0, name: uidPlaceholder })
|
||||
const ulp = ref({ id: 0, name: ulpPlaceholder })
|
||||
const emit = defineEmits(['update:filters'])
|
||||
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: up3.value,
|
||||
ulp: ulp.value,
|
||||
periode: ''
|
||||
})
|
||||
|
||||
watch(data.value, (value) => {
|
||||
emit('update:filters', value)
|
||||
})
|
||||
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value
|
||||
selectedUid(value)
|
||||
up3.value = { id: 0, name: up3Placeholder }
|
||||
data.value.uid = value
|
||||
}
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
up3.value = value
|
||||
selectedUp3Ulp(value)
|
||||
ulp.value = { id: 0, name: ulpPlaceholder }
|
||||
data.value.up3 = value
|
||||
console.log(itemsUlp)
|
||||
}
|
||||
|
||||
const setUlp = (value: any) => {
|
||||
ulp.value = value
|
||||
selectedUlp(value)
|
||||
data.value.ulp = value
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchUid()
|
||||
emit('update:filters', data.value)
|
||||
})
|
||||
</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>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Induk Distribusi/Wilayah"/>
|
||||
<Select @update:selected="setUid($event)" :data="itemsUid" :placeholder="uidPlaceholder" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :selected="up3" :placeholder="up3Placeholder" />
|
||||
</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 Layanan Pelanggan:</label
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Layanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Layanan Pelanggan" />
|
||||
<Select @update:selected="setUlp($event)" :data="itemsUlp" :selected="ulp" :placeholder="ulpPlaceholder" />
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
<DatePicker @update:date-value="(value) => (data.periode = value)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
94
src/components/Form/FiltersType/Type4.vue
Normal file → Executable file
@ -1,42 +1,94 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import { selectedUid, selectedUp3Ulp, selectedUlp, itemsUid, itemsUp3, itemsUlp } from './reference'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah'
|
||||
const up3Placeholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan'
|
||||
const ulpPlaceholder = 'Semua Unit Layanan Pelanggan'
|
||||
const uppp = ref({ id: 0, name: up3Placeholder })
|
||||
const uid = ref({ id: 0, name: uidPlaceholder })
|
||||
const ulp = ref({ id: 0, name: ulpPlaceholder })
|
||||
const emit = defineEmits(['update:filters'])
|
||||
const props = defineProps({
|
||||
jenisLaporan: {
|
||||
type: Array as () => any[],
|
||||
default: () => [
|
||||
{ id: 1, name: 'Laporan Berulang Unit' },
|
||||
{ id: 2, name: 'Laporan Berulang Pelanggan' },
|
||||
{ id: 3, name: 'Laporan Berulang Pelanggan dan Unit' }
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const jenisLaporan = ref(computed(() => props.jenisLaporan))
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: uppp.value,
|
||||
ulp: ulp.value,
|
||||
periode: '',
|
||||
jenisLaporan: ''
|
||||
})
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value
|
||||
selectedUid(value)
|
||||
uppp.value = { id: 0, name: up3Placeholder }
|
||||
data.value.uid = value
|
||||
}
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
uppp.value = value
|
||||
selectedUp3Ulp(value)
|
||||
ulp.value = { id: 0, name: ulpPlaceholder }
|
||||
data.value.up3 = value
|
||||
}
|
||||
|
||||
const setUlp = (value: any) => {
|
||||
ulp.value = value
|
||||
selectedUlp(value)
|
||||
data.value.ulp = value
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emit('update:filters', data.value)
|
||||
// fetchUid()
|
||||
})
|
||||
</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>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Induk Distribusi/Wilayah"/>
|
||||
<Select @update:selected="setUid($event)" :data="itemsUid" :placeholder="uidPlaceholder" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :placeholder="up3Placeholder" />
|
||||
</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 Layanan Pelanggan:</label
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Layanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Layanan Pelanggan" />
|
||||
<Select @update:selected="setUlp($event)" :data="itemsUlp" :placeholder="ulpPlaceholder" />
|
||||
</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 Laporan:</label
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Jenis Laporan:</label>
|
||||
|
||||
<Select placeholder="Laporan Berulang Unit" />
|
||||
<Select
|
||||
@update:selected="(value) => (data.jenisLaporan = value)"
|
||||
:data="jenisLaporan"
|
||||
:placeholder="'Semua Jenis Laporan'"
|
||||
/>
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
<DatePicker @update:date-value="(value) => (data.periode = value)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
88
src/components/Form/FiltersType/Type5.vue
Normal file → Executable file
@ -1,32 +1,86 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import {
|
||||
selectedUid,
|
||||
selectedUp3Posko,
|
||||
selectedPosko,
|
||||
fetchUid,
|
||||
itemsUid,
|
||||
itemsUp3,
|
||||
itemsPosko
|
||||
} from './reference';
|
||||
|
||||
import Select from '@/components/Select.vue';
|
||||
import DatePicker from '@/components/DatePicker.vue';
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah'
|
||||
const uppPlaceholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan'
|
||||
const poskoPlaceholder = 'Semua Posko'
|
||||
const uppp = ref({ id: 0, name: uppPlaceholder })
|
||||
const uid = ref({ id: 0, name: uidPlaceholder })
|
||||
const posko = ref({ id: 0, name: poskoPlaceholder })
|
||||
const emit = defineEmits(['update:filters'])
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: uppp.value,
|
||||
posko: posko.value,
|
||||
periode: ''
|
||||
})
|
||||
|
||||
watch(data.value, (value) => {
|
||||
emit('update:filters', value)
|
||||
})
|
||||
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value
|
||||
selectedUid(value)
|
||||
uppp.value = { id: 0, name: uppPlaceholder }
|
||||
data.value.uid = value
|
||||
}
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
uppp.value = value
|
||||
selectedUp3Posko(value)
|
||||
posko.value = { id: 0, name: poskoPlaceholder }
|
||||
data.value.up3 = value
|
||||
}
|
||||
|
||||
const setPosko = (value: any) => {
|
||||
posko.value = value
|
||||
selectedPosko(value)
|
||||
data.value.posko = value
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emit('update:filters', data.value)
|
||||
fetchUid()
|
||||
})
|
||||
</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>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Induk Distribusi/Wilayah"/>
|
||||
<Select :data="itemsUid" @update:selected="setUid($event)" :placeholder="uidPlaceholder" :selected="uid" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :selected="uppp" :placeholder="uppPlaceholder" />
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Posko:</label>
|
||||
|
||||
<Select placeholder="Semua Posko" />
|
||||
<Select @update:selected="setPosko($event)" :data="itemsPosko" :selected="posko"
|
||||
:placeholder="poskoPlaceholder" />
|
||||
</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 class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
<DatePicker @update:date-value="(value) => data.periode = value" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
94
src/components/Form/FiltersType/Type6.vue
Normal file → Executable file
@ -1,42 +1,98 @@
|
||||
<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,
|
||||
selectedUp3Posko,
|
||||
selectedPosko,
|
||||
fetchUid,
|
||||
itemsUid,
|
||||
itemsUp3,
|
||||
itemsPosko
|
||||
} from './reference'
|
||||
import { onMounted, ref } from 'vue'
|
||||
|
||||
const emit = defineEmits(['update:filters'])
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah'
|
||||
const up3Placeholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan'
|
||||
const poskoPlaceholder = 'Semua Posko'
|
||||
const up3 = ref({ id: 0, name: up3Placeholder })
|
||||
const uid = ref({ id: 0, name: uidPlaceholder })
|
||||
const posko = ref({ id: 0, name: poskoPlaceholder })
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: up3.value,
|
||||
posko: posko.value,
|
||||
periode: '',
|
||||
minJmlLapor: 1,
|
||||
maxJmlLapor: 1
|
||||
})
|
||||
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value
|
||||
selectedUid(value)
|
||||
up3.value = { id: 0, name: up3Placeholder }
|
||||
data.value.uid = value
|
||||
}
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
up3.value = value
|
||||
selectedUp3Posko(value)
|
||||
posko.value = { id: 0, name: poskoPlaceholder }
|
||||
data.value.up3 = value
|
||||
}
|
||||
|
||||
const setPosko = (value: any) => {
|
||||
posko.value = value
|
||||
selectedPosko(value)
|
||||
data.value.posko = value
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchUid()
|
||||
emit('update:filters', data.value)
|
||||
})
|
||||
</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>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Induk Distribusi/Wilayah"/>
|
||||
<Select @update:selected="setUid($event)" :data="itemsUid" :placeholder="uidPlaceholder" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :selected="up3" :placeholder="up3Placeholder" />
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Posko:</label>
|
||||
|
||||
<Select placeholder="Semua Posko" />
|
||||
<Select @update:selected="setPosko($event)" :data="itemsPosko" :selected="posko"
|
||||
:placeholder="poskoPlaceholder" />
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
<DatePicker @update:date-value="(value) => (data.periode = value)" />
|
||||
</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">Lapor Ulang:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Lapor Ulang:</label>
|
||||
|
||||
<div class="grid grid-flow-col auto-cols-auto gap-x-1.5">
|
||||
<Select placeholder="1" />
|
||||
<div class="flex flex-1 justify-between gap-x-1.5">
|
||||
<InputNumber :value="data.minJmlLapor" @update:time-value="(value) => (data.minJmlLapor = value)"
|
||||
class="flex flex-1" />
|
||||
<small class="flex items-center">s/d</small>
|
||||
<Select placeholder="2" />
|
||||
<InputNumber :value="data.maxJmlLapor" @update:time-value="(value) => (data.maxJmlLapor = value)"
|
||||
class="flex flex-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
174
src/components/Form/FiltersType/Type7.vue
Normal file → Executable file
@ -1,47 +1,177 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
interface SlaOption {
|
||||
id: number
|
||||
name: string
|
||||
min: string
|
||||
max: string
|
||||
}
|
||||
|
||||
import Select from '@/components/Select.vue';
|
||||
import DatePicker from '@/components/DatePicker.vue';
|
||||
import InputWithSuffix from '../InputWithSuffix.vue';
|
||||
import {
|
||||
selectedUid,
|
||||
selectedUp3Posko,
|
||||
selectedPosko,
|
||||
fetchUid,
|
||||
itemsUid,
|
||||
itemsUp3,
|
||||
itemsPosko
|
||||
} from './reference';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
slaOptions: {
|
||||
type: Array as () => SlaOption[],
|
||||
default: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'Dibawah / Sesuai SLA (<= 45 menit)',
|
||||
min: '1',
|
||||
max: '45'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'Melebihi SLA (> 45 menit)',
|
||||
min: '46',
|
||||
max: `${99999 * 60 * 24}`
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const sla = props.slaOptions.map((item: any) => {
|
||||
return {
|
||||
id: item.id,
|
||||
name: item.name
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['update:filters'])
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah'
|
||||
const up3Placeholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan'
|
||||
const poskoPlaceholder = 'Semua Posko'
|
||||
const up3 = ref({ id: 0, name: up3Placeholder })
|
||||
const uid = ref({ id: 0, name: uidPlaceholder })
|
||||
const posko = ref({ id: 0, name: poskoPlaceholder })
|
||||
const isHidden = ref(false)
|
||||
const totalMin = ref('1 Menit')
|
||||
const totalMax = ref('5 Menit')
|
||||
|
||||
const setDataMin = (value: any) => (totalMin.value = value)
|
||||
const getDataMin = () => totalMin.value
|
||||
const setDataMax = (value: any) => (totalMax.value = value)
|
||||
const getDataMax = () => totalMax.value
|
||||
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: up3.value,
|
||||
posko: posko.value,
|
||||
periode: '',
|
||||
minTime: getDataMin().split(' ')[0],
|
||||
maxTime: getDataMax().split(' ')[0]
|
||||
})
|
||||
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value
|
||||
selectedUid(value)
|
||||
up3.value = { id: 0, name: up3Placeholder }
|
||||
data.value.uid = value
|
||||
}
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
up3.value = value
|
||||
selectedUp3Posko(value)
|
||||
posko.value = { id: 0, name: poskoPlaceholder }
|
||||
data.value.up3 = value
|
||||
}
|
||||
|
||||
const setPosko = (value: any) => {
|
||||
posko.value = value
|
||||
selectedPosko(value)
|
||||
data.value.posko = value
|
||||
}
|
||||
|
||||
const setMin = (value: any) => {
|
||||
console.log(value)
|
||||
data.value.minTime = value
|
||||
setDataMin(value)
|
||||
}
|
||||
const setMax = (value: any) => {
|
||||
data.value.maxTime = value
|
||||
setDataMax(value)
|
||||
}
|
||||
const triggerInput = ref(false)
|
||||
const changeDuration = (value: any) => {
|
||||
if (value.id === 0) {
|
||||
setMin('1')
|
||||
setMax('5')
|
||||
|
||||
triggerInput.value = false
|
||||
isHidden.value = false
|
||||
} else if (value.id === 1) {
|
||||
setMin(props.slaOptions[0].min)
|
||||
setMax(props.slaOptions[0].max)
|
||||
|
||||
triggerInput.value = true
|
||||
isHidden.value = true
|
||||
} else {
|
||||
setMin(props.slaOptions[1].min)
|
||||
setMax(props.slaOptions[1].max)
|
||||
|
||||
triggerInput.value = true
|
||||
isHidden.value = true
|
||||
}
|
||||
}
|
||||
watch(data, (newValue) => {
|
||||
emit('update:filters', newValue)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
fetchUid()
|
||||
emit('update:filters', data.value)
|
||||
})
|
||||
</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>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Induk Distribusi/Wilayah"/>
|
||||
<Select @update:selected="setUid($event)" :data="itemsUid" :placeholder="uidPlaceholder" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :selected="up3" :placeholder="up3Placeholder" />
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Posko:</label>
|
||||
|
||||
<Select placeholder="Semua Posko" />
|
||||
<Select @update:selected="setPosko($event)" :data="itemsPosko" :selected="posko"
|
||||
:placeholder="poskoPlaceholder" />
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
<DatePicker @update:date-value="(value) => (data.periode = value)" />
|
||||
</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">Durasi:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Durasi:</label>
|
||||
|
||||
<div class="flex flex-col gap-y-1">
|
||||
<Select placeholder="Durasi Menit" />
|
||||
<Select @update:selected="changeDuration($event)" :data="sla" placeholder="Durasi Menit" />
|
||||
|
||||
<div class="grid grid-flow-col auto-cols-auto gap-x-1.5">
|
||||
<InputWithSuffix />
|
||||
<div class="flex flex-1 justify-between gap-x-1.5" :class="[isHidden ? 'hidden' : '']">
|
||||
<InputWithSuffix :value="`${data.minTime} Menit`" @update:text="setMin($event)" class="flex flex-1" />
|
||||
<small class="flex items-center">s/d</small>
|
||||
<InputWithSuffix />
|
||||
<InputWithSuffix :value="`${data.maxTime} Menit`" @update:text="setMax($event)" class="flex flex-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
65
src/components/Form/FiltersType/Type8.vue
Normal file → Executable file
@ -1,26 +1,65 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import Select from '@/components/Select.vue';
|
||||
import DatePicker from '@/components/DatePicker.vue';
|
||||
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { selectedUid, fetchUid, itemsUid, itemsUp3 } from './reference';
|
||||
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah'
|
||||
const uppPlaceholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan'
|
||||
const poskoPlaceholder = 'Semua Posko'
|
||||
const uppp = ref({ id: 0, name: uppPlaceholder })
|
||||
const uid = ref({ id: 0, name: uidPlaceholder })
|
||||
const posko = ref({ id: 0, name: poskoPlaceholder })
|
||||
const emit = defineEmits(['update:filters'])
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: uppp.value,
|
||||
posko: posko.value,
|
||||
periode: ''
|
||||
})
|
||||
|
||||
watch(data.value, (value) => {
|
||||
emit('update:filters', value)
|
||||
})
|
||||
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value
|
||||
selectedUid(value)
|
||||
uppp.value = { id: 0, name: uppPlaceholder }
|
||||
data.value.uid = value
|
||||
}
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
uppp.value = value
|
||||
data.value.up3 = value
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emit('update:filters', data.value)
|
||||
fetchUid()
|
||||
})
|
||||
</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>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Induk Distribusi/Wilayah"/>
|
||||
<Select @update:selected="setUid($event)" :data="itemsUid" :placeholder="uidPlaceholder" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :selected="uppp" :placeholder="uppPlaceholder" />
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
<DatePicker @update:date-value="(value) => (data.periode = value)" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
94
src/components/Form/FiltersType/Type9.vue
Normal file → Executable file
@ -2,38 +2,98 @@
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import InlineRadioGroup from '@/components/Form/InlineRadioGroup.vue'
|
||||
|
||||
import { onMounted, ref, watch } from 'vue'
|
||||
import {
|
||||
selectedUid,
|
||||
selectedUp3Posko,
|
||||
selectedPosko,
|
||||
fetchUid,
|
||||
itemsUid,
|
||||
itemsUp3,
|
||||
itemsPosko
|
||||
} from './reference'
|
||||
|
||||
const uidPlaceholder = 'Semua Unit Induk Distribusi/Wilayah'
|
||||
const uppPlaceholder = 'Semua Unit Pelaksanaan Pelayanan Pelanggan'
|
||||
const poskoPlaceholder = 'Semua Posko'
|
||||
const uppp = ref({ id: 0, name: uppPlaceholder })
|
||||
const uid = ref({ id: 0, name: uidPlaceholder })
|
||||
const posko = ref({ id: 0, name: poskoPlaceholder })
|
||||
const emit = defineEmits(['update:filters'])
|
||||
const data = ref({
|
||||
uid: uid.value,
|
||||
up3: uppp.value,
|
||||
posko: posko.value,
|
||||
periode: '',
|
||||
groupBy: false
|
||||
})
|
||||
|
||||
watch(data.value, (value) => {
|
||||
emit('update:filters', value)
|
||||
})
|
||||
|
||||
const setUid = (value: any) => {
|
||||
uid.value = value
|
||||
selectedUid(value)
|
||||
uppp.value = { id: 0, name: uppPlaceholder }
|
||||
data.value.uid = value
|
||||
}
|
||||
|
||||
const setUp3 = (value: any) => {
|
||||
uppp.value = value
|
||||
selectedUp3Posko(value)
|
||||
posko.value = { id: 0, name: poskoPlaceholder }
|
||||
data.value.up3 = value
|
||||
}
|
||||
|
||||
const setPosko = (value: any) => {
|
||||
posko.value = value
|
||||
selectedPosko(value)
|
||||
data.value.posko = value
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchUid()
|
||||
emit('update:filters', data.value)
|
||||
})
|
||||
</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>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Induk Distribusi/Wilayah:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Induk Distribusi/Wilayah"/>
|
||||
<Select @update:selected="setUid($event)" :data="itemsUid" :placeholder="uidPlaceholder" />
|
||||
</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
|
||||
>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :placeholder="uppPlaceholder" :selected="uppp" />
|
||||
</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>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Posko:</label>
|
||||
|
||||
<Select placeholder="Semua Posko" />
|
||||
<Select @update:selected="setPosko($event)" :data="itemsPosko" :placeholder="poskoPlaceholder"
|
||||
:selected="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">Periode Tanggal:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
<DatePicker @update:date-value="(value) => (data.periode = value)" />
|
||||
</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">Group By Kode Unit Distribusi:</label>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Group By Kode Unit Distribusi:</label>
|
||||
|
||||
<InlineRadioGroup :radio-items="[{id: 1, title: 'Tidak', checked: true}, {id: 2, title: 'Ya, Grupkan'}]" />
|
||||
<InlineRadioGroup @update:group-value="(value) => (data.groupBy = value.id === 2)" :radio-items="[
|
||||
{ id: 1, title: 'Tidak', checked: true },
|
||||
{ id: 2, title: 'Ya, Grupkan' }
|
||||
]" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
1
src/components/Form/FiltersType/index.ts
Normal file → Executable 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'
|
||||
|
190
src/components/Form/FiltersType/reference.ts
Executable file
@ -0,0 +1,190 @@
|
||||
import { usePostsStore } from '@/stores/posts'
|
||||
import { useUlpStore } from '@/stores/ulp'
|
||||
import { getUid, getUp3, getPosko, getUlp, getRegional, getUidRegional } from '@/utils/api/api.rest'
|
||||
import { ref } from 'vue'
|
||||
interface Item {
|
||||
id: any
|
||||
name: any
|
||||
}
|
||||
const months = [
|
||||
{ id: 1, name: 'Januari' },
|
||||
{ id: 2, name: 'Februari' },
|
||||
{ id: 3, name: 'Maret' },
|
||||
{ id: 4, name: 'April' },
|
||||
{ id: 5, name: 'Mei' },
|
||||
{ id: 6, name: 'Juni' },
|
||||
{ id: 7, name: 'Juli' },
|
||||
{ id: 8, name: 'Agustus' },
|
||||
{ id: 9, name: 'September' },
|
||||
{ id: 10, name: 'Oktober' },
|
||||
{ id: 11, name: 'November' },
|
||||
{ id: 12, name: 'Desember' }
|
||||
]
|
||||
// create 4 year back array
|
||||
const year = new Date().getFullYear()
|
||||
const years = ref<Item[]>([])
|
||||
for (let i = 0; i < 5; i++) {
|
||||
years.value.push({ id: year - i, name: year - i })
|
||||
}
|
||||
const itemsUid = ref<Item[]>([])
|
||||
const itemsUp3 = ref<Item[]>([])
|
||||
const itemsPosko = ref<Item[]>([])
|
||||
const itemsUlp = ref<Item[]>([])
|
||||
const itemsRegional = ref<Item[]>([])
|
||||
const itemsMedia = ref<Item[]>([])
|
||||
// Fetch data from the API using Axios
|
||||
const fetchMedia = () => {
|
||||
itemsMedia.value = [
|
||||
{ id: 'Ulasan Aplikasi PLN Mobile', name: 'Ulasan Aplikasi PLN Mobile' },
|
||||
{ id: 'Twitter', name: 'Twitter' },
|
||||
{ id: 'PLN Mobile', name: 'PLN Mobile' },
|
||||
{ id: 'Media Massa', name: 'Media Massa' },
|
||||
{ id: 'Live Chat Website', name: 'Live Chat Website' },
|
||||
{ id: 'Live Chat PLN Mobile', name: 'Live Chat PLN Mobile' },
|
||||
{ id: 'Instagram', name: 'Instagram' },
|
||||
{ id: 'Facebook', name: 'Facebook' },
|
||||
{ id: 'Email', name: 'Email' },
|
||||
{ id: 'EMS', name: 'EMS' },
|
||||
{ id: 'Datang ke Kantor', name: 'Datang ke Kantor' },
|
||||
{ id: 'Call ke Kantor Unit', name: 'Call ke Kantor Unit' },
|
||||
{ id: 'Call PLN 123', name: 'Call PLN 123' }
|
||||
]
|
||||
}
|
||||
const fetchUidByRegional = async (regional: number) => {
|
||||
if (regional == 0) {
|
||||
itemsUid.value = []
|
||||
} else {
|
||||
try {
|
||||
const res = await getUidRegional(regional)
|
||||
itemsUid.value = res.data.map((item: any) => ({
|
||||
id: item.id,
|
||||
name: item.nama.toUpperCase()
|
||||
}))
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fetch data from the API using Axios
|
||||
const fetchUid = async () => {
|
||||
try {
|
||||
const res = await getUid()
|
||||
itemsUid.value = res.data.map((item: any) => ({
|
||||
id: item.id,
|
||||
name: item.nama
|
||||
}))
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const fetchDataUp3 = async (uid: number) => {
|
||||
if (uid == 0) {
|
||||
itemsUp3.value = []
|
||||
itemsUlp.value = []
|
||||
itemsPosko.value = []
|
||||
} else {
|
||||
try {
|
||||
const res = await getUp3(uid)
|
||||
itemsUp3.value = res.data.map((item: any) => ({
|
||||
id: item.id,
|
||||
name: item.nama
|
||||
}))
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
const fetchDataUlp = async (up3: number) => {
|
||||
if (up3 == 0) {
|
||||
itemsUlp.value = []
|
||||
} else {
|
||||
try {
|
||||
const res = await getUlp(up3)
|
||||
itemsUlp.value = res.data.map((item: any) => ({
|
||||
id: item.id,
|
||||
name: item.nama
|
||||
}))
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
const fetchDataPosko = async (up3: number) => {
|
||||
if (up3 == 0) {
|
||||
itemsPosko.value = []
|
||||
} else {
|
||||
try {
|
||||
const res = await getPosko(up3)
|
||||
itemsPosko.value = res.data.map((item: any) => ({
|
||||
id: item.id,
|
||||
name: item.nama
|
||||
}))
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
const fetchRegional = async () => {
|
||||
try {
|
||||
const res = await getRegional()
|
||||
itemsRegional.value = res.data.map((item: any) => ({
|
||||
id: item.id,
|
||||
name: String(item.nama).toUpperCase()
|
||||
}))
|
||||
} catch (error) {
|
||||
console.error('Error fetching data:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const formatWaktu = (durasiDetik: number): string => {
|
||||
const hari = Math.floor(durasiDetik / (3600 * 24))
|
||||
const sisaDetik = durasiDetik % (3600 * 24)
|
||||
const jam = Math.floor(sisaDetik / 3600)
|
||||
const sisaDetik2 = sisaDetik % 3600
|
||||
const menit = Math.floor(sisaDetik2 / 60)
|
||||
const detik = sisaDetik2 % 60
|
||||
|
||||
return `${hari} - ${jam} : ${menit} : ${detik}`
|
||||
}
|
||||
|
||||
const selectedUid = (value: any) => {
|
||||
fetchDataUp3(value.id)
|
||||
}
|
||||
const selectedUp3Posko = (value: any) => {
|
||||
if (value.id != 0) {
|
||||
fetchDataPosko(value.id)
|
||||
}
|
||||
}
|
||||
const selectedUp3Ulp = (value: any) => {
|
||||
if (value.id != 0) {
|
||||
fetchDataUlp(value.id)
|
||||
}
|
||||
}
|
||||
const selectedPosko = (value: any) => {
|
||||
usePostsStore().setData(value.id)
|
||||
}
|
||||
const selectedUlp = (value: any) => {
|
||||
useUlpStore().setData(value.id)
|
||||
}
|
||||
|
||||
export {
|
||||
selectedUid,
|
||||
selectedUp3Posko,
|
||||
selectedUp3Ulp,
|
||||
selectedPosko,
|
||||
selectedUlp,
|
||||
fetchRegional,
|
||||
fetchUidByRegional,
|
||||
fetchUid,
|
||||
fetchMedia,
|
||||
itemsUid,
|
||||
itemsUp3,
|
||||
itemsPosko,
|
||||
itemsRegional,
|
||||
itemsMedia,
|
||||
itemsUlp,
|
||||
months,
|
||||
years,
|
||||
formatWaktu
|
||||
}
|
42
src/components/Form/InlineRadioGroup.vue
Normal file → Executable file
@ -3,11 +3,19 @@
|
||||
<fieldset>
|
||||
<div class="space-y-3 sm:flex sm:items-center sm:space-y-0 sm:space-x-5">
|
||||
<div v-for="item in radioItems" :key="item.id" class="flex items-center">
|
||||
<input :id="`${item.id}`" type="radio" name="radio"
|
||||
:checked="item.hasOwnProperty('checked') && item.checked === true"
|
||||
class="w-4 h-4 border-gray-300 text-primary-500 peer focus:ring-primary-500" />
|
||||
<label :for="`${item.id}`" class="block ml-3 text-sm font-medium text-gray-700 peer-checked:text-primary-500">{{
|
||||
item.title }}</label>
|
||||
<input
|
||||
v-model="groupValue"
|
||||
type="radio"
|
||||
name="radio"
|
||||
:checked="itemSelected.id === item.id ? true : false"
|
||||
@change="onChange(item)"
|
||||
class="w-4 h-4 border-gray-300 text-primary-500 peer focus:ring-primary-500"
|
||||
/>
|
||||
<label
|
||||
:for="`${item.id}`"
|
||||
class="block ml-3 text-sm font-medium text-gray-700 peer-checked:text-primary-500"
|
||||
>{{ item.title }}</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
@ -15,18 +23,32 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { type PropType } from 'vue'
|
||||
import { ref, type PropType, onMounted } from 'vue'
|
||||
|
||||
interface Item {
|
||||
id: number;
|
||||
title: string;
|
||||
checked?: boolean;
|
||||
id: number
|
||||
title: string
|
||||
checked?: boolean
|
||||
}
|
||||
|
||||
defineProps({
|
||||
const onChange = (e: Item) => {
|
||||
itemSelected.value = e
|
||||
console.log(e)
|
||||
emit('update:groupValue', e)
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
radioItems: {
|
||||
type: Array as PropType<Item[]>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const itemSelected = ref(props.radioItems[0])
|
||||
const emit = defineEmits(['update:groupValue'])
|
||||
const groupValue = ref(1)
|
||||
|
||||
onMounted(() => {
|
||||
itemSelected.value = props.radioItems[0]
|
||||
})
|
||||
</script>
|
||||
|
43
src/components/Form/InputNumber.vue
Executable file
@ -0,0 +1,43 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
class: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:timeValue'])
|
||||
const timeValue = ref(1)
|
||||
|
||||
watch(timeValue, (newValue) => {
|
||||
emit('update:timeValue', newValue)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative w-full overflow-hidden bg-gray-200 rounded-lg" :class="[props.class]">
|
||||
<input v-model="timeValue" autocomplete="off" type="number" :placeholder="placeholder" :disabled="disabled"
|
||||
:readonly="readonly" inputmode="numeric" pattern="[0-9.]*"
|
||||
onblur="this.value = parseInt(this.value) ? this.value : 1"
|
||||
oninput="this.value = parseInt(this.value) ? this.value.replace(/[^0-9.]/g, '') : 1"
|
||||
class="w-full px-4 py-2 text-sm leading-6 text-gray-900 bg-gray-200 border-0 border-transparent rounded-lg placeholder:text-gray-400 outline-0 focus:outline-0 focus:border-0 focus:ring-0" />
|
||||
</div>
|
||||
</template>
|
30
src/components/Form/InputWithFilter.vue
Normal file → Executable file
@ -1,10 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { PhMagnifyingGlass } from '@phosphor-icons/vue';
|
||||
import { PhMagnifyingGlass } from '@phosphor-icons/vue'
|
||||
import { type PropType } from 'vue'
|
||||
|
||||
interface FilterItems {
|
||||
id: number;
|
||||
title: string;
|
||||
id: number
|
||||
title: string
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
@ -25,29 +25,43 @@ const props = defineProps({
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:keyword', 'update:filters'])
|
||||
|
||||
const setKeyword = (event: Event) => {
|
||||
emit('update:keyword', (event.target as HTMLInputElement).value)
|
||||
}
|
||||
|
||||
const setFilter = (event: Event) => {
|
||||
emit('update:filters', (event.target as HTMLSelectElement).value)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative w-full overflow-hidden rounded-lg">
|
||||
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
|
||||
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<PhMagnifyingGlass size="18" class="text-gray-900" weight="regular" />
|
||||
</div>
|
||||
<input
|
||||
@input="setKeyword"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
type="text"
|
||||
class="w-full px-4 py-2 pl-10 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"
|
||||
class="w-full px-4 py-2 pl-10 text-sm leading-6 text-gray-900 bg-gray-200 border-0 border-transparent rounded-lg placeholder:text-gray-400 outline-0 focus:outline-0 focus:border-0 focus:ring-0"
|
||||
/>
|
||||
<div class="absolute inset-y-0 right-0 flex items-center">
|
||||
<label for="filters" class="sr-only">filters</label>
|
||||
<span class="block border border-gray-600 h-5"></span>
|
||||
<span class="block h-5 border border-gray-600"></span>
|
||||
<select
|
||||
@change="setFilter"
|
||||
id="filters"
|
||||
name="filters"
|
||||
class="h-full bg-gray-200 text-sm rounded-lg border-transparent py-0 pl-2 pr-7 text-gray-900 focus:outline-0 focus:border-0 focus:ring-0"
|
||||
class="h-full py-0 pl-2 text-sm text-gray-900 bg-gray-200 border-transparent rounded-lg pr-7 focus:outline-0 focus:border-0 focus:ring-0"
|
||||
>
|
||||
<option :key="filter.id" :value="filter.id" v-for="filter in filters">{{ filter.title }}</option>
|
||||
<option :key="filter.id" :value="filter.id" v-for="filter in filters">
|
||||
{{ filter.title }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
58
src/components/Form/InputWithSuffix.vue
Normal file → Executable file
@ -1,34 +1,58 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "",
|
||||
default: ''
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '1 Menit'
|
||||
},
|
||||
class: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const handleInput = (e: any) => {
|
||||
e.target.value = e.target.value.replace(/[^0-9.]/g, '')
|
||||
}
|
||||
|
||||
const handleBlur = (e: any) => {
|
||||
e.target.value = e.target.value ? e.target.value + ' Menit' : ''
|
||||
}
|
||||
|
||||
const handleFocus = (e: any) => {
|
||||
e.target.value = e.target.value.replace(/[^0-9.]/g, '')
|
||||
}
|
||||
|
||||
const emit = defineEmits(['update:text'])
|
||||
const text = ref(props.value)
|
||||
|
||||
watch(text, (val) => {
|
||||
const validatedText = val.replace(/[^0-9.]/g, '')
|
||||
|
||||
if (parseInt(validatedText)) {
|
||||
emit('update:text', validatedText)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="relative w-full overflow-hidden rounded-lg bg-gray-200">
|
||||
<input
|
||||
autocomplete="off"
|
||||
type="text"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:readonly="readonly"
|
||||
inputmode="numeric"
|
||||
pattern="[0-9.]*"
|
||||
oninput="this.value = this.value.replace(/[^0-9.]/g, '')"
|
||||
onblur="this.value = this.value ? this.value + ' Menit' : ''"
|
||||
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 class="relative w-full overflow-hidden bg-gray-200 rounded-lg" :class="[props.class]">
|
||||
<input v-model="text" autocomplete="off" type="text" :placeholder="placeholder" :readonly="readonly"
|
||||
inputmode="numeric" pattern="[0-9.]*" :disabled="disabled" @input="handleInput($event)" @blur="handleBlur($event)"
|
||||
@focus="handleFocus($event)"
|
||||
class="w-full px-4 py-2 text-sm leading-6 text-gray-900 bg-gray-200 border-0 border-transparent rounded-lg placeholder:text-gray-400 outline-0 focus:outline-0 focus:border-0 focus:ring-0" />
|
||||
</div>
|
||||
</template>
|
||||
|
0
src/components/Input.vue
Normal file → Executable file
29
src/components/InputText.vue
Normal file → Executable file
@ -1,37 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { ref } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
default: "text",
|
||||
default: 'text'
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "",
|
||||
default: ''
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: "",
|
||||
default: ''
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
default: false
|
||||
},
|
||||
className: {
|
||||
type: String,
|
||||
default: "",
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:value'])
|
||||
|
||||
const updateValue = (event: Event) => {
|
||||
const value = (event.target as HTMLInputElement).value;
|
||||
const value = (event.target as HTMLInputElement).value
|
||||
emit('update:value', value)
|
||||
}
|
||||
|
||||
@ -39,14 +39,17 @@ const inputType = ref(props.type)
|
||||
const switchInputType = () => {
|
||||
inputType.value = inputType.value == 'password' ? 'text' : 'password'
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="['relative w-full overflow-hidden rounded-lg bg-gray-50 ', className]">
|
||||
<input autocomplete="off" :type="inputType" :placeholder="placeholder" :value="value" @input="updateValue($event)"
|
||||
:disabled="disabled" :readonly="readonly"
|
||||
: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 :class="['relative w-full overflow-hidden rounded-lg bg-gray-200 ', className]">
|
||||
<input v-if="!readonly" autocomplete="off" :type="inputType" :placeholder="placeholder" :value="value"
|
||||
@input="updateValue($event)" :disabled="disabled" :readonly="readonly" :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'
|
||||
]" />
|
||||
<p v-else
|
||||
class="px-4 py-2 text-sm leading-6 text-gray-900 bg-gray-200 border-0 border-transparent rounded-lg outline-0 min-h-[40px]">
|
||||
{{ value && value.length < 1 && value.trim() === '' ? '-' : value }} </p>
|
||||
<span @click="switchInputType" v-if="type == 'password'"
|
||||
class="absolute top-0 bottom-0 right-0 mx-3 my-auto cursor-pointer h-fit">
|
||||
<svg width="20" height="20" viewBox="0 0 20 20"
|
||||
|
4
src/components/Navigation/Aside/Aside.vue
Normal file → Executable file
@ -35,7 +35,7 @@ const closeSideBar = () => menu.toggleSidebar()
|
||||
|
||||
<template>
|
||||
<TransitionRoot as="template" :show="menu.sidebarOpen">
|
||||
<Dialog as="div" class="relative z-40 md:hidden" @close="closeSideBar">
|
||||
<Dialog as="div" class="relative z-40 lg:hidden" @close="closeSideBar">
|
||||
<TransitionChild as="template" enter="transition-opacity ease-linear duration-300" enter-from="opacity-0"
|
||||
enter-to="opacity-100" leave="transition-opacity ease-linear duration-300" leave-from="opacity-100"
|
||||
leave-to="opacity-0">
|
||||
@ -86,7 +86,7 @@ const closeSideBar = () => menu.toggleSidebar()
|
||||
</Dialog>
|
||||
</TransitionRoot>
|
||||
<!-- Static sidebar for desktop -->
|
||||
<div class="z-10 hidden md:fixed md:inset-y-0 md:flex md:w-80 md:flex-col">
|
||||
<div class="z-10 hidden lg:fixed lg:inset-y-0 lg:flex lg:w-80 lg:flex-col">
|
||||
<!-- Sidebar component, swap this element with another sidebar if you like -->
|
||||
<div class="flex flex-row items-center flex-shrink-0 h-16 px-2 bg-primary-50">
|
||||
<button type="button"
|
||||
|
2
src/components/Navigation/Aside/AsideMenuMultiple.vue
Normal file → Executable file
@ -43,7 +43,7 @@ const isMenuSelected = computed(() => {
|
||||
:class="[(isMenuSelected || item.expanded || isChildren || selected) ? ' fill-primary-500' : 'text-aside group-hover:fill-primary-500', 'mr-2 flex-shrink-0 h-6 w-6']"
|
||||
aria-hidden="true" />
|
||||
<span
|
||||
:class="[(isMenuSelected || item.expanded || selected) ? 'text-primary-500' : 'group-hover:text-primary-500', 'flex-1']">
|
||||
:class="[(isMenuSelected || item.expanded || selected) ? 'text-primary-500' : 'group-hover:text-primary-500', 'flex-1 aside-text']">
|
||||
{{ item.name }}
|
||||
</span>
|
||||
|
||||
|
0
src/components/Navigation/Aside/AsideMenuSingle.vue
Normal file → Executable file
29
src/components/Navigation/Header.vue
Normal file → Executable file
@ -1,15 +1,9 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { useCommandPalattesStore } from '@/stores/command'
|
||||
import { useMenuStore } from '@/stores/menu'
|
||||
import {
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuItem,
|
||||
MenuItems,
|
||||
} from '@headlessui/vue'
|
||||
import { Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue'
|
||||
import { MagnifyingGlassIcon } from '@heroicons/vue/24/solid'
|
||||
import PictureInitial from '@/components/PictureInitial.vue'
|
||||
import { useDialogStore } from '@/stores/dialog'
|
||||
@ -39,14 +33,13 @@ const showDialogLogout = () => {
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="sticky top-0 z-10 flex flex-shrink-0 h-16 bg-primary-50 md:ml-80">
|
||||
<button type="button" class="px-4 text-gray-500 focus:outline-none focus:ring-0 md:hidden" @click="openSideBar">
|
||||
<div class="sticky top-0 z-10 flex flex-shrink-0 h-16 bg-primary-50 lg:ml-80">
|
||||
<button type="button" class="px-4 text-gray-500 focus:outline-none focus:ring-0 lg:hidden" @click="openSideBar">
|
||||
<span class="sr-only">Open sidebar</span>
|
||||
<IconBars3 class="w-6 h-6 fill-gray-600" />
|
||||
</button>
|
||||
<RouterLink to="/home" class="flex items-center flex-shrink-0 my-auto ml-2 md:hidden">
|
||||
<RouterLink to="/home" class="flex items-center flex-shrink-0 my-auto ml-2 lg:hidden">
|
||||
<img class="w-auto h-11" :src="IconApp" alt="PLN" />
|
||||
</RouterLink>
|
||||
<div class="flex justify-end w-full px-4">
|
||||
@ -73,17 +66,14 @@ const showDialogLogout = () => {
|
||||
</div>
|
||||
<transition enter-active-class="transition duration-100 ease-out"
|
||||
enter-from-class="transform scale-95 opacity-0" enter-to-class="transform scale-100 opacity-100"
|
||||
leave-active-class="transition duration-75 ease-in"
|
||||
leave-from-class="transform scale-100 opacity-100" leave-to-class="transform scale-95 opacity-0">
|
||||
|
||||
leave-active-class="transition duration-75 ease-in" leave-from-class="transform scale-100 opacity-100"
|
||||
leave-to-class="transform scale-95 opacity-0">
|
||||
<MenuItems class="container-menu-item">
|
||||
<div class="container-menu-profile group">
|
||||
<div class="flex items-center">
|
||||
<div>
|
||||
<PictureInitial class-name="inline-block" size-class="w-9 h-9"
|
||||
background-class="bg-secondary-100"
|
||||
font-class="text-xs font-normal font-semibold text-primary-500"
|
||||
:name="user.user_name" />
|
||||
<PictureInitial class-name="inline-block" size-class="w-9 h-9" background-class="bg-secondary-100"
|
||||
font-class="text-xs font-normal font-semibold text-primary-500" :name="user.user_name" />
|
||||
</div>
|
||||
<div class="ml-3 space-y-1">
|
||||
<p class="text-sm font-medium text-primary-50">
|
||||
@ -92,6 +82,9 @@ const showDialogLogout = () => {
|
||||
<p class="text-xs font-normal text-primary-50">
|
||||
{{ user.user_access }}
|
||||
</p>
|
||||
<p class="text-xs font-normal border-t border-white text-primary-50">
|
||||
• UID {{ user.user_uid }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
0
src/components/Navigation/Navigation.vue
Normal file → Executable file
0
src/components/Notification/Notification.vue
Normal file → Executable file
0
src/components/Notification/NotificationProvider.vue
Normal file → Executable file
0
src/components/Notification/icons/CloseIcon.vue
Normal file → Executable file
0
src/components/Notification/icons/ErrorIcon.vue
Normal file → Executable file
0
src/components/Notification/icons/InfoIcon.vue
Normal file → Executable file
0
src/components/Notification/icons/SuccessIcon.vue
Normal file → Executable file
0
src/components/Notification/icons/WarningIcon.vue
Normal file → Executable file
0
src/components/Notification/icons/index.ts
Normal file → Executable file
0
src/components/Notification/index.ts
Normal file → Executable file
0
src/components/Notification/interfaces/Notification.interface.ts
Normal file → Executable file
0
src/components/Notification/interfaces/NotificationConfig.interface.ts
Normal file → Executable file
0
src/components/Notification/interfaces/NotificationsState.interface.ts
Normal file → Executable file
0
src/components/Notification/interfaces/index.ts
Normal file → Executable file
0
src/components/Notification/store/index.ts
Normal file → Executable file
18324
src/components/Pages/Anomali/Gangguan/Anomali_LAPPGP.vue
Normal file
240
src/components/Pages/Anomali/Gangguan/Anomali_LAPPGP_LPP.vue
Executable file
@ -0,0 +1,240 @@
|
||||
<template>
|
||||
<div class="mt-4 lg:mt-6 max-w-7xl">
|
||||
<h1 class="text-xl font-medium md:text-2xl text-dark">Laporan Pengaduan PLN Mobile</h1>
|
||||
</div>
|
||||
<DxDataGrid
|
||||
class="max-h-[calc(100vh-140px)] mb-10"
|
||||
:data-source="data"
|
||||
:show-column-lines="true"
|
||||
:show-row-lines="false"
|
||||
:show-borders="true"
|
||||
:row-alternation-enabled="true"
|
||||
:hover-state-enabled="true"
|
||||
@selection-changed="onDataSelectionChanged"
|
||||
@exporting="onExporting"
|
||||
:allow-column-resizing="true"
|
||||
column-resizing-mode="widget"
|
||||
:word-wrap-enabled="true"
|
||||
>
|
||||
<DxSelection mode="single" />
|
||||
<DxPaging :enabled="false" />
|
||||
<DxScrolling column-rendering-mode="virtual" mode="virtual" />
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" />
|
||||
<DxExport
|
||||
:enabled="true"
|
||||
:formats="['pdf', 'xlsx', 'document']"
|
||||
:allow-export-selected-data="false"
|
||||
/>
|
||||
<DxColumnFixing :enabled="true" />
|
||||
|
||||
<DxColumn
|
||||
alignment="center"
|
||||
data-field="nama_ulp"
|
||||
caption="Nama Unit"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatText"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="170"
|
||||
alignment="center"
|
||||
data-field=""
|
||||
caption="Nama Petugas"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatText"
|
||||
/>
|
||||
<DxColumn alignment="center" caption="Total WO" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
alignment="center"
|
||||
caption="(PLN Mobile, CC123, DLL)"
|
||||
css-class="custom-table-column"
|
||||
>
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field=""
|
||||
data-type="number"
|
||||
caption="a"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
<DxColumn
|
||||
alignment="center"
|
||||
caption="Total Pengaduan Yang Diselesaikan Secara Anomali"
|
||||
css-class="custom-table-column"
|
||||
>
|
||||
<DxColumn alignment="center" caption="PLN Mobile" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="anomali_pln_mobile_marking"
|
||||
data-type="number"
|
||||
caption="b"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="CC 123" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="anomali_cc123_marking"
|
||||
data-type="number"
|
||||
caption="c"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Total" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="total_anomali_marking"
|
||||
data-type="number"
|
||||
caption="d=b+c"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
<DxColumn
|
||||
alignment="center"
|
||||
caption="% Pengaduan Yang Diselesaikan Secara Anomali"
|
||||
css-class="custom-table-column"
|
||||
>
|
||||
<DxColumn alignment="center" caption="PLN Mobile" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_pln_mobile_marking"
|
||||
data-type="number"
|
||||
caption="e=b/a"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="CC 123" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_cc123_marking"
|
||||
data-type="number"
|
||||
caption="f=c/a"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Total" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_marking"
|
||||
data-type="number"
|
||||
caption="g=e+f"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
|
||||
<template #formatNumber="{ data }">
|
||||
<p class="text-right cursor-pointer" @click="showData()">
|
||||
{{
|
||||
isNumber(data.text)
|
||||
? data.column.caption == '%'
|
||||
? formatPercentage(data.text)
|
||||
: formatNumber(data.text)
|
||||
: data.text
|
||||
}}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template #formatPercentage="{ data }">
|
||||
<p class="text-right cursor-pointer" @click="showData()">
|
||||
{{ isNumber(data.text) ? formatPercentage(data.text) : data.text }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template #formatText="{ data }">
|
||||
<p class="text-left cursor-pointer" @click="showData()">
|
||||
{{ data.text }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template #formatTime="{ data }" @click="showData()">
|
||||
<p class="!text-right">
|
||||
{{ parseInt(data.text) ? formatWaktu(data.text) : '-' }}
|
||||
</p>
|
||||
</template>
|
||||
</DxDataGrid>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DxDataGrid } from 'devextreme-vue'
|
||||
import {
|
||||
DxColumn,
|
||||
DxColumnFixing,
|
||||
DxExport,
|
||||
DxPaging,
|
||||
DxScrolling,
|
||||
DxSearchPanel,
|
||||
DxSelection
|
||||
} from 'devextreme-vue/data-grid'
|
||||
import { jsPDF } from 'jspdf'
|
||||
import { exportDataGrid as exportToPdf } from 'devextreme/pdf_exporter'
|
||||
import { exportDataGrid as exportToExcel } from 'devextreme/excel_exporter'
|
||||
import { saveAs } from 'file-saver'
|
||||
import { Workbook } from 'exceljs'
|
||||
import { computed, ref } from 'vue'
|
||||
import { formatNumber, formatPercentage, isNumber } from '@/utils/numbers'
|
||||
import { formatWaktu } from '@/components/Form/FiltersType/reference'
|
||||
const props = defineProps({
|
||||
data: Array as () => any[]
|
||||
})
|
||||
const data = computed(() => props.data)
|
||||
const dataSub = ref([])
|
||||
const dataSelected = ref({})
|
||||
const dataSubSelected = ref({})
|
||||
const showDetail = ref(false)
|
||||
const showData = () => {
|
||||
showDetail.value = true
|
||||
}
|
||||
const closeDetail = () => {
|
||||
showDetail.value = false
|
||||
}
|
||||
|
||||
const onExporting = (e: any) => {
|
||||
if (e.format === 'pdf') {
|
||||
const doc = new jsPDF()
|
||||
|
||||
exportToPdf({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5
|
||||
}).then(() => {
|
||||
doc.save(`.pdf`)
|
||||
})
|
||||
} else {
|
||||
const workbook = new Workbook()
|
||||
const worksheet = workbook.addWorksheet('Employees')
|
||||
|
||||
exportToExcel({
|
||||
component: e.component,
|
||||
worksheet,
|
||||
autoFilterEnabled: true
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer: any) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx')
|
||||
})
|
||||
})
|
||||
|
||||
e.cancel = true
|
||||
}
|
||||
}
|
||||
|
||||
const onDataSelectionChanged = ({ selectedRowsData }: any) => {
|
||||
const dataSelected = selectedRowsData[0]
|
||||
console.log(data)
|
||||
}
|
||||
</script>
|
432
src/components/Pages/Anomali/Gangguan/Anomali_LAPPGP_LPT.vue
Executable file
@ -0,0 +1,432 @@
|
||||
<template>
|
||||
<div class="mt-4 lg:mt-6 max-w-7xl">
|
||||
<h1 class="text-xl font-medium md:text-2xl text-dark">Laporan Pengaduan Total</h1>
|
||||
</div>
|
||||
<DxDataGrid
|
||||
class="max-h-[calc(100vh-140px)] mb-10"
|
||||
:show-column-lines="true"
|
||||
:show-row-lines="false"
|
||||
:show-borders="true"
|
||||
:row-alternation-enabled="true"
|
||||
:hover-state-enabled="true"
|
||||
@selection-changed="onDataSelectionChanged"
|
||||
:column-width="100"
|
||||
@exporting="onExporting"
|
||||
:allow-column-resizing="true"
|
||||
column-resizing-mode="widget"
|
||||
:word-wrap-enabled="true"
|
||||
:data-source="data"
|
||||
>
|
||||
<DxSelection mode="single" />
|
||||
<DxPaging :enabled="false" />
|
||||
<DxScrolling column-rendering-mode="virtual" mode="virtual" />
|
||||
<DxLoadPanel
|
||||
:position="position"
|
||||
:show-indicator="showIndicator"
|
||||
:show-pane="showPane"
|
||||
:shading="shading"
|
||||
v-if="loading"
|
||||
v-model:visible="loading"
|
||||
:enabled="true"
|
||||
/>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" />
|
||||
<DxExport
|
||||
:enabled="true"
|
||||
:formats="['pdf', 'xlsx', 'document']"
|
||||
:allow-export-selected-data="false"
|
||||
/>
|
||||
<DxColumnFixing :enabled="true" />
|
||||
|
||||
<DxColumn
|
||||
:width="170"
|
||||
alignment="center"
|
||||
data-field="nama_ulp"
|
||||
caption="Nama Unit"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatText"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="170"
|
||||
alignment="center"
|
||||
data-field="nama_ulp"
|
||||
caption="Nama Unit"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatText"
|
||||
name="namaUnit"
|
||||
:group-index="0"
|
||||
/>
|
||||
<DxColumn alignment="center" caption="Total Petugas" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="170"
|
||||
alignment="center"
|
||||
data-field="total_petugas"
|
||||
caption="a"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
<DxColumn
|
||||
alignment="center"
|
||||
caption="Total Petugas Yang Pengaduan Diselesaikan Secara Anomali"
|
||||
css-class="custom-table-column"
|
||||
>
|
||||
<DxColumn alignment="center" caption="PLN Mobile" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="b" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="anomali_pln_mobile_marking"
|
||||
data-type="number"
|
||||
caption="Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="anomali_pln_mobile_non_marking"
|
||||
data-type="number"
|
||||
caption="Non Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="CC 123" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="c" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="anomali_cc123_marking"
|
||||
data-type="number"
|
||||
caption="Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="anomali_cc123_non_marking"
|
||||
data-type="number"
|
||||
caption="Non Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Total" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="d=b+c" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="total_anomali_marking"
|
||||
data-type="number"
|
||||
caption="Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="total_anomali_non_marking"
|
||||
data-type="number"
|
||||
caption="Non Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
<DxColumn
|
||||
alignment="center"
|
||||
caption="% Petugas Yang Pengaduan Diselesaikan Secara Anomali"
|
||||
css-class="custom-table-column"
|
||||
>
|
||||
<DxColumn alignment="center" caption="PLN Mobile" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="e=b/a" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_pln_mobile_marking"
|
||||
data-type="number"
|
||||
caption="Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_pln_mobile_non_marking"
|
||||
data-type="number"
|
||||
caption="Non Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="CC 123" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="f=c/a" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_cc123_marking"
|
||||
data-type="number"
|
||||
caption="Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_cc123_non_marking"
|
||||
data-type="number"
|
||||
caption="Non Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Total" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="g=e+f" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_marking"
|
||||
data-type="number"
|
||||
caption="Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_non_marking"
|
||||
data-type="number"
|
||||
caption="Non Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
|
||||
<template #formatNumber="{ data }">
|
||||
<p class="text-right cursor-pointer" @click="showData()">
|
||||
{{
|
||||
isNumber(data.text)
|
||||
? data.column.caption == '%'
|
||||
? formatPercentage(data.text)
|
||||
: formatNumber(data.text)
|
||||
: data.text
|
||||
}}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template #formatPercentage="{ data }">
|
||||
<p class="text-right cursor-pointer" @click="showData()">
|
||||
{{ isNumber(data.text) ? formatPercentage(data.text) : data.text }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template #formatText="{ data }">
|
||||
<p class="text-left cursor-pointer" @click="showData()">
|
||||
{{ data.text }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template #formatTime="{ data }" @click="showData()">
|
||||
<p class="!text-right">
|
||||
{{ parseInt(data.text) ? formatWaktu(data.text) : '-' }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<DxSummary>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="total_petugas"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="anomali_pln_mobile_marking"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="anomali_pln_mobile_non_marking"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="anomali_cc123_marking"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="anomali_cc123_non_marking"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="total_anomali_marking"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="total_anomali_non_marking"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="persen_anomali_pln_mobile_marking"
|
||||
summary-type="avg"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatPercentage(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="persen_anomali_pln_mobile_non_marking"
|
||||
summary-type="avg"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatPercentage(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="persen_anomali_cc123_marking"
|
||||
summary-type="avg"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatPercentage(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="persen_anomali_cc123_non_marking"
|
||||
summary-type="avg"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatPercentage(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="persen_anomali_marking"
|
||||
summary-type="avg"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatPercentage(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="persen_anomali_non_marking"
|
||||
summary-type="avg"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatPercentage(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
</DxSummary>
|
||||
</DxDataGrid>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { DxDataGrid } from 'devextreme-vue'
|
||||
import {
|
||||
DxColumn,
|
||||
DxColumnFixing,
|
||||
DxExport,
|
||||
DxGroupItem,
|
||||
DxLoadPanel,
|
||||
DxPaging,
|
||||
DxScrolling,
|
||||
DxSearchPanel,
|
||||
DxSelection,
|
||||
DxSummary
|
||||
} from 'devextreme-vue/data-grid'
|
||||
import { jsPDF } from 'jspdf'
|
||||
import { exportDataGrid as exportToPdf } from 'devextreme/pdf_exporter'
|
||||
import { exportDataGrid as exportToExcel } from 'devextreme/excel_exporter'
|
||||
import { saveAs } from 'file-saver'
|
||||
import { Workbook } from 'exceljs'
|
||||
import { formatNumber, formatPercentage, isNumber } from '@/utils/numbers'
|
||||
import { formatWaktu } from '@/components/Form/FiltersType/reference'
|
||||
|
||||
const position = { of: '#data' }
|
||||
const showIndicator = ref(true)
|
||||
const shading = ref(true)
|
||||
const showPane = ref(true)
|
||||
const props = defineProps({
|
||||
data: Array as () => any[],
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
const data = computed(() => props.data)
|
||||
const dataSub = ref<any[]>([])
|
||||
const dataSelected = ref<any>({})
|
||||
const dataSubSelected = ref<any>({})
|
||||
const showDetail = ref(false)
|
||||
const showData = () => {
|
||||
showDetail.value = true
|
||||
}
|
||||
const closeDetail = () => {
|
||||
showDetail.value = false
|
||||
}
|
||||
const loading = ref(computed(() => props.loading))
|
||||
|
||||
const onExporting = (e: any) => {
|
||||
if (e.format === 'pdf') {
|
||||
const doc = new jsPDF()
|
||||
|
||||
exportToPdf({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5
|
||||
}).then(() => {
|
||||
doc.save(`.pdf`)
|
||||
})
|
||||
} else {
|
||||
const workbook = new Workbook()
|
||||
const worksheet = workbook.addWorksheet('Employees')
|
||||
|
||||
exportToExcel({
|
||||
component: e.component,
|
||||
worksheet,
|
||||
autoFilterEnabled: true
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer: any) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx')
|
||||
})
|
||||
})
|
||||
|
||||
e.cancel = true
|
||||
}
|
||||
}
|
||||
|
||||
const onDataSelectionChanged = ({ selectedRowsData }: any) => {
|
||||
dataSelected.value = selectedRowsData[0]
|
||||
console.log(data)
|
||||
}
|
||||
</script>
|
21771
src/components/Pages/Anomali/Gangguan/Anomali_LAPPGU.vue
Normal file
178
src/components/Pages/Anomali/Gangguan/Anomali_LAPPGU_LPP.vue
Executable file
@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div class="mt-4 lg:mt-6 max-w-7xl">
|
||||
<h1 class="text-xl font-medium md:text-2xl text-dark">Laporan Pengaduan PLN Mobile</h1>
|
||||
</div>
|
||||
<DxDataGrid
|
||||
class="max-h-[calc(100vh-140px)] mb-10"
|
||||
:data-source="data"
|
||||
:show-column-lines="true"
|
||||
:show-row-lines="false"
|
||||
:show-borders="true"
|
||||
:row-alternation-enabled="true"
|
||||
:hover-state-enabled="true"
|
||||
@selection-changed="onDataSelectionChanged"
|
||||
@exporting="onExporting"
|
||||
:allow-column-resizing="true"
|
||||
column-resizing-mode="widget"
|
||||
:word-wrap-enabled="true"
|
||||
>
|
||||
<DxSelection mode="single" />
|
||||
<DxPaging :enabled="false" />
|
||||
<DxScrolling column-rendering-mode="virtual" mode="virtual" />
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" />
|
||||
<DxExport
|
||||
:enabled="true"
|
||||
:formats="['pdf', 'xlsx', 'document']"
|
||||
:allow-export-selected-data="false"
|
||||
/>
|
||||
<DxColumnFixing :enabled="true" />
|
||||
|
||||
<DxColumn
|
||||
alignment="center"
|
||||
data-field="nama_ulp"
|
||||
caption="Nama Unit"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatText"
|
||||
/>
|
||||
<DxColumn alignment="center" caption="Total WO PLN Mobile" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="170"
|
||||
alignment="center"
|
||||
data-field="wo_total"
|
||||
data-type="number"
|
||||
caption="a"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
<DxColumn
|
||||
alignment="center"
|
||||
caption="Total Pengaduan Yang Diselesaikan Secara Anomali"
|
||||
css-class="custom-table-column"
|
||||
>
|
||||
<DxColumn
|
||||
:width="170"
|
||||
alignment="center"
|
||||
data-field="total_anomali_marking"
|
||||
data-type="number"
|
||||
caption="b"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
<DxColumn
|
||||
alignment="center"
|
||||
caption="% Pengaduan Yang Diselesaikan Secara Anomali"
|
||||
css-class="custom-table-column"
|
||||
>
|
||||
<DxColumn
|
||||
:width="170"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_marking"
|
||||
data-type="number"
|
||||
caption="c=b/a"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
</DxColumn>
|
||||
|
||||
<template #formatNumber="{ data }">
|
||||
<p class="text-right cursor-pointer" @click="showData()">
|
||||
{{
|
||||
isNumber(data.text)
|
||||
? data.column.caption == '%'
|
||||
? formatPercentage(data.text)
|
||||
: formatNumber(data.text)
|
||||
: data.text
|
||||
}}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template #formatPercentage="{ data }">
|
||||
<p class="text-right cursor-pointer" @click="showData()">
|
||||
{{ isNumber(data.text) ? formatPercentage(data.text) : data.text }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template #formatText="{ data }">
|
||||
<p class="text-left cursor-pointer" @click="showData()">
|
||||
{{ data.text }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template #formatTime="{ data }" @click="showData()">
|
||||
<p class="!text-right">
|
||||
{{ parseInt(data.text) ? formatWaktu(data.text) : '-' }}
|
||||
</p>
|
||||
</template>
|
||||
</DxDataGrid>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DxDataGrid } from 'devextreme-vue'
|
||||
import {
|
||||
DxColumn,
|
||||
DxColumnFixing,
|
||||
DxExport,
|
||||
DxPaging,
|
||||
DxScrolling,
|
||||
DxSearchPanel,
|
||||
DxSelection
|
||||
} from 'devextreme-vue/data-grid'
|
||||
import { jsPDF } from 'jspdf'
|
||||
import { exportDataGrid as exportToPdf } from 'devextreme/pdf_exporter'
|
||||
import { exportDataGrid as exportToExcel } from 'devextreme/excel_exporter'
|
||||
import { saveAs } from 'file-saver'
|
||||
import { Workbook } from 'exceljs'
|
||||
import { computed, ref } from 'vue'
|
||||
import { formatNumber, formatPercentage, isNumber } from '@/utils/numbers'
|
||||
import { formatWaktu } from '@/components/Form/FiltersType/reference'
|
||||
const props = defineProps({
|
||||
data: Array as () => any[]
|
||||
})
|
||||
const data = computed(() => props.data)
|
||||
const dataSub = ref<any[]>([])
|
||||
const dataSelected = ref<any>({})
|
||||
const dataSubSelected = ref<any>({})
|
||||
const showDetail = ref(false)
|
||||
const showData = () => {
|
||||
showDetail.value = true
|
||||
}
|
||||
const closeDetail = () => {
|
||||
showDetail.value = false
|
||||
}
|
||||
|
||||
const onExporting = (e: any) => {
|
||||
if (e.format === 'pdf') {
|
||||
const doc = new jsPDF()
|
||||
|
||||
exportToPdf({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5
|
||||
}).then(() => {
|
||||
doc.save(`.pdf`)
|
||||
})
|
||||
} else {
|
||||
const workbook = new Workbook()
|
||||
const worksheet = workbook.addWorksheet('Employees')
|
||||
|
||||
exportToExcel({
|
||||
component: e.component,
|
||||
worksheet,
|
||||
autoFilterEnabled: true
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer: any) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx')
|
||||
})
|
||||
})
|
||||
|
||||
e.cancel = true
|
||||
}
|
||||
}
|
||||
|
||||
const onDataSelectionChanged = ({ selectedRowsData }: any) => {
|
||||
const dataSelected = selectedRowsData[0]
|
||||
console.log(data)
|
||||
}
|
||||
</script>
|
507
src/components/Pages/Anomali/Gangguan/Anomali_LAPPGU_LPT.vue
Executable file
@ -0,0 +1,507 @@
|
||||
<template>
|
||||
<div class="mt-4 lg:mt-6 max-w-7xl">
|
||||
<h1 class="text-xl font-medium md:text-2xl text-dark">Laporan Pengaduan Total</h1>
|
||||
</div>
|
||||
<DxDataGrid
|
||||
class="max-h-[calc(100vh-140px)] mb-10"
|
||||
:data-source="data"
|
||||
:show-column-lines="true"
|
||||
:show-row-lines="false"
|
||||
:show-borders="true"
|
||||
:row-alternation-enabled="true"
|
||||
:hover-state-enabled="true"
|
||||
@selection-changed="onDataSelectionChanged"
|
||||
:column-width="100"
|
||||
@exporting="onExporting"
|
||||
:allow-column-resizing="true"
|
||||
column-resizing-mode="widget"
|
||||
:word-wrap-enabled="true"
|
||||
>
|
||||
<DxSelection mode="single" />
|
||||
<DxPaging :enabled="false" />
|
||||
<DxScrolling column-rendering-mode="virtual" mode="virtual" />
|
||||
<DxLoadPanel
|
||||
:position="position"
|
||||
:show-indicator="showIndicator"
|
||||
:show-pane="showPane"
|
||||
:shading="shading"
|
||||
v-if="loading"
|
||||
v-model:visible="loading"
|
||||
:enabled="true"
|
||||
/>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" />
|
||||
<DxExport
|
||||
:enabled="true"
|
||||
:formats="['pdf', 'xlsx', 'document']"
|
||||
:allow-export-selected-data="false"
|
||||
/>
|
||||
<DxColumnFixing :enabled="true" />
|
||||
|
||||
<DxColumn
|
||||
:width="170"
|
||||
alignment="center"
|
||||
data-field="nama_ulp"
|
||||
caption="Nama Unit"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatText"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="170"
|
||||
alignment="center"
|
||||
data-field="nama_ulp"
|
||||
caption="Nama Unit"
|
||||
name="namaUnit"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatText"
|
||||
:group-index="0"
|
||||
/>
|
||||
<DxColumn alignment="center" caption="Total WO" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="CC 123" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="wo_cc123"
|
||||
data-type="number"
|
||||
caption="a"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="PLN Mobile" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="wo_pln_mobile"
|
||||
data-type="number"
|
||||
caption="b"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Loket" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="wo_loket"
|
||||
data-type="number"
|
||||
caption="c"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Lainnya" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="wo_lainnya"
|
||||
data-type="number"
|
||||
caption="d"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Total" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="wo_total"
|
||||
data-type="number"
|
||||
caption="e=a+b+c+d"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
<DxColumn
|
||||
alignment="center"
|
||||
caption="Total Pengaduan Yang Diselesaikan Secara Anomali"
|
||||
css-class="custom-table-column"
|
||||
>
|
||||
<DxColumn alignment="center" caption="PLN Mobile" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="f" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="anomali_pln_mobile_marking"
|
||||
data-type="number"
|
||||
caption="Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="anomali_pln_mobile_non_marking"
|
||||
data-type="number"
|
||||
caption="Non Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="CC 123" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="g" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="anomali_cc123_marking"
|
||||
data-type="number"
|
||||
caption="Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="anomali_cc123_non_marking"
|
||||
data-type="number"
|
||||
caption="Non Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Total" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="h=f+g" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="total_anomali_marking"
|
||||
data-type="number"
|
||||
caption="Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="total_anomali_non_marking"
|
||||
data-type="number"
|
||||
caption="Non Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatNumber"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
|
||||
<DxColumn
|
||||
alignment="center"
|
||||
caption="% Pengaduan Yang Diselesaikan Secara Anomali"
|
||||
css-class="custom-table-column"
|
||||
>
|
||||
<DxColumn alignment="center" caption="PLN Mobile" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="i=f/e" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_pln_mobile_marking"
|
||||
data-type="number"
|
||||
caption="Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_pln_mobile_non_marking"
|
||||
data-type="number"
|
||||
caption="Non Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="CC 123" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="j=g/e" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_cc123_marking"
|
||||
data-type="number"
|
||||
caption="Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_cc123_non_marking"
|
||||
data-type="number"
|
||||
caption="Non Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Total" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="k=i+j" css-class="custom-table-column">
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_marking"
|
||||
data-type="number"
|
||||
caption="Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
<DxColumn
|
||||
:width="150"
|
||||
alignment="center"
|
||||
data-field="persen_anomali_non_marking"
|
||||
data-type="number"
|
||||
caption="Non Marking"
|
||||
css-class="custom-table-column"
|
||||
cell-template="formatPercentage"
|
||||
/>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
|
||||
<template #formatNumber="{ data }">
|
||||
<p class="text-right cursor-pointer" @click="showData()">
|
||||
{{
|
||||
isNumber(data.text)
|
||||
? data.column.caption == '%'
|
||||
? formatPercentage(data.text)
|
||||
: formatNumber(data.text)
|
||||
: data.text
|
||||
}}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template #formatPercentage="{ data }">
|
||||
<p class="text-right cursor-pointer" @click="showData()">
|
||||
{{ isNumber(data.text) ? formatPercentage(data.text) : data.text }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template #formatText="{ data }">
|
||||
<p class="text-left cursor-pointer" @click="showData()">
|
||||
{{ data.text }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<template #formatTime="{ data }" @click="showData()">
|
||||
<p class="!text-right">
|
||||
{{ parseInt(data.text) ? formatWaktu(data.text) : '-' }}
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<DxSummary>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="wo_cc123"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="wo_pln_mobile"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="wo_loket"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="wo_lainnya"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="wo_total"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="anomali_pln_mobile_marking"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="anomali_pln_mobile_non_marking"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="anomali_cc123_marking"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="anomali_cc123_non_marking"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="total_anomali_marking"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="total_anomali_non_marking"
|
||||
summary-type="sum"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatNumber(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="persen_anomali_pln_mobile_marking"
|
||||
summary-type="avg"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatPercentage(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="persen_anomali_pln_mobile_non_marking"
|
||||
summary-type="avg"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatPercentage(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="persen_anomali_cc123_marking"
|
||||
summary-type="avg"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatPercentage(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="persen_anomali_cc123_non_marking"
|
||||
summary-type="avg"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatPercentage(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="persen_anomali_marking"
|
||||
summary-type="avg"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatPercentage(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
<DxGroupItem
|
||||
:show-in-group-footer="false"
|
||||
:align-by-column="true"
|
||||
column="persen_anomali_non_marking"
|
||||
summary-type="avg"
|
||||
css-class="!text-right"
|
||||
:customize-text="(e: any) => formatPercentage(parseFloat(e.value.toString()))"
|
||||
/>
|
||||
</DxSummary>
|
||||
</DxDataGrid>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { DxDataGrid } from 'devextreme-vue'
|
||||
import {
|
||||
DxColumn,
|
||||
DxColumnFixing,
|
||||
DxExport,
|
||||
DxGroupItem,
|
||||
DxLoadPanel,
|
||||
DxPaging,
|
||||
DxScrolling,
|
||||
DxSearchPanel,
|
||||
DxSelection,
|
||||
DxSummary
|
||||
} from 'devextreme-vue/data-grid'
|
||||
import { jsPDF } from 'jspdf'
|
||||
import { exportDataGrid as exportToPdf } from 'devextreme/pdf_exporter'
|
||||
import { exportDataGrid as exportToExcel } from 'devextreme/excel_exporter'
|
||||
import { saveAs } from 'file-saver'
|
||||
import { Workbook } from 'exceljs'
|
||||
import { formatWaktu } from '@/components/Form/FiltersType/reference'
|
||||
import { formatNumber, formatPercentage, isNumber } from '@/utils/numbers'
|
||||
const position = { of: '#data' }
|
||||
const showIndicator = ref(true)
|
||||
const loading = ref(computed(() => props.loading))
|
||||
const shading = ref(true)
|
||||
const showPane = ref(true)
|
||||
const props = defineProps({
|
||||
data: Array as () => any[],
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
const showDialog = ref(false)
|
||||
const data = computed(() => props.data)
|
||||
const dataSelected = ref()
|
||||
const dataSub = ref([])
|
||||
const dataSubSelected = ref()
|
||||
const showDetail = ref(false)
|
||||
const showData = () => (showDetail.value = true)
|
||||
const closeDetail = () => (showDetail.value = false)
|
||||
const onExporting = (e: any) => {
|
||||
if (e.format === 'pdf') {
|
||||
const doc = new jsPDF()
|
||||
|
||||
exportToPdf({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5
|
||||
}).then(() => {
|
||||
doc.save(`.pdf`)
|
||||
})
|
||||
} else {
|
||||
const workbook = new Workbook()
|
||||
const worksheet = workbook.addWorksheet('Employees')
|
||||
|
||||
exportToExcel({
|
||||
component: e.component,
|
||||
worksheet,
|
||||
autoFilterEnabled: true
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer: any) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx')
|
||||
})
|
||||
})
|
||||
|
||||
e.cancel = true
|
||||
}
|
||||
}
|
||||
|
||||
const onDataSelectionChanged = ({ selectedRowsData }: any) => {
|
||||
const dataSelected = selectedRowsData[0]
|
||||
console.log(data)
|
||||
}
|
||||
</script>
|
79
src/components/Pages/Anomali/Keluhan/Anomali_LAPPKU.vue
Executable file
@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<Filters @run-search="() => filterData(filters)" class="mb-4">
|
||||
<Type4 @update:filters="(value) => filters = value" />
|
||||
</Filters>
|
||||
|
||||
<Anomali_LAPPKU_LPT :data="data" />
|
||||
<Anomali_LAPPKU_LPP :data="data" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Filters from '@/components/Form/Filters.vue'
|
||||
import { ref } from 'vue'
|
||||
import { Anomali_LAPPKU_LPT, Anomali_LAPPKU_LPP } from '../.'
|
||||
import { Type4 } from '@/components/Form/FiltersType'
|
||||
import { useQuery } from '@vue/apollo-composable'
|
||||
import gql from 'graphql-tag'
|
||||
const data = ref<any[]>([])
|
||||
|
||||
const GET_laporanCheckInCheckOut = gql`
|
||||
query laporanCheckInCheckOut($dateFrom: Date!, $dateTo: Date!, $posko: String, $idUid: Int, $idUp3: Int) {
|
||||
laporanCheckInCheckOut(
|
||||
dateFrom: $dateFrom
|
||||
dateTo: $dateTo
|
||||
posko: $posko
|
||||
idUid: $idUid
|
||||
idUp3: $idUp3
|
||||
) {
|
||||
avg_durasi_wo_gangguan_individual
|
||||
avg_durasi_wo_penugasan_khusus
|
||||
avg_rct_wo_gangguan_individual
|
||||
avg_rpt_wo_gangguan_individual
|
||||
jumlah_wo_gangguan_individual
|
||||
jumlah_wo_penugasan_khusus
|
||||
personil_yantek
|
||||
user_regu
|
||||
}
|
||||
}
|
||||
`
|
||||
const filterData = (params: any) => {
|
||||
const { posko, uid, up3 } = params
|
||||
const dateValue = params.periode.split(' s/d ')
|
||||
refetch({
|
||||
dateFrom: dateValue[0] ? dateValue[0].split('-').reverse().join('-') : new Date().toISOString().slice(0, 10),
|
||||
dateTo: dateValue[1] ? dateValue[1].split('-').reverse().join('-') : new Date().toISOString().slice(0, 10),
|
||||
posko: posko ? posko.id : "",
|
||||
idUid: uid ? uid.id : 0,
|
||||
idUp3: up3 ? up3.id : 0
|
||||
})
|
||||
onResult((queryResult) => {
|
||||
if (queryResult.data != undefined) {
|
||||
queryResult.data.daftarGangguanDialihkanKePoskoLain.forEach((item: any) => {
|
||||
data.value = [
|
||||
...data.value,
|
||||
{
|
||||
...item,
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
console.log(queryResult.data)
|
||||
console.log(queryResult.loading)
|
||||
console.log(queryResult.networkStatus)
|
||||
})
|
||||
onError((error) => {
|
||||
console.log(error)
|
||||
})
|
||||
}
|
||||
const { onResult, onError, loading, refetch } = useQuery(
|
||||
GET_laporanCheckInCheckOut,
|
||||
{
|
||||
dateFrom: new Date().toISOString().slice(0, 10),
|
||||
dateTo: new Date().toISOString().slice(0, 10),
|
||||
posko: '',
|
||||
idUid: 0,
|
||||
idUp3: 0
|
||||
}
|
||||
)
|
||||
const filters = ref()
|
||||
</script>
|
91
src/components/Pages/Anomali/Keluhan/Anomali_LAPPKU_LPP.vue
Executable file
@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<div class="mt-4 lg:mt-6 max-w-7xl">
|
||||
<h1 class="text-xl font-medium md:text-2xl text-dark">
|
||||
Laporan Pengaduan PLN Mobile
|
||||
</h1>
|
||||
</div>
|
||||
<DxDataGrid class="max-h-[calc(100vh-140px)] mb-10" :show-column-lines="true" :show-row-lines="false"
|
||||
:show-borders="true" :row-alternation-enabled="true" :hover-state-enabled="true"
|
||||
@selection-changed="onSelectionChanged" @exporting="onExporting" :allow-column-resizing="true"
|
||||
column-resizing-mode="widget" :word-wrap-enabled="true">
|
||||
<DxSelection mode="single" />
|
||||
<DxPaging :enabled="false" />
|
||||
<DxScrolling column-rendering-mode="virtual" mode="virtual" />
|
||||
<DxLoadPanel :position="position" :show-indicator="showIndicator" :show-pane="showPane" :shading="shading"
|
||||
v-if="loading" v-model:visible="loading" :enabled="true" />
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" />
|
||||
<DxExport :enabled="true" :formats="['pdf', 'xlsx', 'document']" :allow-export-selected-data="false" />
|
||||
<DxColumnFixing :enabled="true" />
|
||||
|
||||
<DxColumn alignment="center" data-field="" caption="Nama Unit" css-class="custom-table-column" />
|
||||
<DxColumn alignment="center" caption="Total WO PLN Mobile" css-class="custom-table-column">
|
||||
<DxColumn :width="170" alignment="center" data-field="" data-type="number" caption="a"
|
||||
css-class="custom-table-column" />
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Total Pengaduan Yang Diselesaikan Secara Anomali"
|
||||
css-class="custom-table-column">
|
||||
<DxColumn :width="170" alignment="center" data-field="" data-type="number" caption="b"
|
||||
css-class="custom-table-column" />
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="% Pengaduan Yang Diselesaikan Secara Anomali" css-class="custom-table-column">
|
||||
<DxColumn :width="170" alignment="center" data-field="" data-type="number" caption="c=b/a"
|
||||
css-class="custom-table-column" />
|
||||
</DxColumn>
|
||||
|
||||
</DxDataGrid>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DxDataGrid } from 'devextreme-vue'
|
||||
import { DxColumn, DxColumnFixing, DxExport, DxLoadPanel, DxPaging, DxScrolling, DxSearchPanel, DxSelection } from 'devextreme-vue/data-grid'
|
||||
import { jsPDF } from 'jspdf'
|
||||
import { exportDataGrid as exportToPdf } from 'devextreme/pdf_exporter'
|
||||
import { exportDataGrid as exportToExcel } from 'devextreme/excel_exporter'
|
||||
import { saveAs } from 'file-saver'
|
||||
import { Workbook } from 'exceljs'
|
||||
import { computed, ref } from 'vue'
|
||||
const position = { of: '#data' };
|
||||
const showIndicator = ref(true);
|
||||
const shading = ref(true);
|
||||
const showPane = ref(true);
|
||||
const props = defineProps({
|
||||
data: Array as () => any[],
|
||||
})
|
||||
const data = computed(() => props.data)
|
||||
const loading = ref(false)
|
||||
|
||||
const onExporting = (e: any) => {
|
||||
if (e.format === 'pdf') {
|
||||
const doc = new jsPDF()
|
||||
|
||||
exportToPdf({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save(`.pdf`)
|
||||
})
|
||||
} else {
|
||||
const workbook = new Workbook()
|
||||
const worksheet = workbook.addWorksheet('Employees')
|
||||
|
||||
exportToExcel({
|
||||
component: e.component,
|
||||
worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer: any) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx')
|
||||
})
|
||||
})
|
||||
|
||||
e.cancel = true
|
||||
}
|
||||
}
|
||||
|
||||
const onSelectionChanged = ({ selectedRowsData }: any) => {
|
||||
const data = selectedRowsData[0]
|
||||
console.log(data)
|
||||
}
|
||||
|
||||
</script>
|
129
src/components/Pages/Anomali/Keluhan/Anomali_LAPPKU_LPT.vue
Executable file
@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<div class="mt-4 lg:mt-6 max-w-7xl">
|
||||
<h1 class="text-xl font-medium md:text-2xl text-dark">
|
||||
Laporan Pengaduan Total
|
||||
</h1>
|
||||
</div>
|
||||
<DxDataGrid class="max-h-[calc(100vh-140px)] mb-10" :show-column-lines="true" :show-row-lines="false"
|
||||
:show-borders="true" :row-alternation-enabled="true" :hover-state-enabled="true"
|
||||
@selection-changed="onSelectionChanged" :column-width="100" @exporting="onExporting" :allow-column-resizing="true"
|
||||
column-resizing-mode="widget" :word-wrap-enabled="true">
|
||||
<DxSelection mode="single" />
|
||||
<DxPaging :enabled="false" />
|
||||
<DxScrolling column-rendering-mode="virtual" mode="virtual" />
|
||||
<DxLoadPanel :position="position" :show-indicator="showIndicator" :show-pane="showPane" :shading="shading"
|
||||
v-if="loading" v-model:visible="loading" :enabled="true" />
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" />
|
||||
<DxExport :enabled="true" :formats="['pdf', 'xlsx', 'document']" :allow-export-selected-data="false" />
|
||||
<DxColumnFixing :enabled="true" />
|
||||
|
||||
<DxColumn :width="170" alignment="center" data-field="" caption="Nama Unit" css-class="custom-table-column" />
|
||||
<DxColumn alignment="center" caption="Total WO" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="CC 123" css-class="custom-table-column">
|
||||
<DxColumn :width="150" alignment="center" data-field="" data-type="number" caption="a"
|
||||
css-class="custom-table-column" />
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="PLN Mobile" css-class="custom-table-column">
|
||||
<DxColumn :width="150" alignment="center" data-field="" data-type="number" caption="b"
|
||||
css-class="custom-table-column" />
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Loket" css-class="custom-table-column">
|
||||
<DxColumn :width="150" alignment="center" data-field="" data-type="number" caption="c"
|
||||
css-class="custom-table-column" />
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Lainnya" css-class="custom-table-column">
|
||||
<DxColumn :width="150" alignment="center" data-field="" data-type="number" caption="d"
|
||||
css-class="custom-table-column" />
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Total" css-class="custom-table-column">
|
||||
<DxColumn :width="150" alignment="center" data-field="" data-type="number" caption="e=a+b+c+d"
|
||||
css-class="custom-table-column" />
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Total Pengaduan Yang Diselesaikan Secara Anomali"
|
||||
css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="PLN Mobile" css-class="custom-table-column">
|
||||
<DxColumn :width="150" alignment="center" data-field="" data-type="number" caption="f"
|
||||
css-class="custom-table-column" />
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="CC 123" css-class="custom-table-column">
|
||||
<DxColumn :width="150" alignment="center" data-field="" data-type="number" caption="g"
|
||||
css-class="custom-table-column" />
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Total" css-class="custom-table-column">
|
||||
<DxColumn :width="150" alignment="center" data-field="" data-type="number" caption="h=f+g"
|
||||
css-class="custom-table-column" />
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
|
||||
<DxColumn alignment="center" caption="% Pengaduan Yang Diselesaikan Secara Anomali" css-class="custom-table-column">
|
||||
<DxColumn alignment="center" caption="PLN Mobile" css-class="custom-table-column">
|
||||
<DxColumn :width="150" alignment="center" data-field="" data-type="number" caption="i=f/e"
|
||||
css-class="custom-table-column" />
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="CC 123" css-class="custom-table-column">
|
||||
<DxColumn :width="150" alignment="center" data-field="" data-type="number" caption="j=g/e"
|
||||
css-class="custom-table-column" />
|
||||
</DxColumn>
|
||||
<DxColumn alignment="center" caption="Total" css-class="custom-table-column">
|
||||
<DxColumn :width="150" alignment="center" data-field="" data-type="number" caption="k=i+j"
|
||||
css-class="custom-table-column" />
|
||||
</DxColumn>
|
||||
</DxColumn>
|
||||
|
||||
</DxDataGrid>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { DxDataGrid } from 'devextreme-vue'
|
||||
import { DxColumn, DxColumnFixing, DxExport, DxLoadPanel, DxPaging, DxScrolling, DxSearchPanel, DxSelection } from 'devextreme-vue/data-grid'
|
||||
import { jsPDF } from 'jspdf'
|
||||
import { exportDataGrid as exportToPdf } from 'devextreme/pdf_exporter'
|
||||
import { exportDataGrid as exportToExcel } from 'devextreme/excel_exporter'
|
||||
import { saveAs } from 'file-saver'
|
||||
import { Workbook } from 'exceljs'
|
||||
const position = { of: '#data' }
|
||||
const showIndicator = ref(true)
|
||||
const shading = ref(true)
|
||||
const showPane = ref(true)
|
||||
const loading = ref(false)
|
||||
const props = defineProps({
|
||||
data: Array as () => any[],
|
||||
})
|
||||
const data = computed(() => props.data)
|
||||
|
||||
const onExporting = (e: any) => {
|
||||
if (e.format === 'pdf') {
|
||||
const doc = new jsPDF()
|
||||
|
||||
exportToPdf({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save(`.pdf`)
|
||||
})
|
||||
} else {
|
||||
const workbook = new Workbook()
|
||||
const worksheet = workbook.addWorksheet('Employees')
|
||||
|
||||
exportToExcel({
|
||||
component: e.component,
|
||||
worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer: any) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx')
|
||||
})
|
||||
})
|
||||
|
||||
e.cancel = true
|
||||
}
|
||||
}
|
||||
|
||||
const onSelectionChanged = ({ selectedRowsData }: any) => {
|
||||
const data = selectedRowsData[0]
|
||||
console.log(data)
|
||||
}
|
||||
</script>
|