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
|
4
.env.development
Normal file → Executable file
@ -1,4 +1,6 @@
|
||||
VITE_BASE_URL=http://localhost:5173
|
||||
VITE_BASE_DIRECTORY=/
|
||||
VITE_APP_VERSION=0.0.1
|
||||
VITE_APP_NAME='Executive Information System'
|
||||
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
|
4
.env.production
Normal file → Executable file
@ -1,4 +1,6 @@
|
||||
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_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
23
.github/workflows/docker-image-development.yml
vendored
Normal file → Executable file
@ -2,27 +2,24 @@ 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:
|
||||
- name: Docker Hub Login
|
||||
env:
|
||||
DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}}
|
||||
DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}}
|
||||
run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
|
||||
run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
|
||||
|
||||
- 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
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build the Docker image
|
||||
run: |
|
||||
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
29
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;"]
|
||||
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 |
|
@ -1,22 +1,22 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: apkt-eis
|
||||
name: apkt-eis
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: apkt-eis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: apkt-eis
|
||||
spec:
|
||||
containers:
|
||||
- name: apkt-eis
|
||||
image: defuj/apkt-eis:v1.0.1-dev
|
||||
ports:
|
||||
- containerPort: 80
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: apkt-eis
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: apkt-eis
|
||||
spec:
|
||||
containers:
|
||||
- name: apkt-eis
|
||||
image: defuj/apkt-eis:v0.0.10-vm
|
||||
ports:
|
||||
- containerPort: 80
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@ -43,4 +43,4 @@ spec:
|
||||
- protocol: TCP
|
||||
port: 32166
|
||||
targetPort: 80
|
||||
type: ClusterIP
|
||||
type: ClusterIP
|
||||
|
0
index.html
Normal file → Executable file
0
nginx.conf
Normal file → Executable file
13335
package-lock.json
generated
Normal file → Executable file
41
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';
|
3035
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",
|
||||
|
82
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']">
|
||||
<component v-if="menu.path.includes('/gangguan/')" :is="navigationIcon[0]"
|
||||
alt="icon"
|
||||
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
|
||||
<component v-else-if="menu.path.includes('/keluhan/')"
|
||||
:is="navigationIcon[1]" alt="icon"
|
||||
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
|
||||
<component v-else-if="menu.path.includes('/monalisa/')"
|
||||
:is="navigationIcon[2]" alt="icon"
|
||||
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
|
||||
<component v-else-if="menu.path.includes('/check-in-out/')"
|
||||
:is="navigationIcon[3]" alt="icon"
|
||||
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
|
||||
<component v-else-if="menu.path.includes('/anomali-pengaduan/')"
|
||||
:is="navigationIcon[4]" alt="icon"
|
||||
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
|
||||
<component v-else-if="menu.path.includes('/ctt-kwh-periksa/')"
|
||||
:is="navigationIcon[5]" alt="icon"
|
||||
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
|
||||
<component v-else-if="menu.path.includes('/material/')"
|
||||
:is="navigationIcon[6]" alt="icon"
|
||||
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
|
||||
<component v-else-if="menu.path.includes('/transaksi/')"
|
||||
:is="navigationIcon[7]" alt="icon"
|
||||
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
|
||||
<component v-else :is="navigationIcon[8]" alt="icon"
|
||||
:class="['h-6 w-6 flex-none', active ? 'fill-white' : 'fill-gray-600']" />
|
||||
<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="['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="['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="['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="['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="['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="['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="['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="['w-8 h-8 fill-gray-600 group-hover:fill-white flex']" />
|
||||
<component v-else :is="navigationIcon[8]" alt="icon"
|
||||
: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']">
|
||||
{{ menu.name }}
|
||||
</span>
|
||||
<span
|
||||
:class="[active ? 'text-white' : 'text-gray-500', 'text-xs line-clamp-1']">
|
||||
{{ menu.path.replace('/home/', '') }}
|
||||
<div class="flex flex-col flex-1 ml-3 space-y-1">
|
||||
<span
|
||||
class="w-full text-sm font-medium text-gray-800 text-start group-hover:text-white line-clamp-1">
|
||||
{{ menu.name }}
|
||||
</span>
|
||||
<span
|
||||
class="w-full text-xs text-gray-500 text-start group-hover:text-white line-clamp-1">
|
||||
{{ menu.path.replace('/home/', '') }}
|
||||
</span>
|
||||
</div>
|
||||
<span class="hidden ml-3 text-sm text-gray-500 group-hover:block group-hover:text-white">
|
||||
Buka
|
||||
</span>
|
||||
</div>
|
||||
<span v-if="active" class="flex-none ml-3 text-gray-200">
|
||||
Buka
|
||||
</span>
|
||||
|
||||
|
||||
</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,
|
||||
|
57
src/components/DatePicker.vue
Normal file → Executable file
@ -1,41 +1,54 @@
|
||||
<script setup lang="ts">
|
||||
import { PhCalendarBlank } from '@phosphor-icons/vue';
|
||||
import { ref } from 'vue'
|
||||
import VueTailwindDatepicker from 'vue-tailwind-datepicker'
|
||||
|
||||
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>
|
||||
<PhCalendarBlank size="18" weight="regular"/>
|
||||
<PhCalendarBlank size="18" weight="regular" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</vue-tailwind-datepicker>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
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">
|
||||
|
48
src/components/Form/Filters.vue
Normal file → Executable file
@ -1,44 +1,38 @@
|
||||
<script setup lang="ts">
|
||||
// components
|
||||
import Button from '@/components/Button.vue';
|
||||
import Button from '@/components/Buttons/Button.vue';
|
||||
import { PhArrowsCounterClockwise, PhFileText, PhMagnifyingGlass } from '@phosphor-icons/vue';
|
||||
|
||||
// icons
|
||||
import {
|
||||
PhArrowsCounterClockwise,
|
||||
PhFileText,
|
||||
PhMagnifyingGlass
|
||||
} from '@phosphor-icons/vue';
|
||||
defineProps({
|
||||
reportButton: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
defineProps({
|
||||
reportButton: {
|
||||
type: Boolean,
|
||||
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>
|
||||
</template>
|
||||
|
103
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="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :selected="up3" :placeholder="up3placeholder" />
|
||||
</div>
|
||||
|
||||
<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" />
|
||||
</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>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block"
|
||||
>Unit Pelaksanaan Pelayanan Pelanggan:</label
|
||||
>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
</div>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Posko:</label>
|
||||
|
||||
<Select 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>
|
||||
|
||||
<DatePicker />
|
||||
</div>
|
||||
</template>
|
||||
|
106
src/components/Form/FiltersType/Type10.vue
Normal file → Executable file
@ -1,44 +1,94 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
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"/>
|
||||
</div>
|
||||
<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" />
|
||||
</div>
|
||||
<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" />
|
||||
</div>
|
||||
<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 />
|
||||
</div>
|
||||
<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" />
|
||||
<small class="flex items-center">s/d</small>
|
||||
<Select placeholder="2" />
|
||||
<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>
|
||||
<InputNumber @update:time-value="(value) => (data.maxJmlLapor = value)" class="flex flex-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
204
src/components/Form/FiltersType/Type11.vue
Normal file → Executable file
@ -1,47 +1,191 @@
|
||||
<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 { 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"/>
|
||||
</div>
|
||||
<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" />
|
||||
</div>
|
||||
<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" />
|
||||
</div>
|
||||
<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 />
|
||||
</div>
|
||||
<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" />
|
||||
<small class="flex items-center">s/d</small>
|
||||
<Select placeholder="2" />
|
||||
<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
|
||||
:value="`${data.maxTime} Menit`"
|
||||
@update:text="setMax($event)"
|
||||
class="flex flex-1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
139
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 InputWithSuffix from '../InputWithSuffix.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"/>
|
||||
</div>
|
||||
<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" />
|
||||
</div>
|
||||
<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" />
|
||||
</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>
|
||||
<Select @update:selected="setUlp($event)" :data="itemsUlp" :placeholder="ulpPlaceholder" />
|
||||
</div>
|
||||
|
||||
<DatePicker />
|
||||
</div>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<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>
|
||||
<DatePicker @update:date-value="(value) => data.periode = value" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-y-1">
|
||||
<Select placeholder="Durasi Menit" />
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Durasi:</label>
|
||||
|
||||
<div class="grid grid-flow-col auto-cols-auto gap-x-1.5">
|
||||
<InputWithSuffix />
|
||||
<small class="flex items-center">s/d</small>
|
||||
<InputWithSuffix />
|
||||
<div class="flex flex-col gap-y-1">
|
||||
<Select @update:selected="changeDuration($event)" :data="sla" placeholder="Durasi Menit" />
|
||||
|
||||
<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 @update:minute-value="(value: any) => data.maxDurasiResponseTime = value" @value="data.maxDurasiResponseTime"
|
||||
:disabled="triggerInput" class="flex flex-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
118
src/components/Form/FiltersType/Type13.vue
Normal file → Executable file
@ -1,41 +1,93 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import InlineRadioGroup from '@/components/Form/InlineRadioGroup.vue'
|
||||
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="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :selected="up3" :placeholder="up3Placeholder" />
|
||||
</div>
|
||||
|
||||
<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="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="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Group By Kode Unit Distribusi:</label>
|
||||
|
||||
<InlineRadioGroup @update:group-value="(value) => (data.groupBy = value.id === 2)" :radio-items="[
|
||||
{ id: 1, title: 'Tidak' },
|
||||
{ id: 2, title: 'Ya, Grupkan' }
|
||||
]" />
|
||||
</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"
|
||||
>Unit Pelaksanaan Pelayanan Pelanggan:</label
|
||||
>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
</div>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block"
|
||||
>Unit Layanan Pelanggan:</label
|
||||
>
|
||||
|
||||
<Select placeholder="Semua Unit Layanan Pelanggan" />
|
||||
</div>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
</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>
|
||||
|
||||
<InlineRadioGroup :radio-items="[{id: 1, title: 'Tidak', checked: true}, {id: 2, title: 'Ya, Grupkan'}]" />
|
||||
</div>
|
||||
</template>
|
||||
|
90
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>
|
||||
<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>
|
||||
|
||||
<Select placeholder="Semua Distribusi/Wilayah"/>
|
||||
<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" />
|
||||
|
||||
</div>
|
||||
|
||||
<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" />
|
||||
|
||||
</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>
|
||||
|
||||
<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
|
||||
>
|
||||
|
||||
<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
|
||||
>
|
||||
|
||||
<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>
|
||||
|
||||
<DatePicker />
|
||||
</div>
|
||||
</template>
|
||||
|
79
src/components/Form/FiltersType/Type15.vue
Normal file → Executable file
@ -1,25 +1,76 @@
|
||||
<script setup lang="ts">
|
||||
import InputWithFilter from '../InputWithFilter.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import InlineRadioGroup from '@/components/Form/InlineRadioGroup.vue'
|
||||
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'}]" />
|
||||
</div>
|
||||
<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'}]" />
|
||||
</div>
|
||||
<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>
|
||||
|
127
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="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select :data="itemsUp3" @update:selected="setUp3($event)" :placeholder="up3Placeholder" :selected="up3" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Posko:</label>
|
||||
|
||||
<Select :data="itemsPosko" @update:selected="setPosko($event)" :placeholder="poskoPlaceholder"
|
||||
:selected="posko" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Media:</label>
|
||||
|
||||
<Select :selected="media" @update:selected="setMedia($event)" :placeholder="mediaPlaceholder"
|
||||
:data="itemsMedia" />
|
||||
</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>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block"
|
||||
>Unit Pelaksanaan Pelayanan Pelanggan:</label
|
||||
>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
</div>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Posko:</label>
|
||||
|
||||
<Select 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">Media:</label>
|
||||
|
||||
<Select placeholder="Semua Media" />
|
||||
</div>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
</div>
|
||||
</template>
|
||||
|
71
src/components/Form/FiltersType/Type17.vue
Normal file → Executable file
@ -1,46 +1,51 @@
|
||||
<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 />
|
||||
</div>
|
||||
<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" />
|
||||
<div class="flex flex-col gap-y-1">
|
||||
<Select placeholder="Pilih Unit" />
|
||||
|
||||
<div class="grid grid-flow-col auto-cols-auto gap-x-1.5">
|
||||
<Select placeholder="Pilih Area" />
|
||||
<Select placeholder="Pilih Rayon" />
|
||||
<div class="grid grid-flow-col auto-cols-auto gap-x-1.5">
|
||||
<Select placeholder="Pilih Area" />
|
||||
<Select placeholder="Pilih Rayon" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Status:</label>
|
||||
|
||||
<Select placeholder="Pilih Status" />
|
||||
</div>
|
||||
|
||||
<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="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>
|
||||
|
||||
<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>
|
||||
|
||||
<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
|
||||
>
|
||||
|
||||
<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>
|
||||
|
||||
<InputWithFilter placeholder="cari report" :filters="[{id: 1, title: 'Pilih Jenis'}]" />
|
||||
</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>
|
147
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"/>
|
||||
</div>
|
||||
<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"/>
|
||||
</div>
|
||||
<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" />
|
||||
</div>
|
||||
<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" />
|
||||
</div>
|
||||
<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" />
|
||||
<div class="grid grid-cols-2 gap-x-2">
|
||||
<Select @update:selected="setMonth($event)" :data="months" :placeholder="bulanPlaceholder" />
|
||||
<Select @update:selected="setYear($event)" :data="years" :placeholder="tahunPlaceholder" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
106
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="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :selected="up3" :placeholder="up3Placeholder" />
|
||||
</div>
|
||||
|
||||
<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="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>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block"
|
||||
>Unit Pelaksanaan Pelayanan Pelanggan:</label
|
||||
>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
</div>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block"
|
||||
>Unit Layanan Pelanggan:</label
|
||||
>
|
||||
|
||||
<Select placeholder="Semua Unit Layanan Pelanggan" />
|
||||
</div>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
</div>
|
||||
</template>
|
||||
|
106
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 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"/>
|
||||
</div>
|
||||
<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" />
|
||||
</div>
|
||||
<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" />
|
||||
</div>
|
||||
<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" />
|
||||
</div>
|
||||
<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>
|
||||
|
102
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="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :selected="uppp" :placeholder="uppPlaceholder" />
|
||||
</div>
|
||||
|
||||
<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" />
|
||||
</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>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block"
|
||||
>Unit Pelaksanaan Pelayanan Pelanggan:</label
|
||||
>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
</div>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Posko:</label>
|
||||
|
||||
<Select 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>
|
||||
|
||||
<DatePicker />
|
||||
</div>
|
||||
</template>
|
||||
|
110
src/components/Form/FiltersType/Type6.vue
Normal file → Executable file
@ -1,42 +1,98 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
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"/>
|
||||
</div>
|
||||
<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" />
|
||||
</div>
|
||||
<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" />
|
||||
</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>
|
||||
<Select @update:selected="setPosko($event)" :data="itemsPosko" :selected="posko"
|
||||
:placeholder="poskoPlaceholder" />
|
||||
</div>
|
||||
|
||||
<DatePicker />
|
||||
</div>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<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>
|
||||
<DatePicker @update:date-value="(value) => (data.periode = value)" />
|
||||
</div>
|
||||
|
||||
<div class="grid grid-flow-col auto-cols-auto gap-x-1.5">
|
||||
<Select placeholder="1" />
|
||||
<small class="flex items-center">s/d</small>
|
||||
<Select placeholder="2" />
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Lapor Ulang:</label>
|
||||
|
||||
<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>
|
||||
<InputNumber :value="data.maxJmlLapor" @update:time-value="(value) => (data.maxJmlLapor = value)"
|
||||
class="flex flex-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
190
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'
|
||||
import InputWithSuffix from '../InputWithSuffix.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"/>
|
||||
</div>
|
||||
<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" />
|
||||
</div>
|
||||
<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" />
|
||||
</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>
|
||||
<Select @update:selected="setPosko($event)" :data="itemsPosko" :selected="posko"
|
||||
:placeholder="poskoPlaceholder" />
|
||||
</div>
|
||||
|
||||
<DatePicker />
|
||||
</div>
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Periode Tanggal:</label>
|
||||
|
||||
<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>
|
||||
<DatePicker @update:date-value="(value) => (data.periode = value)" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-y-1">
|
||||
<Select placeholder="Durasi Menit" />
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Durasi:</label>
|
||||
|
||||
<div class="grid grid-flow-col auto-cols-auto gap-x-1.5">
|
||||
<InputWithSuffix />
|
||||
<small class="flex items-center">s/d</small>
|
||||
<InputWithSuffix />
|
||||
<div class="flex flex-col gap-y-1">
|
||||
<Select @update:selected="changeDuration($event)" :data="sla" placeholder="Durasi Menit" />
|
||||
|
||||
<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 :value="`${data.maxTime} Menit`" @update:text="setMax($event)" class="flex flex-1" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
75
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="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :selected="uppp" :placeholder="uppPlaceholder" />
|
||||
</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>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block"
|
||||
>Unit Pelaksanaan Pelayanan Pelanggan:</label
|
||||
>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
</div>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Periode Tanggal:</label>
|
||||
|
||||
<DatePicker />
|
||||
</div>
|
||||
</template>
|
||||
|
122
src/components/Form/FiltersType/Type9.vue
Normal file → Executable file
@ -1,39 +1,99 @@
|
||||
<script setup lang="ts">
|
||||
import Select from '@/components/Select.vue'
|
||||
import DatePicker from '@/components/DatePicker.vue'
|
||||
import InlineRadioGroup from '@/components/Form/InlineRadioGroup.vue'
|
||||
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="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Unit Pelaksanaan Pelayanan Pelanggan:</label>
|
||||
|
||||
<Select @update:selected="setUp3($event)" :data="itemsUp3" :placeholder="uppPlaceholder" :selected="uppp" />
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Posko:</label>
|
||||
|
||||
<Select @update:selected="setPosko($event)" :data="itemsPosko" :placeholder="poskoPlaceholder"
|
||||
:selected="posko" />
|
||||
</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 class="flex flex-col flex-1 space-y-2">
|
||||
<label class="filter-input-label">Group By Kode Unit Distribusi:</label>
|
||||
|
||||
<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>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block"
|
||||
>Unit Pelaksanaan Pelayanan Pelanggan:</label
|
||||
>
|
||||
|
||||
<Select placeholder="Semua Unit Pelaksanaan Pelayanan Pelanggan" />
|
||||
</div>
|
||||
|
||||
<div class="sm:grid sm:grid-cols-2 lg:grid-cols-3 sm:items-center">
|
||||
<label class="text-gray-800 font-semibold mb-2 sm:mb-0 block">Posko:</label>
|
||||
|
||||
<Select 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>
|
||||
|
||||
<DatePicker />
|
||||
</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>
|
||||
|
||||
<InlineRadioGroup :radio-items="[{id: 1, title: 'Tidak', checked: true}, {id: 2, title: 'Ya, Grupkan'}]" />
|
||||
</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>
|
||||
|
80
src/components/Form/InputWithSuffix.vue
Normal file → Executable file
@ -1,34 +1,58 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
})
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
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
85
src/components/InputText.vue
Normal file → Executable file
@ -1,59 +1,62 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { ref } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
default: "text",
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
className: {
|
||||
type: String,
|
||||
default: "",
|
||||
}
|
||||
type: {
|
||||
type: String,
|
||||
default: 'text'
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
className: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:value'])
|
||||
|
||||
const updateValue = (event: Event) => {
|
||||
const value = (event.target as HTMLInputElement).value;
|
||||
emit('update:value', value)
|
||||
const value = (event.target as HTMLInputElement).value
|
||||
emit('update:value', value)
|
||||
}
|
||||
|
||||
const inputType = ref(props.type)
|
||||
const switchInputType = () => {
|
||||
inputType.value = inputType.value == 'password' ? 'text' : 'password'
|
||||
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"
|
||||
:class="[inputType == 'password' ? 'fill-gray-500' : 'fill-primary-500']">
|
||||
<path
|
||||
d="M19.3211 9.74688C19.2937 9.68516 18.632 8.21719 17.1609 6.74609C15.2008 4.78594 12.725 3.75 9.99999 3.75C7.27499 3.75 4.79921 4.78594 2.83905 6.74609C1.36796 8.21719 0.703118 9.6875 0.678899 9.74688C0.643362 9.82681 0.625 9.91331 0.625 10.0008C0.625 10.0883 0.643362 10.1748 0.678899 10.2547C0.706243 10.3164 1.36796 11.7836 2.83905 13.2547C4.79921 15.2141 7.27499 16.25 9.99999 16.25C12.725 16.25 15.2008 15.2141 17.1609 13.2547C18.632 11.7836 19.2937 10.3164 19.3211 10.2547C19.3566 10.1748 19.375 10.0883 19.375 10.0008C19.375 9.91331 19.3566 9.82681 19.3211 9.74688ZM9.99999 15C7.5953 15 5.49452 14.1258 3.75546 12.4023C3.0419 11.6927 2.43483 10.8836 1.95312 10C2.4347 9.11636 3.04179 8.30717 3.75546 7.59766C5.49452 5.87422 7.5953 5 9.99999 5C12.4047 5 14.5055 5.87422 16.2445 7.59766C16.9595 8.307 17.5679 9.11619 18.0508 10C17.4875 11.0516 15.0336 15 9.99999 15ZM9.99999 6.25C9.25831 6.25 8.53329 6.46993 7.9166 6.88199C7.29992 7.29404 6.81927 7.87971 6.53544 8.56494C6.25162 9.25016 6.17735 10.0042 6.32205 10.7316C6.46674 11.459 6.82389 12.1272 7.34834 12.6517C7.87279 13.1761 8.54097 13.5333 9.2684 13.6779C9.99583 13.8226 10.7498 13.7484 11.4351 13.4645C12.1203 13.1807 12.7059 12.7001 13.118 12.0834C13.5301 11.4667 13.75 10.7417 13.75 10C13.749 9.00576 13.3535 8.05253 12.6505 7.34949C11.9475 6.64645 10.9942 6.25103 9.99999 6.25ZM9.99999 12.5C9.50554 12.5 9.02219 12.3534 8.61107 12.0787C8.19994 11.804 7.87951 11.4135 7.69029 10.9567C7.50107 10.4999 7.45157 9.99723 7.54803 9.51227C7.64449 9.02732 7.88259 8.58186 8.23222 8.23223C8.58186 7.8826 9.02731 7.6445 9.51227 7.54804C9.99722 7.45157 10.4999 7.50108 10.9567 7.6903C11.4135 7.87952 11.804 8.19995 12.0787 8.61107C12.3534 9.0222 12.5 9.50555 12.5 10C12.5 10.663 12.2366 11.2989 11.7678 11.7678C11.2989 12.2366 10.663 12.5 9.99999 12.5Z" />
|
||||
</svg>
|
||||
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"
|
||||
:class="[inputType == 'password' ? 'fill-gray-500' : 'fill-primary-500']">
|
||||
<path
|
||||
d="M19.3211 9.74688C19.2937 9.68516 18.632 8.21719 17.1609 6.74609C15.2008 4.78594 12.725 3.75 9.99999 3.75C7.27499 3.75 4.79921 4.78594 2.83905 6.74609C1.36796 8.21719 0.703118 9.6875 0.678899 9.74688C0.643362 9.82681 0.625 9.91331 0.625 10.0008C0.625 10.0883 0.643362 10.1748 0.678899 10.2547C0.706243 10.3164 1.36796 11.7836 2.83905 13.2547C4.79921 15.2141 7.27499 16.25 9.99999 16.25C12.725 16.25 15.2008 15.2141 17.1609 13.2547C18.632 11.7836 19.2937 10.3164 19.3211 10.2547C19.3566 10.1748 19.375 10.0883 19.375 10.0008C19.375 9.91331 19.3566 9.82681 19.3211 9.74688ZM9.99999 15C7.5953 15 5.49452 14.1258 3.75546 12.4023C3.0419 11.6927 2.43483 10.8836 1.95312 10C2.4347 9.11636 3.04179 8.30717 3.75546 7.59766C5.49452 5.87422 7.5953 5 9.99999 5C12.4047 5 14.5055 5.87422 16.2445 7.59766C16.9595 8.307 17.5679 9.11619 18.0508 10C17.4875 11.0516 15.0336 15 9.99999 15ZM9.99999 6.25C9.25831 6.25 8.53329 6.46993 7.9166 6.88199C7.29992 7.29404 6.81927 7.87971 6.53544 8.56494C6.25162 9.25016 6.17735 10.0042 6.32205 10.7316C6.46674 11.459 6.82389 12.1272 7.34834 12.6517C7.87279 13.1761 8.54097 13.5333 9.2684 13.6779C9.99583 13.8226 10.7498 13.7484 11.4351 13.4645C12.1203 13.1807 12.7059 12.7001 13.118 12.0834C13.5301 11.4667 13.75 10.7417 13.75 10C13.749 9.00576 13.3535 8.05253 12.6505 7.34949C11.9475 6.64645 10.9942 6.25103 9.99999 6.25ZM9.99999 12.5C9.50554 12.5 9.02219 12.3534 8.61107 12.0787C8.19994 11.804 7.87951 11.4135 7.69029 10.9567C7.50107 10.4999 7.45157 9.99723 7.54803 9.51227C7.64449 9.02732 7.88259 8.58186 8.23222 8.23223C8.58186 7.8826 9.02731 7.6445 9.51227 7.54804C9.99722 7.45157 10.4999 7.50108 10.9567 7.6903C11.4135 7.87952 11.804 8.19995 12.0787 8.61107C12.3534 9.0222 12.5 9.50555 12.5 10C12.5 10.663 12.2366 11.2989 11.7678 11.7678C11.2989 12.2366 10.663 12.5 9.99999 12.5Z" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
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
157
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'
|
||||
@ -25,85 +19,84 @@ const dialog = useDialogStore()
|
||||
const openSideBar = () => menu.toggleSidebar()
|
||||
|
||||
const showDialogLogout = () => {
|
||||
dialog.type = 'error'
|
||||
dialog.title = 'Logout dari akun?'
|
||||
dialog.content = 'Apakah Anda sudah yakin akan logout dari akun ini?'
|
||||
dialog.cancelText = 'Batalkan'
|
||||
dialog.confirmText = 'Ya, logout'
|
||||
dialog.showCancelButton = true
|
||||
dialog.onConfirm = () => {
|
||||
auth.logout()
|
||||
window.location.href = '/login'
|
||||
}
|
||||
dialog.open = true
|
||||
dialog.type = 'error'
|
||||
dialog.title = 'Logout dari akun?'
|
||||
dialog.content = 'Apakah Anda sudah yakin akan logout dari akun ini?'
|
||||
dialog.cancelText = 'Batalkan'
|
||||
dialog.confirmText = 'Ya, logout'
|
||||
dialog.showCancelButton = true
|
||||
dialog.onConfirm = () => {
|
||||
auth.logout()
|
||||
window.location.href = '/login'
|
||||
}
|
||||
dialog.open = true
|
||||
}
|
||||
</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">
|
||||
<span class="sr-only">Open sidebar</span>
|
||||
<IconBars3 class="w-6 h-6 fill-gray-600" />
|
||||
<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 lg:hidden">
|
||||
<img class="w-auto h-11" :src="IconApp" alt="PLN" />
|
||||
</RouterLink>
|
||||
<div class="flex justify-end w-full px-4">
|
||||
<div class="flex items-center ml-4 md:ml-6">
|
||||
<button @click="command.showCommandPalettes" type="button"
|
||||
class="flex flex-row items-center md:w-[300px] p-2 mr-2 text-gray-400 bg-white rounded-full hover:text-primary-500 focus:outline-none focus:ring-0">
|
||||
<span class="sr-only">Search</span>
|
||||
<MagnifyingGlassIcon class="w-6 h-6 text-primary-500" aria-hidden="true" />
|
||||
<span class="hidden px-3 text-sm font-medium text-gray-500 md:block text-md">Cari menu</span>
|
||||
</button>
|
||||
<RouterLink to="/home" class="flex items-center flex-shrink-0 my-auto ml-2 md:hidden">
|
||||
<img class="w-auto h-11" :src="IconApp" alt="PLN" />
|
||||
</RouterLink>
|
||||
<div class="flex justify-end w-full px-4">
|
||||
<div class="flex items-center ml-4 md:ml-6">
|
||||
<button @click="command.showCommandPalettes" type="button"
|
||||
class="flex flex-row items-center md:w-[300px] p-2 mr-2 text-gray-400 bg-white rounded-full hover:text-primary-500 focus:outline-none focus:ring-0">
|
||||
<span class="sr-only">Search</span>
|
||||
<MagnifyingGlassIcon class="w-6 h-6 text-primary-500" aria-hidden="true" />
|
||||
<span class="hidden px-3 text-sm font-medium text-gray-500 md:block text-md">Cari menu</span>
|
||||
</button>
|
||||
|
||||
<!-- Profile dropdown -->
|
||||
<Menu as="div" class="relative ml-1">
|
||||
<div>
|
||||
<MenuButton
|
||||
class="flex items-center max-w-xs px-1 py-1 text-sm rounded-full bg-secondary-100 md:bg-primary-500 focus:outline-none focus:ring-0 line-clamp-1">
|
||||
<span class="sr-only">Open user menu</span>
|
||||
<PictureInitial size-class="w-8 h-8" background-class="bg-secondary-100"
|
||||
font-class="text-xs font-bold text-primary-500" :name="user.user_name" />
|
||||
<span class="hidden px-3 text-xs font-medium md:block text-primary-50 line-clamp-1">
|
||||
{{ user.user_name }}
|
||||
</span>
|
||||
</MenuButton>
|
||||
</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">
|
||||
|
||||
<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" />
|
||||
</div>
|
||||
<div class="ml-3 space-y-1">
|
||||
<p class="text-sm font-medium text-primary-50 ">
|
||||
{{ user.user_name }}
|
||||
</p>
|
||||
<p class="text-xs font-normal text-primary-50">
|
||||
{{ user.user_access }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<MenuItem v-slot="{ active }">
|
||||
<button @click="showDialogLogout" :class="[active ? 'menu-item-active' : 'menu-item']">
|
||||
Log out
|
||||
</button>
|
||||
</MenuItem>
|
||||
</MenuItems>
|
||||
</transition>
|
||||
</Menu>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Profile dropdown -->
|
||||
<Menu as="div" class="relative ml-1">
|
||||
<div>
|
||||
<MenuButton
|
||||
class="flex items-center max-w-xs px-1 py-1 text-sm rounded-full bg-secondary-100 md:bg-primary-500 focus:outline-none focus:ring-0 line-clamp-1">
|
||||
<span class="sr-only">Open user menu</span>
|
||||
<PictureInitial size-class="w-8 h-8" background-class="bg-secondary-100"
|
||||
font-class="text-xs font-bold text-primary-500" :name="user.user_name" />
|
||||
<span class="hidden px-3 text-xs font-medium md:block text-primary-50 line-clamp-1">
|
||||
{{ user.user_name }}
|
||||
</span>
|
||||
</MenuButton>
|
||||
</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">
|
||||
<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" />
|
||||
</div>
|
||||
<div class="ml-3 space-y-1">
|
||||
<p class="text-sm font-medium text-primary-50">
|
||||
{{ user.user_name }}
|
||||
</p>
|
||||
<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>
|
||||
<MenuItem v-slot="{ active }">
|
||||
<button @click="showDialogLogout" :class="[active ? 'menu-item-active' : 'menu-item']">
|
||||
Log out
|
||||
</button>
|
||||
</MenuItem>
|
||||
</MenuItems>
|
||||
</transition>
|
||||
</Menu>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
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>
|