sk_fems_ui commit
13
.editorconfig
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
34
.eslintrc.js
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// .eslintrc.js
|
||||||
|
module.exports = {
|
||||||
|
// 현재 eslintrc 파일을 기준으로 ESLint 규칙을 적용
|
||||||
|
root: true,
|
||||||
|
// 추가적인 규칙들을 적용
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:vue/essential',
|
||||||
|
'prettier',
|
||||||
|
'plugin:prettier/recommended',
|
||||||
|
],
|
||||||
|
// 코드 정리 플러그인 추가
|
||||||
|
plugins: ['prettier'],
|
||||||
|
// 사용자 편의 규칙 추가
|
||||||
|
rules: {
|
||||||
|
'prettier/prettier': [
|
||||||
|
'error',
|
||||||
|
// 아래 규칙들은 개인 선호에 따라 prettier 문법 적용
|
||||||
|
// https://prettier.io/docs/en/options.html
|
||||||
|
{
|
||||||
|
singleQuote: true,
|
||||||
|
semi: true,
|
||||||
|
useTabs: true,
|
||||||
|
tabWidth: 2,
|
||||||
|
trailingComma: 'all',
|
||||||
|
printWidth: 80,
|
||||||
|
bracketSpacing: true,
|
||||||
|
arrowParens: 'avoid',
|
||||||
|
endOfLine: 'auto',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||||
|
},
|
||||||
|
};
|
90
.gitignore
vendored
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
# Created by .ignore support plugin (hsz.mobi)
|
||||||
|
### Node template
|
||||||
|
# Logs
|
||||||
|
/logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# nuxt.js build output
|
||||||
|
.nuxt
|
||||||
|
|
||||||
|
# Nuxt generate
|
||||||
|
dist
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless
|
||||||
|
|
||||||
|
# IDE / Editor
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# Service worker
|
||||||
|
sw.*
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Vim swap files
|
||||||
|
*.swp
|
63
.gitlab-ci.yml
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
image: docker:19.03.7
|
||||||
|
|
||||||
|
services:
|
||||||
|
- docker:19.03.7-dind
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- install
|
||||||
|
- build_docker_image
|
||||||
|
- build_docker_clear
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- node_modules/
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- node -v
|
||||||
|
- npm install
|
||||||
|
|
||||||
|
install_dependencies:
|
||||||
|
image: node:14.19.3
|
||||||
|
stage: install
|
||||||
|
only:
|
||||||
|
- main
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
script:
|
||||||
|
- echo "=====node install start====="
|
||||||
|
- pwd
|
||||||
|
- npm ci
|
||||||
|
- npm run build
|
||||||
|
- echo "=====node install end ====="
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- node_modules/
|
||||||
|
|
||||||
|
docker-build-main:
|
||||||
|
variables:
|
||||||
|
# do not clone again
|
||||||
|
GIT_STRATEGY: none
|
||||||
|
stage: build_docker_image
|
||||||
|
only:
|
||||||
|
- main
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
script:
|
||||||
|
# make docker image and push to local docker
|
||||||
|
- echo "=====node build_docker_image start====="
|
||||||
|
- sudo docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||||
|
- sudo docker build -t $CI_REGISTRY/root/registry/skfems/ui .
|
||||||
|
- sudo docker push $CI_REGISTRY/root/registry/skfems/ui
|
||||||
|
- sudo docker rmi $CI_REGISTRY/root/registry/skfems/ui
|
||||||
|
- echo "=====node build_docker_image end====="
|
||||||
|
|
||||||
|
clear-files:
|
||||||
|
stage: build_docker_clear
|
||||||
|
only:
|
||||||
|
- main
|
||||||
|
tags:
|
||||||
|
- test
|
||||||
|
script:
|
||||||
|
# 빌드 완료후 빌드시 Root 계정으로 생성된 자료 클리어 처리(아래 부분을 수행 안하면, 다음번 파이브라인 처리시 권한 문제로 수행 안됨)
|
||||||
|
- sudo rm -rf .nuxt
|
||||||
|
- sudo rm -rf dist
|
||||||
|
- sudo rm -rf node_modules
|
17
.project
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>sk_fems_ui</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
7
.settings/.jsdtscope
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
|
||||||
|
<classpathentry kind="src" path=""/>
|
||||||
|
<classpathentry kind="output" path=""/>
|
||||||
|
</classpath>
|
1
.settings/org.eclipse.wst.jsdt.ui.superType.container
Normal file
@ -0,0 +1 @@
|
|||||||
|
org.eclipse.wst.jsdt.launching.JRE_CONTAINER
|
1
.settings/org.eclipse.wst.jsdt.ui.superType.name
Normal file
@ -0,0 +1 @@
|
|||||||
|
Global
|
14
Dockerfile
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Package stage
|
||||||
|
FROM node:14-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ADD dist/ /app/dist/
|
||||||
|
|
||||||
|
RUN npm install -g serve
|
||||||
|
|
||||||
|
#ENV HOST 0.0.0.0
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENTRYPOINT ["serve", "-s", "dist", "-p", "3000"]
|
21
Dockerfile.comm
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Package stage
|
||||||
|
FROM node:14-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ADD dist/_nuxt/ /app/dist/_nuxt/
|
||||||
|
ADD dist/comm/ /app/dist/comm/
|
||||||
|
ADD dist/login/ /app/dist/login/
|
||||||
|
COPY dist/*.html /app/dist/
|
||||||
|
COPY dist/*.ico /app/dist/
|
||||||
|
COPY dist/*.png /app/dist/
|
||||||
|
COPY dist/*.svg /app/dist/
|
||||||
|
COPY dist/.* /app/dist/
|
||||||
|
|
||||||
|
RUN npm install -g serve
|
||||||
|
|
||||||
|
#ENV HOST 0.0.0.0
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENTRYPOINT ["serve", "-s", "dist", "-p", "3000"]
|
21
Dockerfile.comm.auth
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Package stage
|
||||||
|
FROM node:14-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ADD dist/_nuxt/ /app/dist/_nuxt/
|
||||||
|
ADD dist/comm/auth/ /app/dist/comm/auth/
|
||||||
|
ADD dist/login/ /app/dist/login/
|
||||||
|
COPY dist/*.html /app/dist/
|
||||||
|
COPY dist/*.ico /app/dist/
|
||||||
|
COPY dist/*.png /app/dist/
|
||||||
|
COPY dist/*.svg /app/dist/
|
||||||
|
COPY dist/.* /app/dist/
|
||||||
|
|
||||||
|
RUN npm install -g serve
|
||||||
|
|
||||||
|
#ENV HOST 0.0.0.0
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENTRYPOINT ["serve", "-s", "dist", "-p", "3000"]
|
21
Dockerfile.comm.base
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Package stage
|
||||||
|
FROM node:14-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ADD dist/_nuxt/ /app/dist/_nuxt/
|
||||||
|
ADD dist/comm/base/ /app/dist/comm/base/
|
||||||
|
ADD dist/login/ /app/dist/login/
|
||||||
|
COPY dist/*.html /app/dist/
|
||||||
|
COPY dist/*.ico /app/dist/
|
||||||
|
COPY dist/*.png /app/dist/
|
||||||
|
COPY dist/*.svg /app/dist/
|
||||||
|
COPY dist/.* /app/dist/
|
||||||
|
|
||||||
|
RUN npm install -g serve
|
||||||
|
|
||||||
|
#ENV HOST 0.0.0.0
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENTRYPOINT ["serve", "-s", "dist", "-p", "3000"]
|
21
Dockerfile.ems
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Package stage
|
||||||
|
FROM node:14-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ADD dist/_nuxt/ /app/dist/_nuxt/
|
||||||
|
ADD dist/ems/ /app/dist/ems/
|
||||||
|
ADD dist/login/ /app/dist/login/
|
||||||
|
COPY dist/*.html /app/dist/
|
||||||
|
COPY dist/*.ico /app/dist/
|
||||||
|
COPY dist/*.png /app/dist/
|
||||||
|
COPY dist/*.svg /app/dist/
|
||||||
|
COPY dist/.* /app/dist/
|
||||||
|
|
||||||
|
RUN npm install -g serve
|
||||||
|
|
||||||
|
#ENV HOST 0.0.0.0
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENTRYPOINT ["serve", "-s", "dist", "-p", "3000"]
|
21
Dockerfile.ems.base
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Package stage
|
||||||
|
FROM node:14-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ADD dist/_nuxt/ /app/dist/_nuxt/
|
||||||
|
ADD dist/ems/base/ /app/dist/ems/base/
|
||||||
|
ADD dist/login/ /app/dist/login/
|
||||||
|
COPY dist/*.html /app/dist/
|
||||||
|
COPY dist/*.ico /app/dist/
|
||||||
|
COPY dist/*.png /app/dist/
|
||||||
|
COPY dist/*.svg /app/dist/
|
||||||
|
COPY dist/.* /app/dist/
|
||||||
|
|
||||||
|
RUN npm install -g serve
|
||||||
|
|
||||||
|
#ENV HOST 0.0.0.0
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENTRYPOINT ["serve", "-s", "dist", "-p", "3000"]
|
21
Dockerfile.ems.fopm
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Package stage
|
||||||
|
FROM node:14-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ADD dist/_nuxt/ /app/dist/_nuxt/
|
||||||
|
ADD dist/ems/fopm/ /app/dist/ems/fopm/
|
||||||
|
ADD dist/login/ /app/dist/login/
|
||||||
|
COPY dist/*.html /app/dist/
|
||||||
|
COPY dist/*.ico /app/dist/
|
||||||
|
COPY dist/*.png /app/dist/
|
||||||
|
COPY dist/*.svg /app/dist/
|
||||||
|
COPY dist/.* /app/dist/
|
||||||
|
|
||||||
|
RUN npm install -g serve
|
||||||
|
|
||||||
|
#ENV HOST 0.0.0.0
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
ENTRYPOINT ["serve", "-s", "dist", "-p", "3000"]
|
42
README.md
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# FEMS
|
||||||
|
|
||||||
|
## Build Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# install dependencies
|
||||||
|
$ npm install
|
||||||
|
|
||||||
|
# serve with hot reload at localhost:3000
|
||||||
|
$ npm run dev
|
||||||
|
|
||||||
|
# build for production and launch server
|
||||||
|
$ npm run build
|
||||||
|
$ npm run start
|
||||||
|
|
||||||
|
# generate static project
|
||||||
|
$ npm run generate
|
||||||
|
```
|
||||||
|
|
||||||
|
For detailed explanation on how things work, check out [Nuxt.js docs](https://nuxtjs.org).
|
||||||
|
|
||||||
|
# VSCode && ESLint Prettier 적용 settings.json 옵션 추가
|
||||||
|
"editor.formatOnSave": false,
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll.eslint": true
|
||||||
|
},
|
||||||
|
"eslint.alwaysShowStatus": true,
|
||||||
|
"eslint.workingDirectories": [
|
||||||
|
{"mode": "auto"}
|
||||||
|
],
|
||||||
|
"eslint.validate": [
|
||||||
|
"javascript",
|
||||||
|
"typescript"
|
||||||
|
],
|
||||||
|
|
||||||
|
# 프로젝트 install 후 기동시 버전 mismatch 일때
|
||||||
|
vue-server-renderer, vue-template-compiler 를 현재 vue 버전에 맞게 수동 인스톨
|
||||||
|
Ex) npm install vue-server-renderer@2.6.14
|
||||||
|
Ex) npm install vue-template-compiler@2.6.14
|
||||||
|
|
||||||
|
# 프로젝트 Clean 작업
|
||||||
|
rm package-lock.json; rm .nuxt; rm node_modules;
|
7
assets/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# ASSETS
|
||||||
|
|
||||||
|
**This directory is not required, you can delete it if you don't want to use it.**
|
||||||
|
|
||||||
|
This directory contains your un-compiled assets such as LESS, SASS, or JavaScript.
|
||||||
|
|
||||||
|
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#webpacked).
|
46
assets/css/SpoqaHanSansNeo.css
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Spoqa Han Sans Neo';
|
||||||
|
font-weight: 700;
|
||||||
|
src: local('Spoqa Han Sans Neo Bold'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Bold.woff2') format('woff2'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Bold.woff') format('woff'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Bold.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Spoqa Han Sans Neo';
|
||||||
|
font-weight: 500;
|
||||||
|
src: local('Spoqa Han Sans Neo Medium'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Medium.woff2') format('woff2'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Medium.woff') format('woff'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Medium.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Spoqa Han Sans Neo';
|
||||||
|
font-weight: 400;
|
||||||
|
src: local('Spoqa Han Sans Neo Regular'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Regular.woff2') format('woff2'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Regular.woff') format('woff'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Regular.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Spoqa Han Sans Neo';
|
||||||
|
font-weight: 300;
|
||||||
|
src: local('Spoqa Han Sans Neo Light'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Light.woff2') format('woff2'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Light.woff') format('woff'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Light.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Spoqa Han Sans Neo';
|
||||||
|
font-weight: 100;
|
||||||
|
src: local('Spoqa Han Sans Neo Thin'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Thin.woff2') format('woff2'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Thin.woff') format('woff'),
|
||||||
|
url('../font/SpoqaHanSansNeo-Thin.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
|
BIN
assets/font/SpoqaHanSansNeo-Bold.eot
Normal file
BIN
assets/font/SpoqaHanSansNeo-Bold.ttf
Normal file
BIN
assets/font/SpoqaHanSansNeo-Bold.woff
Normal file
BIN
assets/font/SpoqaHanSansNeo-Bold.woff2
Normal file
BIN
assets/font/SpoqaHanSansNeo-Light.eot
Normal file
BIN
assets/font/SpoqaHanSansNeo-Light.ttf
Normal file
BIN
assets/font/SpoqaHanSansNeo-Light.woff
Normal file
BIN
assets/font/SpoqaHanSansNeo-Light.woff2
Normal file
BIN
assets/font/SpoqaHanSansNeo-Medium.eot
Normal file
BIN
assets/font/SpoqaHanSansNeo-Medium.ttf
Normal file
BIN
assets/font/SpoqaHanSansNeo-Medium.woff
Normal file
BIN
assets/font/SpoqaHanSansNeo-Medium.woff2
Normal file
BIN
assets/font/SpoqaHanSansNeo-Regular.eot
Normal file
BIN
assets/font/SpoqaHanSansNeo-Regular.ttf
Normal file
BIN
assets/font/SpoqaHanSansNeo-Regular.woff
Normal file
BIN
assets/font/SpoqaHanSansNeo-Regular.woff2
Normal file
BIN
assets/font/SpoqaHanSansNeo-Thin.eot
Normal file
BIN
assets/font/SpoqaHanSansNeo-Thin.ttf
Normal file
BIN
assets/font/SpoqaHanSansNeo-Thin.woff
Normal file
BIN
assets/font/SpoqaHanSansNeo-Thin.woff2
Normal file
BIN
assets/images/ico_grid_list.png
Normal file
After Width: | Height: | Size: 157 B |
BIN
assets/images/ico_grid_list_active.png
Normal file
After Width: | Height: | Size: 159 B |
BIN
assets/images/ico_grid_open.png
Normal file
After Width: | Height: | Size: 149 B |
BIN
assets/images/ico_grid_open_active.png
Normal file
After Width: | Height: | Size: 152 B |
BIN
assets/images/icon/ico-cal-month.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/images/icon/ico-cal-month_before.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
assets/images/icon/ico-cal-year.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/images/icon/ico-enrgMap.png
Normal file
After Width: | Height: | Size: 796 B |
BIN
assets/images/icon/ico-theme-dark.png
Normal file
After Width: | Height: | Size: 359 B |
BIN
assets/images/icon/ico-theme-light.png
Normal file
After Width: | Height: | Size: 417 B |
BIN
assets/images/login_dm.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
assets/images/login_lm.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
assets/images/logo_dm.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
assets/images/logo_lm.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
assets/images/temp/DataSetMngPage.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
assets/images/temp/EnrgEffcEqpmDetlMntrPage.png
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
assets/images/temp/EnrgEffcTotSummPage.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
assets/images/temp/EnrgMapPage.png
Normal file
After Width: | Height: | Size: 361 KiB |
BIN
assets/images/temp/EnrgReptMngPage.png
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
assets/images/temp/EnrgUseEqpmDetlMntrPage.png
Normal file
After Width: | Height: | Size: 108 KiB |
BIN
assets/images/temp/EnrgUsePalnPage.png
Normal file
After Width: | Height: | Size: 114 KiB |
BIN
assets/images/temp/EnrgUseTotSummPage.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
assets/images/temp/EqpmIndMntrPage.png
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
assets/images/temp/TagTrndPage.png
Normal file
After Width: | Height: | Size: 114 KiB |
1314
assets/scss/common.scss
Normal file
75
assets/scss/common/button.scss
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
.v-btn {
|
||||||
|
background-color: #144985;
|
||||||
|
&-radius {
|
||||||
|
&__20 {
|
||||||
|
border-radius: 20px !important;
|
||||||
|
}
|
||||||
|
&__50per {
|
||||||
|
border-radius: 50% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__full {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
&__round {
|
||||||
|
min-width: 100px !important;
|
||||||
|
padding: 8px 25px !important;
|
||||||
|
border-radius: 20px !important;
|
||||||
|
}
|
||||||
|
&__excel {
|
||||||
|
background-color: #47535c !important;
|
||||||
|
}
|
||||||
|
&-bg {
|
||||||
|
&__transparent {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
&__blue {
|
||||||
|
background-color: $--color-primary__blue;
|
||||||
|
}
|
||||||
|
&__white-blue {
|
||||||
|
background-color: $--color-white;
|
||||||
|
color: $--color-primary__blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__transparent {
|
||||||
|
border: 0;
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
&.v-btn--icon.v-btn--tile {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $theme in dark, light {
|
||||||
|
@include theme($theme);
|
||||||
|
.v-application.#{$theme}-mode {
|
||||||
|
.v-btn-bg__w-g5 {
|
||||||
|
background-color: $--theme-color-w-g5;
|
||||||
|
i {
|
||||||
|
color: $--theme-color-g5-w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.v-btn {
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-btn-backgroundColor"
|
||||||
|
);
|
||||||
|
color: map-deep-get($color, "white", "0");
|
||||||
|
|
||||||
|
&.v-btn--disabled {
|
||||||
|
opacity: 0.4;
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-btn-backgroundColor"
|
||||||
|
) !important;
|
||||||
|
color: map-deep-get($color, "white", "0") !important;
|
||||||
|
|
||||||
|
.v-icon {
|
||||||
|
color: map-deep-get($color, "white", "0") !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
assets/scss/common/card.scss
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.v-card {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $theme in dark, light {
|
||||||
|
// @include theme($theme);
|
||||||
|
.v-application.#{$theme}-mode {
|
||||||
|
.v-card {
|
||||||
|
color: map-deep-get($config, #{$theme}, "card-default-color");
|
||||||
|
.v-card__subtitle {
|
||||||
|
color: map-deep-get($config, #{$theme}, "card-subtitle");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
52
assets/scss/common/fonts.scss
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
.ft {
|
||||||
|
&-size {
|
||||||
|
&_12 { font-size: 12px !important; }
|
||||||
|
&_13 { font-size: 13px !important; }
|
||||||
|
&_14 { font-size: 14px !important; }
|
||||||
|
&_15 { font-size: 15px !important; }
|
||||||
|
&_16 { font-size: 16px !important; }
|
||||||
|
&_20 { font-size: 20px !important; }
|
||||||
|
&_24 { font-size: 24px !important; }
|
||||||
|
&_32 { font-size: 32px !important; }
|
||||||
|
&_40 { font-size: 40px !important; }
|
||||||
|
}
|
||||||
|
&-wt {
|
||||||
|
&_100 { font-weight: 100; }
|
||||||
|
&_200 { font-weight: 200; }
|
||||||
|
&_300 { font-weight: 300; }
|
||||||
|
&_400 { font-weight: 400; }
|
||||||
|
&_500 { font-weight: 500; }
|
||||||
|
&_600 { font-weight: 600; }
|
||||||
|
&_700 { font-weight: 700; }
|
||||||
|
&_800 { font-weight: 800; }
|
||||||
|
&_900 { font-weight: 900; }
|
||||||
|
}
|
||||||
|
|
||||||
|
&-clr {
|
||||||
|
&_g-9 { color: $--color-gray_9; }
|
||||||
|
&_g-7 { color: $--color-gray_7; }
|
||||||
|
&_g-c { color: $--color-gray_C; }
|
||||||
|
&_g-555 { color: $--color-gray_555 }
|
||||||
|
&_g-999 { color: $--color-gray_999; }
|
||||||
|
&_g-aaa { color: $--color-gray_aaa; }
|
||||||
|
&_blue { color: $--color-primary__blue; }
|
||||||
|
&_green { color: $--color-primary__green; }
|
||||||
|
&_yellow { color: $--color-sub__yellow; }
|
||||||
|
&_red { color: $--color-warning__red; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $theme in dark, light{
|
||||||
|
@include theme($theme);
|
||||||
|
.v-application.#{$theme}-mode{
|
||||||
|
color: $--theme-color-w-g5;
|
||||||
|
.ft {
|
||||||
|
&-clr {
|
||||||
|
&_gc-g9 { color: $--theme-color-gc-g9; }
|
||||||
|
&_g5-gc { color: $--theme-color-g5-gc; }
|
||||||
|
&_g7-g9 { color: $--theme-color-g7-g9; }
|
||||||
|
&_g9-g7 { color: $--theme-color-g9-g7; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
376
assets/scss/common/grid.scss
Normal file
@ -0,0 +1,376 @@
|
|||||||
|
.tui-grid {
|
||||||
|
&-layer-state {
|
||||||
|
z-index: 5 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// &-layer-selection {
|
||||||
|
// width: calc(100% - 2px) !important;
|
||||||
|
// }
|
||||||
|
|
||||||
|
&-container {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
&-content-area {
|
||||||
|
width: 100%;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// &-body-container {
|
||||||
|
// width: 100% !important;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &-table {
|
||||||
|
// width: 100% !important;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// &-lside-area .tui-grid-body-area {
|
||||||
|
// margin-right: -11px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
&-lside-area .tui-grid-scrollbar-left-bottom {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-rside-area {
|
||||||
|
.tui-grid-header-area,
|
||||||
|
.tui-grid-summary-area {
|
||||||
|
margin-right: $scrollbar-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-border-line-top,
|
||||||
|
&-border-line-bottom,
|
||||||
|
&-border-line-right {
|
||||||
|
border: 0 !important;
|
||||||
|
}
|
||||||
|
&-cell {
|
||||||
|
border-width: 1px !important;
|
||||||
|
}
|
||||||
|
&-cell-header {
|
||||||
|
border-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-cell-header,
|
||||||
|
&-cell-content,
|
||||||
|
&-cell.tui-grid-cell-summary {
|
||||||
|
font-family: "Spoqa Han Sans Neo";
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.25rem;
|
||||||
|
letter-spacing: 0.0178571429em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.treeGrid {
|
||||||
|
.tui-grid {
|
||||||
|
&-header-area {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-cell {
|
||||||
|
border: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tui-grid-scrollbar-right-top{
|
||||||
|
z-index:5;
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $theme in dark, light {
|
||||||
|
@include theme($theme);
|
||||||
|
.v-application.#{$theme}-mode {
|
||||||
|
.tui-grid {
|
||||||
|
&-container,
|
||||||
|
&-summary-area {
|
||||||
|
& ::-webkit-scrollbar {
|
||||||
|
width: $scrollbar-width !important;
|
||||||
|
height: $scrollbar-width !important;
|
||||||
|
-webkit-appearance: initial;
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"scrollbar-track"
|
||||||
|
) !important;
|
||||||
|
border-radius: 3px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
& ::-webkit-scrollbar-track {
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"scrollbar-track"
|
||||||
|
) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
& ::-webkit-scrollbar-thumb {
|
||||||
|
width: 50px !important;
|
||||||
|
height: 50px !important;
|
||||||
|
background-color: map-deep-get($config, #{$theme}, "scrollbar-thumb");
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-rside-area {
|
||||||
|
background-color: map-deep-get($config, #{$theme}, "scrollbar-track");
|
||||||
|
}
|
||||||
|
|
||||||
|
&-scrollbar-left-bottom {
|
||||||
|
background-color: map-deep-get($config, #{$theme}, "cardBackground");
|
||||||
|
border-color: map-deep-get($config, #{$theme}, "cardBackground");
|
||||||
|
}
|
||||||
|
|
||||||
|
&-scrollbar-right-top {
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"tui-grid-header-backgroundColor"
|
||||||
|
);
|
||||||
|
border-left-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"tui-grid-border-horziontal-color"
|
||||||
|
);
|
||||||
|
border-right-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"tui-grid-border-horziontal-color"
|
||||||
|
);
|
||||||
|
border-bottom-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"tui-grid-border-vertical-color"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-scrollbar-right-bottom {
|
||||||
|
width: $scrollbar-width !important;
|
||||||
|
height: $scrollbar-width !important;
|
||||||
|
// display: none !important;
|
||||||
|
border-color: map-deep-get($config, #{$theme}, "scrollbar-track");
|
||||||
|
background-color: map-deep-get($config, #{$theme}, "scrollbar-track");
|
||||||
|
// border: none !important;
|
||||||
|
// bottom: -1px;
|
||||||
|
// right: -2px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-scrollbar-frozen-border,
|
||||||
|
&-scrollbar-y-outer-border,
|
||||||
|
&-scrollbar-y-inner-border {
|
||||||
|
background-color: transparent !important;
|
||||||
|
border-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-body-area {
|
||||||
|
overflow: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-container,
|
||||||
|
&-layer-state,
|
||||||
|
&-body-area,
|
||||||
|
&-summary-area,
|
||||||
|
&-cell {
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"tui-grid-cell-backgroundColor"
|
||||||
|
);
|
||||||
|
border-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"tui-grid-border-vertical-color"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
&-cell-summary {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-header-area,
|
||||||
|
&-cell-header {
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"tui-grid-header-backgroundColor"
|
||||||
|
);
|
||||||
|
border-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"tui-grid-border-vertical-color"
|
||||||
|
);
|
||||||
|
color: map-deep-get($config, #{$theme}, "activate");
|
||||||
|
}
|
||||||
|
|
||||||
|
&-row-odd,
|
||||||
|
&-row-even {
|
||||||
|
.tui-grid-cell-content {
|
||||||
|
color: map-deep-get($config, #{$theme}, "tui-grid-cell-color");
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
> .tui-grid-cell {
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"tui-grid-cell-hover-backgroundColor"
|
||||||
|
);
|
||||||
|
|
||||||
|
.tui-grid-cell-content {
|
||||||
|
color: map-deep-get($config, #{$theme}, "activate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-cell {
|
||||||
|
&.row-insert {
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"tui-grid-cell-insert-color"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
&.row-modify {
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"tui-grid-cell-modify-color"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
&.row-removed {
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"tui-grid-cell-removed-color"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
&.row-disabled {
|
||||||
|
color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"tui-grid-cell-disabled-color"
|
||||||
|
);
|
||||||
|
|
||||||
|
.tui-grid-cell-content {
|
||||||
|
color: map-deep-get($config, #{$theme}, "tui-grid-cell-disabled-color");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.row-selected {
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"tui-grid-cell-selected-color"
|
||||||
|
);
|
||||||
|
|
||||||
|
.tui-grid-cell-content {
|
||||||
|
color: map-deep-get($config, #{$theme}, "activate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-layer-focus-border {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-cell-has-tree {
|
||||||
|
.tui-grid-cell-content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tree-extra-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.tui-grid-tree-depth
|
||||||
|
{
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
position: relative;
|
||||||
|
left: 0 !important;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&-btn-tree {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin-top: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
margin-right: 6px;
|
||||||
|
top: 0;
|
||||||
|
left: 0 !important;
|
||||||
|
i {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tree-icon {
|
||||||
|
margin-top: 0;
|
||||||
|
top: 0;
|
||||||
|
i {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin-left: 0;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 0 0;
|
||||||
|
@if $theme == dark {
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg id='ico_tree_item' xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cdefs%3E%3Cstyle%3E .cls-1, .cls-4 %7B fill: none; %7D .cls-1 %7B stroke: %23fff; opacity: 0.3; %7D .cls-2 %7B fill: %23fff; %7D .cls-3 %7B stroke: none; %7D %3C/style%3E%3C/defs%3E%3Cg id='사각형_703' data-name='사각형 703' class='cls-1'%3E%3Crect class='cls-3' width='16' height='16' rx='3'/%3E%3Crect class='cls-4' x='0.5' y='0.5' width='15' height='15' rx='2.5'/%3E%3C/g%3E%3Crect id='사각형_1384' data-name='사각형 1384' class='cls-2' width='8' height='1' rx='0.5' transform='translate(4 4.5)'/%3E%3Crect id='사각형_1386' data-name='사각형 1386' class='cls-2' width='8' height='1' rx='0.5' transform='translate(4 7.5)'/%3E%3Crect id='사각형_1387' data-name='사각형 1387' class='cls-2' width='8' height='1' rx='0.5' transform='translate(4 10.5)'/%3E%3C/svg%3E%0A");
|
||||||
|
} @else {
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg id='ico_tree_item' xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cdefs%3E%3Cstyle%3E .cls-2%7Bfill:%23a4aac3%7D %3C/style%3E%3C/defs%3E%3Cg id='사각형_703' data-name='사각형 703' style='stroke:%23a4aac3;fill:none'%3E%3Crect width='16' height='16' rx='3' style='stroke:none'/%3E%3Crect x='.5' y='.5' width='15' height='15' rx='2.5' style='fill:none'/%3E%3C/g%3E%3Crect id='사각형_1384' data-name='사각형 1384' class='cls-2' width='8' height='1' rx='.5' transform='translate(4 4.5)'/%3E%3Crect id='사각형_1386' data-name='사각형 1386' class='cls-2' width='8' height='1' rx='.5' transform='translate(4 7.5)'/%3E%3Crect id='사각형_1387' data-name='사각형 1387' class='cls-2' width='8' height='1' rx='.5' transform='translate(4 10.5)'/%3E%3C/svg%3E%0A");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tree-button-expand {
|
||||||
|
.tui-grid-btn-tree {
|
||||||
|
i {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background-position: 0 0;
|
||||||
|
@if $theme == dark {
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg id='btn_tree_item_close' xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cdefs%3E%3Cstyle%3E .cls-1 %7B fill: %230d0f17; stroke: %23fff; opacity: 0.3; %7D .cls-2 %7B fill: %23fff; %7D .cls-3 %7B stroke: none; %7D .cls-4 %7B fill: none; %7D %3C/style%3E%3C/defs%3E%3Cg id='사각형_703' data-name='사각형 703' class='cls-1'%3E%3Crect class='cls-3' width='16' height='16' rx='3'/%3E%3Crect class='cls-4' x='0.5' y='0.5' width='15' height='15' rx='2.5'/%3E%3C/g%3E%3Crect id='사각형_1384' data-name='사각형 1384' class='cls-2' width='8' height='2' rx='1' transform='translate(4 7)'/%3E%3C/svg%3E%0A");
|
||||||
|
} @else {
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cg data-name='사각형 703' style='fill:%23f1f3f9;stroke:%23a4aac3'%3E%3Crect width='16' height='16' rx='3' style='stroke:none'/%3E%3Crect x='.5' y='.5' width='15' height='15' rx='2.5' style='fill:none'/%3E%3C/g%3E%3Crect data-name='사각형 1384' width='8' height='2' rx='1' transform='translate(4 7)' style='fill:%23a4aac3'/%3E%3C/svg%3E ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tree-button-collapse {
|
||||||
|
.tui-grid-btn-tree {
|
||||||
|
i {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background-position: 0 0;
|
||||||
|
@if $theme == dark {
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg id='btn_tree_item_open' xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cdefs%3E%3Cstyle%3E .cls-2%7Bfill:%23fff%7D %3C/style%3E%3C/defs%3E%3Cg id='사각형_703' data-name='사각형 703' style='fill:%230d0f17;stroke:%23fff;opacity:.3'%3E%3Crect width='16' height='16' rx='3' style='stroke:none'/%3E%3Crect x='.5' y='.5' width='15' height='15' rx='2.5' style='fill:none'/%3E%3C/g%3E%3Crect id='사각형_1384' data-name='사각형 1384' class='cls-2' width='8' height='2' rx='1' transform='translate(4 7)'/%3E%3Crect id='사각형_1385' data-name='사각형 1385' class='cls-2' width='2' height='8' rx='1' transform='translate(7 4)'/%3E%3C/svg%3E%0A");
|
||||||
|
} @else {
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg id='btn_tree_item_open' xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cdefs%3E%3Cstyle%3E .cls-2%7Bfill:%23a4aac3%7D %3C/style%3E%3C/defs%3E%3Cg id='사각형_703' data-name='사각형 703' style='fill:%23f1f3f9;stroke:%23a4aac3'%3E%3Crect width='16' height='16' rx='3' style='stroke:none'/%3E%3Crect x='.5' y='.5' width='15' height='15' rx='2.5' style='fill:none'/%3E%3C/g%3E%3Crect id='사각형_1384' data-name='사각형 1384' class='cls-2' width='8' height='2' rx='1' transform='translate(4 7)'/%3E%3Crect id='사각형_1385' data-name='사각형 1385' class='cls-2' width='2' height='8' rx='1' transform='translate(7 4)'/%3E%3C/svg%3E ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tree-button-expand,
|
||||||
|
&-tree-button-collapse {
|
||||||
|
.tui-grid-tree-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-frozen-border {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*="tui-grid-tree-wrapper"] {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
257
assets/scss/common/input.scss
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
.v-select__custom {
|
||||||
|
&.v-text-field.v-text-field--solo:not(.v-text-field--solo-flat)
|
||||||
|
> .v-input__control
|
||||||
|
> .v-input__slot {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
&.v-text-field.v-text-field--solo .v-input__control {
|
||||||
|
min-height: 36px;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
&.v-input input {
|
||||||
|
min-height: 36px;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-input--selection-controls {
|
||||||
|
margin-top: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
.v-input__slot {
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
height: 36px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-input__custom {
|
||||||
|
.v-input__slot {
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.v-input__slot {
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-text-field .v-input__append-inner,
|
||||||
|
.v-text-field .v-input__prepend-inner {
|
||||||
|
align-self: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.v-select__widget {
|
||||||
|
&.v-text-field.v-text-field--solo:not(.v-text-field--solo-flat)
|
||||||
|
> .v-input__control
|
||||||
|
> .v-input__slot {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
&.v-text-field.v-text-field--solo .v-input__control {
|
||||||
|
min-height: 30px !important;
|
||||||
|
height: 30px !important;
|
||||||
|
}
|
||||||
|
&.v-input input {
|
||||||
|
min-height: 30px !important;
|
||||||
|
height: 30px !important;
|
||||||
|
}
|
||||||
|
&.v-text-field--outlined > .v-input__control > .v-input__slot {
|
||||||
|
align-items: stretch;
|
||||||
|
min-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-input--selection-controls {
|
||||||
|
margin-top: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
.v-input__slot {
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
height: 30px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.size {
|
||||||
|
&-mini {
|
||||||
|
width: 110px;
|
||||||
|
height: 30px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
&.v-text-field.v-text-field--solo .v-input__control {
|
||||||
|
min-height: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.v-text-field > .v-input__control > .v-input__slot:after,
|
||||||
|
.v-text-field > .v-input__control > .v-input__slot:before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-input__slot {
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
.v-input {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
padding-top: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-input__append-inner {
|
||||||
|
.v-icon {
|
||||||
|
color: currentColor !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $theme in dark, light {
|
||||||
|
@include theme($theme);
|
||||||
|
.v-application.#{$theme}-mode {
|
||||||
|
.v-input {
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
&:not(.v-input--radio-group, .v-input--checkbox) {
|
||||||
|
.v-input__slot {
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-input-backgroundColor"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.v-input__slot {
|
||||||
|
fieldset {
|
||||||
|
color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-input-fieldset-color"
|
||||||
|
) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
fieldset {
|
||||||
|
color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-input-fieldset-hover-color"
|
||||||
|
) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-input__append-inner {
|
||||||
|
color: map-deep-get($config, #{$theme}, "v-input-icon-color");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--is-readonly {
|
||||||
|
border-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-input-readonly-border-color"
|
||||||
|
);
|
||||||
|
&:not(.v-input--radio-group, .v-input--checkbox) {
|
||||||
|
.v-input__slot {
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-input-readonly-backgroundColor"
|
||||||
|
) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--is-disabled {
|
||||||
|
border-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-input-readonly-border-color"
|
||||||
|
);
|
||||||
|
&:not(.v-input--radio-group, .v-input--checkbox) {
|
||||||
|
.v-input__slot {
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-input-disabled-backgroundColor"
|
||||||
|
) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
color: map-deep-get($config, #{$theme}, "v-input-disabled-color");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-select {
|
||||||
|
.v-label {
|
||||||
|
color: map-deep-get($config, #{$theme}, "v-select-label-color");
|
||||||
|
}
|
||||||
|
|
||||||
|
&.v-input--is-disabled {
|
||||||
|
.v-label {
|
||||||
|
color: map-deep-get($config, #{$theme}, "v-input-disabled-color");
|
||||||
|
}
|
||||||
|
.v-icon.v-icon--disabled {
|
||||||
|
color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-input-disabled-color"
|
||||||
|
) !important;
|
||||||
|
}
|
||||||
|
.v-select__selection--disabled {
|
||||||
|
color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-input-disabled-color"
|
||||||
|
) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-radio {
|
||||||
|
.v-label {
|
||||||
|
color: map-deep-get($config, #{$theme}, "non-activate");
|
||||||
|
}
|
||||||
|
&.v-item--active {
|
||||||
|
.v-label {
|
||||||
|
color: map-deep-get($config, #{$theme}, "activate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-radio {
|
||||||
|
.v-icon {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-label {
|
||||||
|
color: map-deep-get($config, #{$theme}, "non-activate");
|
||||||
|
}
|
||||||
|
|
||||||
|
&.v-item--active {
|
||||||
|
.v-icon {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-label {
|
||||||
|
color: map-deep-get($config, #{$theme}, "activate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-input--checkbox {
|
||||||
|
.v-icon {
|
||||||
|
@if $theme == dark {
|
||||||
|
color: rgba(255, 255, 255, 0.6);
|
||||||
|
} @else {
|
||||||
|
color: #aaaaaa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-textarea{
|
||||||
|
textarea{
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
assets/scss/common/numericInput.scss
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
.vue-numeric-input {
|
||||||
|
min-height:36px;
|
||||||
|
}
|
||||||
|
.vue-numeric-input .numeric-input {
|
||||||
|
font-size: 14px;
|
||||||
|
border-radius: 4px;
|
||||||
|
height:100%;
|
||||||
|
border-color: rgba(255, 255, 255, 0.4);
|
||||||
|
background: rgba(57, 64, 94, 0.3);
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
border-color: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.vue-numeric-input.updown .btn-decrement .btn-icon {
|
||||||
|
border-color: #fff transparent #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vue-numeric-input.updown .btn-increment .btn-icon{
|
||||||
|
border-color: transparent transparent #fff !important;
|
||||||
|
}
|
88
assets/scss/common/tabs.scss
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
// .v-tabs {
|
||||||
|
// height: 38px;
|
||||||
|
// flex: 0;
|
||||||
|
// & + .v-tabs-items {
|
||||||
|
// height: calc(100% - 38px) !important;
|
||||||
|
// width: 100%;
|
||||||
|
// background-color: transparent !important;
|
||||||
|
// }
|
||||||
|
// &-bar {
|
||||||
|
// height: 38px;
|
||||||
|
// background-color: transparent !important;
|
||||||
|
// border-bottom: 1px solid $--color-hover_d;
|
||||||
|
// }
|
||||||
|
// .v-tab {
|
||||||
|
// margin: 0 !important;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
@each $theme in dark, light {
|
||||||
|
.v-application.#{$theme}-mode {
|
||||||
|
.v-tabs {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
.v-slide-group__wrapper {
|
||||||
|
overflow: visible !important;
|
||||||
|
contain: initial !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-tab {
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 6px 6px 0 0;
|
||||||
|
border-bottom-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-tabs-active-border-color"
|
||||||
|
);
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-tabs-backgroundColor"
|
||||||
|
);
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
transform: translateY(1px);
|
||||||
|
letter-spacing: 0;
|
||||||
|
+ .v-tab {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-tab--active {
|
||||||
|
border-top-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-tabs-active-border-color"
|
||||||
|
);
|
||||||
|
border-right-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-tabs-active-border-color"
|
||||||
|
);
|
||||||
|
border-left-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-tabs-active-border-color"
|
||||||
|
);
|
||||||
|
border-bottom-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-tabs-active-backgroundColor"
|
||||||
|
);
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
"v-tabs-active-backgroundColor"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.v-tabs-items {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
border-top: 1px
|
||||||
|
solid
|
||||||
|
map-deep-get($config, #{$theme}, "v-tabs-active-border-color");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
98
assets/scss/common/text.scss
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
.txt {
|
||||||
|
&__bar {
|
||||||
|
display: flex;
|
||||||
|
&:before {
|
||||||
|
content: "";
|
||||||
|
display: inline-block;
|
||||||
|
width: 2px;
|
||||||
|
height: 14px;
|
||||||
|
background-color: #ccc;
|
||||||
|
margin-right: 8px;
|
||||||
|
position: relative;
|
||||||
|
top: 3px;
|
||||||
|
}
|
||||||
|
&.log {
|
||||||
|
&:before {
|
||||||
|
background-color: $--color-primary__green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-title-1 {
|
||||||
|
font-size: 2.5rem; // 40px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-title-2 {
|
||||||
|
font-size: 1.75rem; // 28px
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-title-2-5 {
|
||||||
|
font-size: 1.5rem; // 28px
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-title-3 {
|
||||||
|
font-size: 1.15rem; // 28px
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-title-4 {
|
||||||
|
font-size: 1.125rem !important;
|
||||||
|
font-weight: 700 !important;
|
||||||
|
line-height: 1.25 !important;
|
||||||
|
}
|
||||||
|
.custom-title-6 {
|
||||||
|
font-size: 1.0rem !important;
|
||||||
|
font-weight: 700 !important;
|
||||||
|
line-height: 1.25 !important;
|
||||||
|
}
|
||||||
|
.custom-title-8 {
|
||||||
|
font-size: 0.75rem !important;
|
||||||
|
font-weight: 700 !important;
|
||||||
|
line-height: 1.0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-text-1 {
|
||||||
|
font-size: 1.125rem; // 18px;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-text-2 {
|
||||||
|
opacity: 0.6;
|
||||||
|
font-family: SpoqaHanSansNeo;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
font-stretch: normal;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: 2.17;
|
||||||
|
letter-spacing: normal;
|
||||||
|
text-align: right;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-color--white-0 {
|
||||||
|
color: map-deep-get($color, "white", "0") !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $theme in dark, light {
|
||||||
|
.v-application.#{$theme}-mode {
|
||||||
|
.text-color--activate {
|
||||||
|
color: map-deep-get($config, #{$theme}, "activate");
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-color--non-activate {
|
||||||
|
color: map-deep-get($config, #{$theme}, "non-activate");
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-color--sub {
|
||||||
|
color: map-deep-get($config, #{$theme}, "text-subcolor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
assets/scss/functions.scss
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
@function setStyle($map, $object, $style) {
|
||||||
|
@if map-has-key($map, $object) {
|
||||||
|
@return map-get(map-get($map, $object), $style);
|
||||||
|
}
|
||||||
|
@warn "The key ´#{$object} is not available in the map.";
|
||||||
|
@return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Map deep get
|
||||||
|
/// @author Kitty Giraudel
|
||||||
|
/// @access public
|
||||||
|
/// @param {Map} $map - Map
|
||||||
|
/// @param {Arglist} $keys - Key chain
|
||||||
|
/// @return {*} - Desired value
|
||||||
|
|
||||||
|
@function map-deep-get($map, $keys...) {
|
||||||
|
@each $key in $keys {
|
||||||
|
$map: map-get($map, $key);
|
||||||
|
}
|
||||||
|
@return $map;
|
||||||
|
}
|
15
assets/scss/mixin.scss
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
@import './var.scss';
|
||||||
|
@import './functions.scss';
|
||||||
|
@mixin theme($key) {
|
||||||
|
$--theme-font-color: #{setStyle($config, $key, fontColor)} !global;
|
||||||
|
$--theme-bg-page: #{setStyle($config, $key, pageBackground)} !global;
|
||||||
|
$--theme-bg-card: #{setStyle($config, $key, cardBackground)} !global;
|
||||||
|
$--theme-hover-color: #{setStyle($config, $key, hover)} !global;
|
||||||
|
$--theme-button-close-color: #{setStyle($config, $key, btnClose)} !global;
|
||||||
|
$--theme-color-w-g5: #{setStyle($config, $key, w-g5)} !global;
|
||||||
|
$--theme-color-g5-w: #{setStyle($config, $key, g5-w)} !global;
|
||||||
|
$--theme-color-gc-g9: #{setStyle($config, $key, gc-g9)} !global;
|
||||||
|
$--theme-color-g5-gc: #{setStyle($config, $key, g5-gc)} !global;
|
||||||
|
$--theme-color-g7-g9: #{setStyle($config, $key, g7-g9)} !global;
|
||||||
|
$--theme-color-g9-g7: #{setStyle($config, $key, g9-g7)} !global;
|
||||||
|
}
|
15
assets/scss/theme.scss
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// @import './var.scss';
|
||||||
|
// @import './functions.scss';
|
||||||
|
// @import './mixin.scss';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// @each $theme in dark, light{
|
||||||
|
// @include theme($theme);
|
||||||
|
// .v-application.#{$theme}-mode{
|
||||||
|
// span {
|
||||||
|
// color: $--theme-font-color;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
210
assets/scss/var.scss
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
$--color-primary__blue: #278bff !important;
|
||||||
|
$--color-primary__green: #26bf6b !important;
|
||||||
|
$--color-sub__yellow: #ff9541 !important;
|
||||||
|
$--color-warning__red: #ff5050 !important;
|
||||||
|
$--color-white: #fff !important;
|
||||||
|
$--color-black: #333 !important;
|
||||||
|
$--color-gray_C: #cccccc !important;
|
||||||
|
$--color-gray_9: #95a0a9 !important;
|
||||||
|
$--color-gray_7: #767d83 !important;
|
||||||
|
$--color-gray_999: #999 !important;
|
||||||
|
$--color-gray_555: #555 !important;
|
||||||
|
$--color-gray_aaa: #aaa !important;
|
||||||
|
$--color-hover_d: #47535c !important;
|
||||||
|
$--color-hover_l: #f0f5fc !important;
|
||||||
|
|
||||||
|
$--theme-font-color: "";
|
||||||
|
$--theme-bg-page: "";
|
||||||
|
$--theme-bg-card: "";
|
||||||
|
$--theme-hover-color: "";
|
||||||
|
$--theme-button-close-color: "";
|
||||||
|
$--theme-color-w-g5: "";
|
||||||
|
$--theme-color-gc-g9: "";
|
||||||
|
$--theme-color-g5-gc: "";
|
||||||
|
$--theme-color-g7-g9: "";
|
||||||
|
$--theme-color-g9-g7: "";
|
||||||
|
|
||||||
|
$scrollbar-width: 11px; // 스크롤 바
|
||||||
|
$column-spacer: 20px; // 검색 영역 열 간격
|
||||||
|
$row-spacer: 14px; // 검색 영역 행 간격
|
||||||
|
|
||||||
|
$color: (
|
||||||
|
"black": (
|
||||||
|
"0": #000,
|
||||||
|
"1": #111
|
||||||
|
),
|
||||||
|
"white": (
|
||||||
|
"0": #fff
|
||||||
|
),
|
||||||
|
"week": (
|
||||||
|
"sun": #fb5a83,
|
||||||
|
"sat": #2d8cf6
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$config: (
|
||||||
|
dark: (
|
||||||
|
w-g5: $--color-white,
|
||||||
|
g5-w: $--color-gray_555,
|
||||||
|
gc-g9: $--color-gray_C,
|
||||||
|
g5-gc: $--color-gray_555,
|
||||||
|
g7-g9: $--color-gray_7,
|
||||||
|
g9-g7: $--color-gray_9,
|
||||||
|
pageBackground: #23272b,
|
||||||
|
cardBackground: #242940,
|
||||||
|
hover: #47535c,
|
||||||
|
btnClose: #24282c,
|
||||||
|
scrollbar-track: #2f334a,
|
||||||
|
scrollbar-thumb: #575b72,
|
||||||
|
card-default-color: #fff,
|
||||||
|
card-subtitle: rgba(255, 255, 255, 0.6),
|
||||||
|
activate: #fff,
|
||||||
|
non-activate: rgba(255, 255, 255, 0.6),
|
||||||
|
text-subcolor: rgba(255, 255, 255, 0.6),
|
||||||
|
border-color: rgba(255, 255, 255, 0.1),
|
||||||
|
router-header: #1d2133,
|
||||||
|
router-tab-item: #2d3355,
|
||||||
|
router-tab-item-active: #18579e,
|
||||||
|
router-tab-item-color: #fff,
|
||||||
|
router-tab-item-active-color: #fff,
|
||||||
|
router-tab-item-icon-color: rgba(255, 255, 255, 0.5),
|
||||||
|
router-tab-item-icon-active-color: #fff,
|
||||||
|
router-tab-item-hover-color: #3896ff,
|
||||||
|
router-tab-slot-end-button-backgroundColor: #144985,
|
||||||
|
v-btn-backgroundColor: #144985,
|
||||||
|
v-box: #383f5d,
|
||||||
|
v-banner-border-color: rgba(255, 255, 255, 0.1),
|
||||||
|
v-treeview-node-root-backgroundColor: #18579e,
|
||||||
|
v-treeview-node-root-label-color: #fff,
|
||||||
|
v-treeview-node-root-label-active-color: #fff,
|
||||||
|
v-treeview-node-root-icon-color: #fff,
|
||||||
|
v-treeview-node-root-icon-active-color: #fff,
|
||||||
|
v-treeview-node-subroot-backgroundColor: #2d3355,
|
||||||
|
v-treeview-node-label-color: rgba(255, 255, 255, 0.6),
|
||||||
|
v-treeview-node-label-active-color: #fff,
|
||||||
|
v-treeview-leaf-active-backgroundColor: rgba(45, 51, 85, 0.5),
|
||||||
|
v-treeview-leaf-active-color: #3896ff,
|
||||||
|
v-treeview-icon-color: rgba(255, 255, 255, 0.6),
|
||||||
|
v-treeview-icon-active-color: #fff,
|
||||||
|
v-input-backgroundColor: rgba(13, 15, 23, 0.3),
|
||||||
|
v-input-fieldset-color: rgba(255, 255, 255, 0.32),
|
||||||
|
v-input-fieldset-hover-color: rgba(255, 255, 255, 1),
|
||||||
|
v-input-icon-color: #fff,
|
||||||
|
v-input-readonly-border-color: rgba(255, 255, 255, 0.3),
|
||||||
|
v-input-readonly-backgroundColor: rgba(57, 64, 94, 0.3),
|
||||||
|
v-input-disabled-backgroundColor: rgba(57, 64, 94, 0.3),
|
||||||
|
v-input-disabled-color: rgba(255, 255, 255, 0.2),
|
||||||
|
v-select-label-color: #fff,
|
||||||
|
v-calendar-weekday-backgroundColor: #383f5d,
|
||||||
|
v-calendar-weekday-color: #fff,
|
||||||
|
v-calendar-weekday-border-color: rgba(255, 255, 255, 0.1),
|
||||||
|
v-calendar-day-color: #fff,
|
||||||
|
v-calendar-day-in-not-month-color: rgba(255, 255, 255, 0.05),
|
||||||
|
v-calendar-is-today-background-color: #2d4571,
|
||||||
|
tui-grid-header-backgroundColor: #383f5d,
|
||||||
|
tui-grid-border-horziontal-color: #383f5d,
|
||||||
|
tui-grid-border-vertical-color: rgba(255, 255, 255, 0.1),
|
||||||
|
tui-grid-cell-backgroundColor: #242940,
|
||||||
|
tui-grid-cell-color: #fff,
|
||||||
|
tui-grid-cell-insert-color: #13636c,
|
||||||
|
tui-grid-cell-selected-color: #1a4e87,
|
||||||
|
tui-grid-cell-modify-color: #13636c,
|
||||||
|
tui-grid-cell-removed-color: #f6637b,
|
||||||
|
tui-grid-cell-disabled-color: rgb(170, 170, 170),
|
||||||
|
tui-grid-cell-hover-backgroundColor: #31375b,
|
||||||
|
v-tabs-items-border-color: rgba(255, 255, 255, 0.7),
|
||||||
|
v-tabs-backgroundColor: rgba(57, 64, 94, 0.5),
|
||||||
|
v-tabs-active-backgroundColor: #242940,
|
||||||
|
v-tabs-active-border-color: rgba(255, 255, 255, 0.7),
|
||||||
|
v-dialog-card-text-color: #fff,
|
||||||
|
tui-datepicker-backgroundColor: #0d0f17,
|
||||||
|
tui-datepicker-border-color: rgba(255, 255, 255, 0.3),
|
||||||
|
tui-datepicker-selectable-hover-color: #2d3355,
|
||||||
|
tui-datepicker-selected-color: #1a4e87,
|
||||||
|
tui-datepicker-calendar-color: #fff,
|
||||||
|
tui-editor-contents-color: #111,
|
||||||
|
admin-menu-expanded-list-backgroundColor: #144985
|
||||||
|
),
|
||||||
|
light: (
|
||||||
|
w-g5: $--color-gray_555,
|
||||||
|
g5-w: $--color-white,
|
||||||
|
gc-g9: $--color-gray_999,
|
||||||
|
g5-gc: $--color-gray_C,
|
||||||
|
g7-g9: $--color-gray_9,
|
||||||
|
g9-g7: $--color-gray_7,
|
||||||
|
fontColor: #333,
|
||||||
|
pageBackground: #ececef,
|
||||||
|
cardBackground: #fefefe,
|
||||||
|
hover: #f0f5fc,
|
||||||
|
btnClose: #f1f0f8,
|
||||||
|
scrollbar-track: #e9e9e9,
|
||||||
|
scrollbar-thumb: #bbbbbb,
|
||||||
|
card-default-color: #111,
|
||||||
|
card-subtitle: #555,
|
||||||
|
activate: #111,
|
||||||
|
non-activate: #555,
|
||||||
|
text-subcolor: #999,
|
||||||
|
border-color: #ddd,
|
||||||
|
router-header: #fff,
|
||||||
|
router-tab-item: #e1e7f3,
|
||||||
|
router-tab-item-active: #4777d9,
|
||||||
|
router-tab-item-color: #111,
|
||||||
|
router-tab-item-active-color: #fff,
|
||||||
|
router-tab-item-icon-color: #838aa6,
|
||||||
|
router-tab-item-icon-active-color: #fff,
|
||||||
|
router-tab-item-hover-color: #366dbe,
|
||||||
|
router-tab-slot-end-button-backgroundColor: #3f4d7d,
|
||||||
|
v-btn-backgroundColor: #4777d9,
|
||||||
|
v-box: #f0f3fa,
|
||||||
|
v-banner-border-color: #ddd,
|
||||||
|
v-treeview-node-root-backgroundColor: #4777d9,
|
||||||
|
v-treeview-node-root-label-color: #111,
|
||||||
|
v-treeview-node-root-label-active-color: #fff,
|
||||||
|
v-treeview-node-root-icon-color: #555,
|
||||||
|
v-treeview-node-root-icon-active-color: #fff,
|
||||||
|
v-treeview-node-subroot-backgroundColor: #e1e7f3,
|
||||||
|
v-treeview-node-label-color: #555,
|
||||||
|
v-treeview-node-label-active-color: #111,
|
||||||
|
v-treeview-leaf-active-backgroundColor: #edf1f7,
|
||||||
|
v-treeview-leaf-active-color: #366dbe,
|
||||||
|
v-treeview-icon-color: #a4aac3,
|
||||||
|
v-treeview-icon-active-color: #616885,
|
||||||
|
v-input-backgroundColor: #ffffff,
|
||||||
|
v-input-fieldset-color: #b4b8c9,
|
||||||
|
v-input-fieldset-hover-color: #b4b8c9,
|
||||||
|
v-input-icon-color: #555,
|
||||||
|
v-input-readonly-border-color: #b4b8c9,
|
||||||
|
v-input-readonly-backgroundColor: #f5f5f5,
|
||||||
|
v-input-disabled-backgroundColor: #eee,
|
||||||
|
v-input-disabled-color: #bbb,
|
||||||
|
v-select-label-color: #111,
|
||||||
|
v-calendar-weekday-backgroundColor: #e0e0e0,
|
||||||
|
v-calendar-weekday-color: #111,
|
||||||
|
v-calendar-weekday-border-color: #d4d4d4,
|
||||||
|
v-calendar-day-color: #111,
|
||||||
|
v-calendar-day-in-not-month-color: #f8f8f8,
|
||||||
|
v-calendar-is-today-background-color: #e3eaf3,
|
||||||
|
tui-grid-header-backgroundColor: #e0e0e0,
|
||||||
|
tui-grid-border-horziontal-color: #e0e0e0,
|
||||||
|
tui-grid-border-vertical-color: #d4d4d4,
|
||||||
|
tui-grid-cell-backgroundColor: #fff,
|
||||||
|
tui-grid-cell-color: #555,
|
||||||
|
tui-grid-cell-insert-color: #13636c,
|
||||||
|
tui-grid-cell-selected-color: #ecf2fa,
|
||||||
|
tui-grid-cell-modify-color: #e6f5f7,
|
||||||
|
tui-grid-cell-removed-color: #fddde1,
|
||||||
|
tui-grid-cell-hover-backgroundColor: #f5f5f5,
|
||||||
|
v-tabs-items-border-color: #989db1,
|
||||||
|
v-tabs-backgroundColor: #ddd,
|
||||||
|
v-tabs-active-backgroundColor: #fff,
|
||||||
|
v-tabs-active-border-color: #989db1,
|
||||||
|
v-dialog-card-text-color: #111,
|
||||||
|
tui-datepicker-backgroundColor: #fff,
|
||||||
|
tui-datepicker-border-color: #b4b8c9,
|
||||||
|
tui-datepicker-selectable-hover-color: #e1e7f3,
|
||||||
|
tui-datepicker-selected-color: #4777d9,
|
||||||
|
tui-datepicker-calendar-color: #111,
|
||||||
|
tui-editor-contents-color: #111,
|
||||||
|
admin-menu-expanded-list-backgroundColor: #3f4d7d
|
||||||
|
)
|
||||||
|
);
|
56
assets/variables.scss
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Ref: https://github.com/nuxt-community/vuetify-module#customvariables
|
||||||
|
//
|
||||||
|
// The variables you want to modify
|
||||||
|
// $font-size-root: 20px;
|
||||||
|
$body-font-family: "Spoqa Han Sans Neo", "Roboto", "sans-serif" !default;
|
||||||
|
$grid-gutter: 10px;
|
||||||
|
$material-dark: (
|
||||||
|
"background": #383f5d,
|
||||||
|
"cards": #242940,
|
||||||
|
"navigation-drawer": #1a1d2d,
|
||||||
|
"chips": rgba(255, 255, 255, 0.1)
|
||||||
|
);
|
||||||
|
|
||||||
|
$material-light: (
|
||||||
|
"background": #f0f3fa,
|
||||||
|
"cards": #fff,
|
||||||
|
"navigation-drawer": #fff,
|
||||||
|
"chips": #eee
|
||||||
|
);
|
||||||
|
|
||||||
|
$treeview-node-padding: 10px;
|
||||||
|
$treeview-node-height: 40px;
|
||||||
|
|
||||||
|
$banner-start-padding: 10px;
|
||||||
|
$banner-end-padding: 10px;
|
||||||
|
$banner-y-padding: 12px;
|
||||||
|
|
||||||
|
$card-border-radius: 10px;
|
||||||
|
$card-title-font-size: 1.25rem;
|
||||||
|
$card-title-font-weight: 700;
|
||||||
|
$card-title-line-height: 1.5;
|
||||||
|
$card-subtitle-padding: 20px;
|
||||||
|
|
||||||
|
$timeline-dot-small-size: 10px;
|
||||||
|
|
||||||
|
$data-table-regular-row-height: 36px;
|
||||||
|
|
||||||
|
$input-font-size: 14px;
|
||||||
|
$input-max-height: 36px;
|
||||||
|
$text-field-filled-full-width-outlined-slot-min-height: 36px;
|
||||||
|
$text-field-solo-control-min-height: 36px;
|
||||||
|
$text-field-line-height: 1.285;
|
||||||
|
$text-field-enclosed-prepend-append-margin-top: 0;
|
||||||
|
$text-field-enclosed-details-padding: 0 8px;
|
||||||
|
|
||||||
|
$tab-font-size: 1rem; // 16px;
|
||||||
|
$tab-font-weight: 400;
|
||||||
|
$tabs-bar-height: 45px;
|
||||||
|
$tabs-item-padding: 12px;
|
||||||
|
|
||||||
|
$list-border-radius: 4px;
|
||||||
|
$list-padding: 0;
|
||||||
|
$list-item-min-height: 36px;
|
||||||
|
$list-item-padding: 0;
|
||||||
|
$list-item-title-font-size: 0.875rem; // 14px;
|
||||||
|
$list-item-content-padding: 10px 7px;
|
79
components/Logo.vue
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<template>
|
||||||
|
<div class="VueToNuxtLogo">
|
||||||
|
<div class="Triangle Triangle--two" />
|
||||||
|
<div class="Triangle Triangle--one" />
|
||||||
|
<div class="Triangle Triangle--three" />
|
||||||
|
<div class="Triangle Triangle--four" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.VueToNuxtLogo {
|
||||||
|
display: inline-block;
|
||||||
|
animation: turn 2s linear forwards 1s;
|
||||||
|
transform: rotateX(180deg);
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 180px;
|
||||||
|
width: 245px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Triangle {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Triangle--one {
|
||||||
|
border-left: 105px solid transparent;
|
||||||
|
border-right: 105px solid transparent;
|
||||||
|
border-bottom: 180px solid #41b883;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Triangle--two {
|
||||||
|
top: 30px;
|
||||||
|
left: 35px;
|
||||||
|
animation: goright 0.5s linear forwards 3.5s;
|
||||||
|
border-left: 87.5px solid transparent;
|
||||||
|
border-right: 87.5px solid transparent;
|
||||||
|
border-bottom: 150px solid #3b8070;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Triangle--three {
|
||||||
|
top: 60px;
|
||||||
|
left: 35px;
|
||||||
|
animation: goright 0.5s linear forwards 3.5s;
|
||||||
|
border-left: 70px solid transparent;
|
||||||
|
border-right: 70px solid transparent;
|
||||||
|
border-bottom: 120px solid #35495e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Triangle--four {
|
||||||
|
top: 120px;
|
||||||
|
left: 70px;
|
||||||
|
animation: godown 0.5s linear forwards 3s;
|
||||||
|
border-left: 35px solid transparent;
|
||||||
|
border-right: 35px solid transparent;
|
||||||
|
border-bottom: 60px solid #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes turn {
|
||||||
|
100% {
|
||||||
|
transform: rotateX(0deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes godown {
|
||||||
|
100% {
|
||||||
|
top: 180px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes goright {
|
||||||
|
100% {
|
||||||
|
left: 70px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
209
components/Pagination.vue
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
<template>
|
||||||
|
<div class="ly-pager d-flex">
|
||||||
|
<v-row class="con-pager" align="center" justify="start">
|
||||||
|
<!-- <span class="grey--text">{{ $m('CAP.PAGE_ROW', '페이지 행당') }} : </span> -->
|
||||||
|
<v-menu offset-y>
|
||||||
|
<template #activator="{ on, attrs }">
|
||||||
|
<v-btn
|
||||||
|
dark
|
||||||
|
text
|
||||||
|
color="primary"
|
||||||
|
class="ml-2"
|
||||||
|
v-bind="attrs"
|
||||||
|
v-on="on"
|
||||||
|
>
|
||||||
|
{{ itemsPerPage }}
|
||||||
|
<v-icon>mdi-chevron-down</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
<v-list v-if="useLimit">
|
||||||
|
<v-list-item
|
||||||
|
v-for="(number, index) in itemsPerPageArray"
|
||||||
|
:key="index"
|
||||||
|
@click="changePageLeng(number)"
|
||||||
|
>
|
||||||
|
<v-list-item-title>{{ number }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
<v-btn fab small class="mr-1 btn-pager" @click="firstToPage">
|
||||||
|
<v-icon>mdi-chevron-double-left</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
<v-btn fab small class="mr-1 btn-pager" @click="prevPage">
|
||||||
|
<v-icon>mdi-chevron-left</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
<!-- <span class="mr-4 grey--text mr-1"> {{ numberOfPages }} / {{ lastPage }} </span> -->
|
||||||
|
<span class="mr-4 mr-1"> {{ numberOfPages }} / {{ lastPage }} </span>
|
||||||
|
<v-btn fab small class="ml-1 btn-pager" @click="nextPage">
|
||||||
|
<v-icon>mdi-chevron-right</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
<v-btn fab small class="mr-1 btn-pager" @click="lastToPage">
|
||||||
|
<v-icon>mdi-chevron-double-right</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
<div class="mr-1 btn-pager">
|
||||||
|
<v-text-field v-model="moveToPage" type="number" label="page" />
|
||||||
|
</div>
|
||||||
|
<v-btn fab small class="mr-1" @click="movePage">
|
||||||
|
{{ $m('CAP.MOVE', '이동') }}
|
||||||
|
</v-btn>
|
||||||
|
</v-row>
|
||||||
|
<slot name="btn"> </slot>
|
||||||
|
<!-- <Alert ref="alert" /> -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
useLimit: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
totalCount: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
pageNum: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
limit: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
itemsPerPageArray: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [20, 50, 100],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
moveToPage: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
page: function() {
|
||||||
|
return this.numberOfPages + '-' + this.lastPage;
|
||||||
|
},
|
||||||
|
lastPage: function() {
|
||||||
|
//grid data가 없을 경우 1 리턴
|
||||||
|
if (this.totalCount == 0) return 1;
|
||||||
|
|
||||||
|
let pageLength = Math.floor(this.totalCount / this.itemsPerPage);
|
||||||
|
if (this.totalCount % this.itemsPerPage > 0) {
|
||||||
|
pageLength++;
|
||||||
|
}
|
||||||
|
return pageLength;
|
||||||
|
},
|
||||||
|
itemsPerPage: function() {
|
||||||
|
return this.limit;
|
||||||
|
},
|
||||||
|
numberOfPages: function() {
|
||||||
|
return Number(this.pageNum);
|
||||||
|
},
|
||||||
|
plusPage: function() {
|
||||||
|
return Number(this.pageNum) + 1;
|
||||||
|
},
|
||||||
|
minusPage: function() {
|
||||||
|
return Number(this.pageNum) - 1;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
totalCount: function(newData) {
|
||||||
|
return (this.moveToPage = newData > 0 ? this.moveToPage : '');
|
||||||
|
},
|
||||||
|
|
||||||
|
moveToPage: function() {
|
||||||
|
return (this.moveToPage = this.moveToPage.replaceAll(/[^0-9]/g, ''));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
nextPage: function() {
|
||||||
|
if (this.lastPage >= this.plusPage) {
|
||||||
|
this.$emit('loadData', this.plusPage, this.itemsPerPage);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
prevPage: function() {
|
||||||
|
if (0 != this.minusPage) {
|
||||||
|
this.$emit('loadData', this.minusPage, this.itemsPerPage);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
movePage: function() {
|
||||||
|
if (0 < this.moveToPage && this.moveToPage <= this.lastPage) {
|
||||||
|
this.$emit('loadData', Number(this.moveToPage), this.itemsPerPage);
|
||||||
|
} else {
|
||||||
|
this.$refs.alert.done = () => {
|
||||||
|
this.$emit('refresh');
|
||||||
|
};
|
||||||
|
this.$refs.alert.open(
|
||||||
|
this.$m('COD.CNFM', '확인'),
|
||||||
|
this.$m('CAP.PAGE_MOVE_CNFM', '이동할 페이지 정보를 확인 하세요'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
changePageLeng: function(limit) {
|
||||||
|
//부모 컴포넌트에서 loadData(데이터 조회) 구현
|
||||||
|
//this.$emit('loadData', this.pageNum, limit);
|
||||||
|
// limit 변경 시 1 페이지로 초기화
|
||||||
|
this.$emit('loadData', 1, limit);
|
||||||
|
},
|
||||||
|
|
||||||
|
firstToPage: function() {
|
||||||
|
if (0 != this.minusPage) {
|
||||||
|
this.$emit('loadData', 1, this.itemsPerPage);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
lastToPage: function() {
|
||||||
|
if (this.lastPage >= this.plusPage) {
|
||||||
|
this.$emit('loadData', this.lastPage, this.itemsPerPage);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.btn-pager {
|
||||||
|
margin: 4px;
|
||||||
|
input {
|
||||||
|
width: 80px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.v-btn--fab.v-size--small {
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
.v-text-field__details {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.con-pager {
|
||||||
|
margin-top: 12px;
|
||||||
|
margin-bottom: -12px;
|
||||||
|
}
|
||||||
|
.ly-pager {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
.v-btn {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
.v-btn--text {
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
// .grey--text {
|
||||||
|
// margin-left: 16px;
|
||||||
|
// }
|
||||||
|
.mr-4 {
|
||||||
|
margin-left: 14px;
|
||||||
|
}
|
||||||
|
.v-btn__content {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
</style>
|
7
components/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# COMPONENTS
|
||||||
|
|
||||||
|
**This directory is not required, you can delete it if you don't want to use it.**
|
||||||
|
|
||||||
|
The components directory contains your Vue.js Components.
|
||||||
|
|
||||||
|
_Nuxt.js doesn't supercharge these components._
|
18
components/VuetifyLogo.vue
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<template>
|
||||||
|
<img class="VuetifyLogo" alt="Vuetify Logo" src="/vuetify-logo.svg" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.VuetifyLogo {
|
||||||
|
height: 180px;
|
||||||
|
width: 180px;
|
||||||
|
transform: rotateY(560deg);
|
||||||
|
animation: turn 3.5s ease-out forwards 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes turn {
|
||||||
|
100% {
|
||||||
|
transform: rotateY(0deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
181
components/common/AdminMenu.vue
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
<template>
|
||||||
|
<v-menu offset-y nudge-bottom="8" :left="true">
|
||||||
|
<template v-slot:activator="{ on, attrs }">
|
||||||
|
<v-btn
|
||||||
|
v-bind="attrs"
|
||||||
|
v-on="on"
|
||||||
|
depressed
|
||||||
|
:ripple="false"
|
||||||
|
:class="{ miniVariant }"
|
||||||
|
:style="btnStyle"
|
||||||
|
>
|
||||||
|
<v-icon size="32" :class="{ 'mr-2': !miniVariant }"
|
||||||
|
>$icoAdminMenu</v-icon
|
||||||
|
>
|
||||||
|
<span class="body-1 mr-1">{{ userNm }}</span>
|
||||||
|
<v-icon>mdi-chevron-down</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
<!-- <AlertPopup
|
||||||
|
ref="alertPop"
|
||||||
|
v-show='false'
|
||||||
|
:item="item"
|
||||||
|
|
||||||
|
/> -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<v-list class="pa-2">
|
||||||
|
<!-- <v-list-item class="mb-1">-->
|
||||||
|
<!-- <div class="d-flex align-center">-->
|
||||||
|
<!-- <v-avatar class="mr-1" size="20">-->
|
||||||
|
<!-- <v-icon color="white">mdi-account-outline</v-icon>-->
|
||||||
|
<!-- </v-avatar>-->
|
||||||
|
<!-- <div class="d-flex flex-column">-->
|
||||||
|
<!-- <span class="body-2 white--text">관리자</span>-->
|
||||||
|
<!-- <!– <nuxt-link class="d-flex align-center mypage" to="/">-->
|
||||||
|
<!-- <span class="clr-ccc-aaa">마이페이지</span>-->
|
||||||
|
<!-- <v-icon class="ico-right">mdi-chevron-right</v-icon>-->
|
||||||
|
<!-- </nuxt-link> –>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- </v-list-item>-->
|
||||||
|
<v-list-item>
|
||||||
|
<v-btn @click="pswdChange" small elevation="0">
|
||||||
|
<v-icon class="mr-1" size="20">mdi-account-outline</v-icon>
|
||||||
|
<span class="body-2">비밀번호 변경</span>
|
||||||
|
</v-btn>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item>
|
||||||
|
<v-btn @click="logout" small elevation="0">
|
||||||
|
<v-icon class="mr-1" size="20">mdi-logout</v-icon>
|
||||||
|
<span class="body-2">로그아웃</span>
|
||||||
|
</v-btn>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import $cookie from 'vue-cookie';
|
||||||
|
import { mapState } from 'vuex';
|
||||||
|
// import AlertPopup from "~/components/common/modal/AlertPopup";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
miniVariant: Boolean,
|
||||||
|
userNm: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
comId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
// AlertPopup
|
||||||
|
//ChangePswdPop
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
logoutUrl: '/login',
|
||||||
|
item: {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(['isDarkMode']),
|
||||||
|
btnStyle() {
|
||||||
|
return this.isDarkMode ? { color: '#fff' } : { color: '#111' };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
logout() {
|
||||||
|
$cookie.delete('FEMS_SESSION');
|
||||||
|
// alert("정상적으로 로그아웃 되었습니다.");
|
||||||
|
// this.item={
|
||||||
|
// label:'로그아웃',
|
||||||
|
// message:'정상적으로 로그아웃 되었습니다.'
|
||||||
|
// }
|
||||||
|
// this.$refs['alertPop'].dialog = true;
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
window.location.href = this.logoutUrl + '?' + this.comId;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
pswdChange() {
|
||||||
|
this.$parent.$parent.$parent.$parent.$refs['changePswdPop'].dialog = true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/assets/scss/var.scss';
|
||||||
|
@each $theme in dark, light {
|
||||||
|
.v-application.#{$theme}-mode {
|
||||||
|
.mdi-account {
|
||||||
|
color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
'tui-datepicker-calendar-color'
|
||||||
|
) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-list {
|
||||||
|
background-color: map-deep-get(
|
||||||
|
$config,
|
||||||
|
#{$theme},
|
||||||
|
'admin-menu-expanded-list-backgroundColor'
|
||||||
|
);
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-menu__content {
|
||||||
|
box-shadow: 0 5px 15px 0 rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-list {
|
||||||
|
.v-btn {
|
||||||
|
padding: 0 !important;
|
||||||
|
margin-bottom: 0;
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #46c0ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
> span {
|
||||||
|
color: currentColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-btn {
|
||||||
|
width: 100%;
|
||||||
|
min-width: auto !important;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 20px !important;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
|
||||||
|
&,
|
||||||
|
&:before {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep {
|
||||||
|
.v-btn__content {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.miniVariant {
|
||||||
|
::v-deep {
|
||||||
|
.v-btn__content > .body-1,
|
||||||
|
.v-btn__content > .mdi-chevron-down {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
77
components/common/BtnXlsx.vue
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<template>
|
||||||
|
<div id="btnExeclDownload">
|
||||||
|
<v-btn class="v-btn__round v-btn__excel" @click="downloadExcelFile">
|
||||||
|
<v-icon>mdi-microsoft-excel</v-icon>
|
||||||
|
엑셀
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import XLSX from 'xlsx';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'btnExeclDownload',
|
||||||
|
props: {
|
||||||
|
xlsHeader: {
|
||||||
|
// JSON 데이터로 만들 시 필요
|
||||||
|
type: Array,
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
|
xlsRowData: {
|
||||||
|
// JSON 데이터로 만들 시 필요
|
||||||
|
type: Array,
|
||||||
|
default: [],
|
||||||
|
},
|
||||||
|
tableId: {
|
||||||
|
// 성성된 테이블 그대로 쓸 경우 그리드에 id 지정 후 바인딩
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
fileName: {
|
||||||
|
// 테이블이 하나일 경우, 현재 활성화 메뉴명을 가져와도 될듯,.
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
sheetName: {
|
||||||
|
// 지정된 시트명이 없으면 'Sheet1'
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
xlsData: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setExcelData() {
|
||||||
|
let tmpData = [];
|
||||||
|
let tmpMap = {};
|
||||||
|
this.xlsRowData.map(item => {
|
||||||
|
this.xlsHeader.map(v => {
|
||||||
|
return Object.assign(tmpMap, { [v.header]: item[v.name] || '' });
|
||||||
|
});
|
||||||
|
tmpData = tmpData.concat(tmpMap);
|
||||||
|
tmpMap = {};
|
||||||
|
});
|
||||||
|
this.xlsData = tmpData;
|
||||||
|
tmpData = null;
|
||||||
|
tmpMap = null;
|
||||||
|
},
|
||||||
|
async downloadExcelFile() {
|
||||||
|
if (!this.tableId) await this.setExcelData(); // 들어온 JSON 데이타 가공
|
||||||
|
|
||||||
|
const workBook = XLSX.utils.book_new(); // 새 시트 생성
|
||||||
|
const excelData = this.tableId
|
||||||
|
? // 테이블 그대로 가져올때
|
||||||
|
XLSX.utils.table_to_sheet(document.getElementById(this.tableId))
|
||||||
|
: // JSON 형식으로 가져올때
|
||||||
|
XLSX.utils.json_to_sheet(this.xlsData);
|
||||||
|
const sheetName = this.sheetName || null;
|
||||||
|
XLSX.utils.book_append_sheet(workBook, excelData, sheetName); // 시트 명명, 데이터 지정
|
||||||
|
XLSX.writeFile(workBook, `${this.fileName}.xlsx`); // 엑셀파일 만듬
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
339
components/common/Calendar.vue
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
<template>
|
||||||
|
<div class="custom-vc-calender">
|
||||||
|
<div class="custom-vc-calender-title text-center" v-if="headerVisible">
|
||||||
|
<span>{{ selectedYear }}년 {{ selectedMonth }}월</span>
|
||||||
|
</div>
|
||||||
|
<vc-calendar
|
||||||
|
ref="myCalendar"
|
||||||
|
:attributes="calendarAttributes"
|
||||||
|
class="custom-calendar"
|
||||||
|
>
|
||||||
|
<!-- disable-page-swipe
|
||||||
|
is-expanded -->
|
||||||
|
<template v-slot:day-content="{ day, attributes }">
|
||||||
|
<div class="plusButton" style="overflow:auto">
|
||||||
|
<!-- <p class="plusButton mr-1" >+</p> -->
|
||||||
|
<span
|
||||||
|
:class="['day-label', { 'is-holiday': hldyValues(day.day) }]"
|
||||||
|
@click="addPlan(day.year, day.month, day.day)"
|
||||||
|
>{{ day.day }}</span
|
||||||
|
>
|
||||||
|
<span v-for="attr in attributes" :key="attr.key" class="day-hldyNm">
|
||||||
|
{{ attr.customData.title }}
|
||||||
|
</span>
|
||||||
|
<div class="">
|
||||||
|
<p
|
||||||
|
v-for="attr in attributes"
|
||||||
|
:key="attr.key"
|
||||||
|
:class="attr.customData.planColor"
|
||||||
|
@click="updatePlan(attr.customData.planSeq)"
|
||||||
|
>
|
||||||
|
{{ attr.customData.planTitle }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</vc-calendar>
|
||||||
|
<component
|
||||||
|
ref="planPop"
|
||||||
|
:is="'PlanPop'"
|
||||||
|
v-show="false"
|
||||||
|
:detailList="detailList"
|
||||||
|
:label="planLabel"
|
||||||
|
:parentPrgmId="parentPrgmId"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapState } from 'vuex';
|
||||||
|
import Utility from '~/plugins/utility';
|
||||||
|
import PlanPop from '@/components/common/modal/PlanPop';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
gridName: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
headerVisible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
pageData(state) {
|
||||||
|
return state.pageData[this.parentPrgmId];
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
gridData() {
|
||||||
|
return this.pageData[this.gridName].data;
|
||||||
|
},
|
||||||
|
planData() {
|
||||||
|
return this.pageData.planData;
|
||||||
|
},
|
||||||
|
calendarDtValue() {
|
||||||
|
const dt = this.pageData['fromDt'];
|
||||||
|
return dt;
|
||||||
|
},
|
||||||
|
selectedYear() {
|
||||||
|
return Utility.setFormatDate(this.calendarDtValue, 'YYYY');
|
||||||
|
//return this.calendarDtValue.split("-")[0];
|
||||||
|
},
|
||||||
|
selectedMonth() {
|
||||||
|
return Utility.setFormatDate(this.calendarDtValue, 'MM');
|
||||||
|
//return this.calendarDtValue.split("-")[1];
|
||||||
|
},
|
||||||
|
hldyValues() {
|
||||||
|
const filter = this.gridData.filter(
|
||||||
|
data => data.hldyFg === '1' || data.hldyNm,
|
||||||
|
);
|
||||||
|
const map = filter.map(item => {
|
||||||
|
const dt = item.dt.split(' ')[0];
|
||||||
|
const dtArr = dt.split('-');
|
||||||
|
const dd = dtArr[2] * 1;
|
||||||
|
return dd;
|
||||||
|
});
|
||||||
|
|
||||||
|
return day => {
|
||||||
|
return map.includes(day);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
calendarAttributes() {
|
||||||
|
if (this.planData.length > 0) {
|
||||||
|
let attrArr = [];
|
||||||
|
this.planData.forEach((item, idx) => {
|
||||||
|
const dt = item.dt.split(' ')[0];
|
||||||
|
const dtArr = dt.split('-');
|
||||||
|
const yy = dtArr[0] * 1;
|
||||||
|
const mm = dtArr[1] * 1 - 1;
|
||||||
|
const dd = dtArr[2] * 1;
|
||||||
|
attrArr.push({
|
||||||
|
key: idx,
|
||||||
|
customData: {
|
||||||
|
title: item.hldyNm,
|
||||||
|
hldyFg: item.hldyFg,
|
||||||
|
planTitle: item.planTitle,
|
||||||
|
planSeq: item.planSeq,
|
||||||
|
planColor:
|
||||||
|
// item.endDt < Utility.setFormatDate(new Date(), 'YYYY-MM-DD')
|
||||||
|
// ? 'grey':
|
||||||
|
item.planColor,
|
||||||
|
},
|
||||||
|
dates: new Date(yy, mm, dd),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return attrArr;
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
calendarDtValue(val) {
|
||||||
|
// if (val) {
|
||||||
|
// this.$refs.myCalendar.move(this.calendarDtValue);
|
||||||
|
// }
|
||||||
|
if (val) {
|
||||||
|
const yy = Utility.setFormatDate(this.calendarDtValue, 'YYYY');
|
||||||
|
const mm = Utility.setFormatDate(this.calendarDtValue, 'MM') - 1;
|
||||||
|
this.$refs.myCalendar.showPageRange(new Date(yy, mm, 1));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
PlanPop,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
detailList: myDetail,
|
||||||
|
planPopDisableFlag: false,
|
||||||
|
planLabel: '일정',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addPlan(year, month, day) {
|
||||||
|
this.planLabel = '일정 등록';
|
||||||
|
this.$refs['planPop'].popUpAction = 'insert';
|
||||||
|
// this.$refs['planPop'].strtDt = year + '-' + month + '-' + day;
|
||||||
|
// this.$refs['planPop'].endDt = year + '-' + month + '-' + day;
|
||||||
|
// this.$refs['planPop'].strtDt = year + '-' + String(month).padStart(2, '0') + '-' + String(day).padStart(2, '0');
|
||||||
|
// this.$refs['planPop'].endDt = year + '-' + String(month).padStart(2, '0') + '-' + String(day).padStart(2, '0');
|
||||||
|
this.$refs['planPop'].strtDt = '';
|
||||||
|
this.$refs['planPop'].endDt = '';
|
||||||
|
this.$refs['planPop'].addPlanData = {
|
||||||
|
year : year,
|
||||||
|
month : month,
|
||||||
|
day : day
|
||||||
|
}
|
||||||
|
this.$refs['planPop'].blocId = this.pageData.blocMstrList[
|
||||||
|
this.pageData.blocId
|
||||||
|
].blocId;
|
||||||
|
this.$refs['planPop'].dialog = true;
|
||||||
|
},
|
||||||
|
updatePlan(val) {
|
||||||
|
this.$refs['planPop'].popUpAction = 'update';
|
||||||
|
this.$refs['planPop'].planSeq = val;
|
||||||
|
this.$refs['planPop'].strtDt = '';
|
||||||
|
this.$refs['planPop'].endDt = '';
|
||||||
|
this.$refs['planPop'].blocId = this.pageData.blocMstrList[
|
||||||
|
this.pageData.blocId
|
||||||
|
].blocId;
|
||||||
|
this.$refs['planPop'].dialog = true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {},
|
||||||
|
};
|
||||||
|
const myDetail = [];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/assets/scss/var.scss';
|
||||||
|
@import '@/assets/scss/mixin.scss';
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 0px;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.custom-vc-calender {
|
||||||
|
&-title {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::v-deep {
|
||||||
|
.custom-calendar.vc-container {
|
||||||
|
width: 100%;
|
||||||
|
background-color: transparent;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
.vc-header,
|
||||||
|
.vc-arrows-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.vc-weeks {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0;
|
||||||
|
> div {
|
||||||
|
flex: 1 0 calc(100% / 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.vc-weekday {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 36px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.vc-day {
|
||||||
|
height: 10.889vh;
|
||||||
|
min-height: auto;
|
||||||
|
|
||||||
|
.day-label {
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.235;
|
||||||
|
}
|
||||||
|
.day-hldyNm {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
display: block;
|
||||||
|
max-width: 80%;
|
||||||
|
float: right;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
> div {
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.vc-day.is-not-in-month {
|
||||||
|
* {
|
||||||
|
opacity: 1 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.plusButton:hover > span:first-child {
|
||||||
|
font-weight: bolder;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.red {
|
||||||
|
//background-color: rgba(229,62,62,var(--bg-opacity));
|
||||||
|
background-color: #e53e3e !important;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 0.125rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 1.25;
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
.blue {
|
||||||
|
//background-color: rgba(66,153,225,var(--bg-opacity));
|
||||||
|
background-color: #4299e1 !important;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 0.125rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 1.25;
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
.puple {
|
||||||
|
//background-color: rgba(102,126,234,var(--bg-opacity));
|
||||||
|
background-color: #667eea !important;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 0.125rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 1.25;
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
.green {
|
||||||
|
//background-color: rgba(56,178,172,var(--bg-opacity));
|
||||||
|
background-color: #38b2ac !important;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 0.125rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 1.25;
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
.orange {
|
||||||
|
//background-color: rgba(237,137,54,var(--bg-opacity));
|
||||||
|
background-color: #ed8936 !important;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 0.125rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 1.25;
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
.pink {
|
||||||
|
//background-color: rgba(237,100,166,var(--bg-opacity));
|
||||||
|
background-color: #ed64a6 !important;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 0.125rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 1.25;
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
.grey {
|
||||||
|
background-color: #6d6d6d;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 0.125rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 1.25;
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
409
components/common/Chart.vue
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
<template>
|
||||||
|
<div class="chart-wrap">
|
||||||
|
<v-chart
|
||||||
|
class="chart"
|
||||||
|
:option="chartOption"
|
||||||
|
ref="VChart"
|
||||||
|
@click="onClick"
|
||||||
|
@dblclick="onDblClick"
|
||||||
|
@click.right="onRightClick"
|
||||||
|
@legendselectchanged="onLegendSelectChanged"
|
||||||
|
autoresize
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import VChart from 'vue-echarts';
|
||||||
|
import { mapState } from 'vuex';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
VChart,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
widgetId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
widgetData: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
modalId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
modalDataKey: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
chartName: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
chartColor: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
legendSeletedList: {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
isDarkMode: 'isDarkMode',
|
||||||
|
|
||||||
|
chartOption(state) {
|
||||||
|
var dark_Col = [
|
||||||
|
'#01AE6A',
|
||||||
|
'#FFB046',
|
||||||
|
'#F6637B',
|
||||||
|
'#944FE9',
|
||||||
|
'#4385E3',
|
||||||
|
'#00AA8C',
|
||||||
|
'#FF8808',
|
||||||
|
'#EA5E9A',
|
||||||
|
'#B742D9',
|
||||||
|
'#6363DA',
|
||||||
|
'#79B100',
|
||||||
|
'#D66500',
|
||||||
|
'#DC5ABC',
|
||||||
|
'#764FD7',
|
||||||
|
'#009DD1',
|
||||||
|
'#3BAD43',
|
||||||
|
'#D75E3D',
|
||||||
|
'#CF4DCA',
|
||||||
|
'#A148D9',
|
||||||
|
'#5972DF',
|
||||||
|
];
|
||||||
|
var darkCol_1_5 = [
|
||||||
|
'#01AE6A',
|
||||||
|
'#089362',
|
||||||
|
'#0F7959',
|
||||||
|
'#165E51',
|
||||||
|
'#19514D',
|
||||||
|
];
|
||||||
|
var darkCol_1_10 = [
|
||||||
|
'#01AE6A',
|
||||||
|
'#04A166',
|
||||||
|
'#089362',
|
||||||
|
'#0B865D',
|
||||||
|
'#0F7959',
|
||||||
|
'#126C55',
|
||||||
|
'#165E51',
|
||||||
|
'#19514D',
|
||||||
|
'#1D4448',
|
||||||
|
'#1F3D46',
|
||||||
|
];
|
||||||
|
var darkCol_2_5 = [
|
||||||
|
'#FFB046',
|
||||||
|
'#D39545',
|
||||||
|
'#A77A44',
|
||||||
|
'#7C5F42',
|
||||||
|
'#665242',
|
||||||
|
];
|
||||||
|
var darkCol_2_10 = [
|
||||||
|
'#FFB046',
|
||||||
|
'#EAA345',
|
||||||
|
'#D39545',
|
||||||
|
'#BE8844',
|
||||||
|
'#A77A44',
|
||||||
|
'#926D43',
|
||||||
|
'#7C5F42',
|
||||||
|
'#665242',
|
||||||
|
'#4C4141',
|
||||||
|
'#453D41',
|
||||||
|
];
|
||||||
|
var darkCol_3_5 = [
|
||||||
|
'#F6637B',
|
||||||
|
'#CC576F',
|
||||||
|
'#A24C63',
|
||||||
|
'#784058',
|
||||||
|
'#633B52',
|
||||||
|
];
|
||||||
|
var darkCol_3_10 = [
|
||||||
|
'#F6637B',
|
||||||
|
'#E15D75',
|
||||||
|
'#CC576F',
|
||||||
|
'#B75269',
|
||||||
|
'#A24C63',
|
||||||
|
'#8D465E',
|
||||||
|
'#784058',
|
||||||
|
'#633B52',
|
||||||
|
'#4E354C',
|
||||||
|
'#433249',
|
||||||
|
];
|
||||||
|
var darkCol_4_5 = [
|
||||||
|
'#944FE9',
|
||||||
|
'#7E47C7',
|
||||||
|
'#6740A5',
|
||||||
|
'#513884',
|
||||||
|
'#463473',
|
||||||
|
];
|
||||||
|
var darkCol_4_10 = [
|
||||||
|
'#944FE9',
|
||||||
|
'#894BD8',
|
||||||
|
'#7E47C7',
|
||||||
|
'#7344B7',
|
||||||
|
'#6740A5',
|
||||||
|
'#5C3C95',
|
||||||
|
'#513884',
|
||||||
|
'#463473',
|
||||||
|
'#3A3162',
|
||||||
|
'#352F59',
|
||||||
|
];
|
||||||
|
var darkCol_5_5 = [
|
||||||
|
'#4385E3',
|
||||||
|
'#3D73C2',
|
||||||
|
'#3760A2',
|
||||||
|
'#304E81',
|
||||||
|
'#2D4571',
|
||||||
|
];
|
||||||
|
var darkCol_5_10 = [
|
||||||
|
'#4385E3',
|
||||||
|
'#407CD3',
|
||||||
|
'#3D73C2',
|
||||||
|
'#3A6AB2',
|
||||||
|
'#3760A2',
|
||||||
|
'#345792',
|
||||||
|
'#304E81',
|
||||||
|
'#2D4571',
|
||||||
|
'#2A3B61',
|
||||||
|
'#293758',
|
||||||
|
];
|
||||||
|
var darkCol_dashGauge = [
|
||||||
|
[0.125, '#009245'],
|
||||||
|
[0.25, '#39b54a'],
|
||||||
|
[0.375, '#d9e021'],
|
||||||
|
[0.5, '#fcee21'],
|
||||||
|
[0.625, '#fbb03b'],
|
||||||
|
[0.75, '#f7931e'],
|
||||||
|
[0.875, '#f15a24'],
|
||||||
|
[1.0, '#ed1c24'],
|
||||||
|
];
|
||||||
|
var darkCol_dashUseStatus = ['#2fad35', '#fb8200', '#fb5a8b'];
|
||||||
|
var darkCol_dashTodayUsageCost = ['#01ae6a', '#ffb046', '#f6637b'];
|
||||||
|
var darkCol_dashEnrgUsage = ['#01ae6a', '#4385e3'];
|
||||||
|
var darkCol_dashReadplcStatus = ['#01ae6a', '#ffb046', '#f6637b'];
|
||||||
|
var lightCol_dashReadplcStatus = ['#3cc380', '#ffb13b', '#f98694'];
|
||||||
|
|
||||||
|
var light_Col = [
|
||||||
|
'#3CC380',
|
||||||
|
'#FFB13B',
|
||||||
|
'#F98694',
|
||||||
|
'#CF74E5',
|
||||||
|
'#6A9BF4',
|
||||||
|
'#29BCA2',
|
||||||
|
'#EC8D3B',
|
||||||
|
'#FC749D',
|
||||||
|
'#CF74E5',
|
||||||
|
'#7E84FF',
|
||||||
|
'#83BE01',
|
||||||
|
'#D58B03',
|
||||||
|
'#FF7E71',
|
||||||
|
'#BE6DF0',
|
||||||
|
'#3FAED2',
|
||||||
|
'#5DBF63',
|
||||||
|
'#D1886C',
|
||||||
|
'#ED71B7',
|
||||||
|
'#977EE6',
|
||||||
|
'#7A8EE2',
|
||||||
|
];
|
||||||
|
var lightCol_1_5 = [
|
||||||
|
'#3CC380',
|
||||||
|
'#5BCD94',
|
||||||
|
'#7BD6A9',
|
||||||
|
'#99E0BD',
|
||||||
|
'#B1E7CC',
|
||||||
|
];
|
||||||
|
var lightCol_1_10 = [
|
||||||
|
'#3CC380',
|
||||||
|
'#4BC88A',
|
||||||
|
'#5BCD94',
|
||||||
|
'#6BD19E',
|
||||||
|
'#7BD6A9',
|
||||||
|
'#8ADBB3',
|
||||||
|
'#99E0BD',
|
||||||
|
'#A9E5C7',
|
||||||
|
'#B9E9D1',
|
||||||
|
'#C9EEDC',
|
||||||
|
];
|
||||||
|
var lightCol_2_5 = [
|
||||||
|
'#FFB13B',
|
||||||
|
'#FFBE5B',
|
||||||
|
'#FFCA7A',
|
||||||
|
'#FFD699',
|
||||||
|
'#FFE0B1',
|
||||||
|
];
|
||||||
|
var lightCol_2_10 = [
|
||||||
|
'#FFB13B',
|
||||||
|
'#FFB74A',
|
||||||
|
'#FFBE5B',
|
||||||
|
'#FFC46A',
|
||||||
|
'#FFCA7A',
|
||||||
|
'#FFD089',
|
||||||
|
'#FFD699',
|
||||||
|
'#FFDDA9',
|
||||||
|
'#FFE3B8',
|
||||||
|
'#FFE9C8',
|
||||||
|
];
|
||||||
|
var lightCol_3_5 = [
|
||||||
|
'#F98694',
|
||||||
|
'#FA99A5',
|
||||||
|
'#FBADB6',
|
||||||
|
'#FCC0C7',
|
||||||
|
'#FDCFD4',
|
||||||
|
];
|
||||||
|
var lightCol_3_10 = [
|
||||||
|
'#F98694',
|
||||||
|
'#F98F9C',
|
||||||
|
'#FA99A5',
|
||||||
|
'#FAA3AE',
|
||||||
|
'#FBADB6',
|
||||||
|
'#FBB6BF',
|
||||||
|
'#FCC0C7',
|
||||||
|
'#FCCAD0',
|
||||||
|
'#FDD3D8',
|
||||||
|
'#FDDDE1',
|
||||||
|
];
|
||||||
|
var lightCol_4_5 = [
|
||||||
|
'#CF74E5',
|
||||||
|
'#D78AE9',
|
||||||
|
'#DEA1ED',
|
||||||
|
'#E6B7F1',
|
||||||
|
'#ECC7F5',
|
||||||
|
];
|
||||||
|
var lightCol_4_10 = [
|
||||||
|
'#CF74E5',
|
||||||
|
'#D37FE7',
|
||||||
|
'#D78AE9',
|
||||||
|
'#DA95EB',
|
||||||
|
'#DEA1ED',
|
||||||
|
'#E2ACEF',
|
||||||
|
'#E6B7F1',
|
||||||
|
'#EAC2F4',
|
||||||
|
'#EECDF6',
|
||||||
|
'#F2D8F8',
|
||||||
|
];
|
||||||
|
var lightCol_5_5 = [
|
||||||
|
'#6A9BF4',
|
||||||
|
'#82ABF6',
|
||||||
|
'#9ABBF8',
|
||||||
|
'#B1CBF9',
|
||||||
|
'#C3D7FB',
|
||||||
|
];
|
||||||
|
var lightCol_5_10 = [
|
||||||
|
'#6A9BF4',
|
||||||
|
'#76A3F5',
|
||||||
|
'#82ABF6',
|
||||||
|
'#8EB3F7',
|
||||||
|
'#9ABBF8',
|
||||||
|
'#A6C3F8',
|
||||||
|
'#B1CBF9',
|
||||||
|
'#BED3FA',
|
||||||
|
'#C9DBFB',
|
||||||
|
'#D6E3FC',
|
||||||
|
];
|
||||||
|
var lightCol_dashGauge = [
|
||||||
|
[0.125, '#58c06f'],
|
||||||
|
[0.25, '#7cd574'],
|
||||||
|
[0.375, '#fbe462'],
|
||||||
|
[0.5, '#ffd771'],
|
||||||
|
[0.625, '#ffad7f'],
|
||||||
|
[0.75, '#ff966e'],
|
||||||
|
[0.875, '#ff706e'],
|
||||||
|
[1.0, '#ff6689'],
|
||||||
|
];
|
||||||
|
var lightCol_dashUseStatus = ['#00c875', '#fdab3d', '#ff7b8b'];
|
||||||
|
var lightCol_dashTodayUsageCost = ['#3cc380', '#cf74e5', '#ffb13b'];
|
||||||
|
var lightCol_dashEnrgUsage = ['#ce83e0', '#78a3f3'];
|
||||||
|
var lightCol_dashReadplcStatus = ['#3cc380', '#ffb13b', '#f98694'];
|
||||||
|
|
||||||
|
var tmpChrtOp;
|
||||||
|
if (this.widgetId || this.widgetData) {
|
||||||
|
tmpChrtOp =
|
||||||
|
state.pageData[this.parentPrgmId][this.widgetId][this.widgetData][
|
||||||
|
this.chartName
|
||||||
|
];
|
||||||
|
} else if(this.modalId || this.modalDataKey) {
|
||||||
|
tmpChrtOp =
|
||||||
|
state.pageData[this.parentPrgmId][this.modalId][this.modalDataKey][this.chartName];
|
||||||
|
} else {
|
||||||
|
tmpChrtOp = state.pageData[this.parentPrgmId][this.chartName];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.chartColor != undefined) {
|
||||||
|
if (this.isDarkMode) {
|
||||||
|
tmpChrtOp.color = eval('darkCol_' + this.chartColor);
|
||||||
|
} else {
|
||||||
|
tmpChrtOp.color = eval('lightCol_' + this.chartColor);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.isDarkMode) {
|
||||||
|
tmpChrtOp.color = dark_Col;
|
||||||
|
} else {
|
||||||
|
tmpChrtOp.color = light_Col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tmpChrtOp;
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onClick(event, instance, ECharts) {
|
||||||
|
console.log('onClick : ', event);
|
||||||
|
this.$emit('click', event);
|
||||||
|
},
|
||||||
|
onDblClick(event, instance, ECharts) {
|
||||||
|
console.log('onDblClick : ', event);
|
||||||
|
this.$emit('dblclick', event);
|
||||||
|
},
|
||||||
|
onRightClick(event, instance, ECharts) {
|
||||||
|
console.log('onRightClick : ', event);
|
||||||
|
this.$emit('rclick', event);
|
||||||
|
},
|
||||||
|
onLegendSelect(params) {
|
||||||
|
const myChart = this.$refs.VChart;
|
||||||
|
for (const key of params) {
|
||||||
|
//차트 instance에 'legendSelect' action 전달
|
||||||
|
myChart.dispatchAction({
|
||||||
|
type: 'legendSelect',
|
||||||
|
name: key,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLegendUnSelect(params) {
|
||||||
|
const myChart = this.$refs.VChart;
|
||||||
|
for (const key of params) {
|
||||||
|
//차트 instance에 'legendUnSelect' action 전달
|
||||||
|
myChart.dispatchAction({
|
||||||
|
type: 'legendUnSelect',
|
||||||
|
name: key,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLegendSelectChanged(params) {
|
||||||
|
const obj = params.selected;
|
||||||
|
this.legendSeletedList = obj;
|
||||||
|
},
|
||||||
|
onGetChangedLegendSeletedList() {
|
||||||
|
return this.legendSeletedList;
|
||||||
|
},
|
||||||
|
onGetLegendSelectedList() {
|
||||||
|
const myChart = this.$refs.VChart;
|
||||||
|
return myChart.getOption().legend[0].selected;
|
||||||
|
},
|
||||||
|
clear() {
|
||||||
|
const myChart = this.$refs.VChart;
|
||||||
|
myChart.clear();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
103
components/common/CheckBox.vue
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<template>
|
||||||
|
<v-row class="search-box" align="center" no-gutters>
|
||||||
|
<v-col v-if="label" :cols="labelCols">
|
||||||
|
<label for="" class="search-box-label">
|
||||||
|
<v-icon x-small :color="required ? '#fb8200' : 'primary'" class="mr-1"
|
||||||
|
>mdi-record-circle</v-icon
|
||||||
|
>
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
</v-col>
|
||||||
|
<v-col :cols="label ? textCols : ''">
|
||||||
|
<v-checkbox
|
||||||
|
v-model="chkValue"
|
||||||
|
:disabled="disabledFlag"
|
||||||
|
:readonly="readonly || false"
|
||||||
|
:required="required || false"
|
||||||
|
:false-value="false"
|
||||||
|
:color="isDarkMode ? '#fff' : '#4777d9'"
|
||||||
|
@change="modifyValue"
|
||||||
|
></v-checkbox>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations } from 'vuex';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
isDarkMode: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
readonly: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
valueNm: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
labelCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 4,
|
||||||
|
},
|
||||||
|
textCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 7,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chkValue: false,
|
||||||
|
testData: false,
|
||||||
|
disabledFlag: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
searchParam: state => state.pageData,
|
||||||
|
myBindingDara(state) {
|
||||||
|
return state.pageData[this.parentPrgmId][this.valueNm];
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
myBindingDara: {
|
||||||
|
deep: true,
|
||||||
|
handler(val) {
|
||||||
|
this.chkValue = val;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.chkValue = this.searchParam[this.parentPrgmId][this.valueNm];
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({ setPageData: 'setPageData' }),
|
||||||
|
modifyValue(e) {
|
||||||
|
return this.setPageData({ [this.valueNm]: e });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
145
components/common/CheckBoxLabelChange.vue
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
<template>
|
||||||
|
<v-row class="search-box" align="center" no-gutters>
|
||||||
|
<v-col v-if="location == 'front'" :cols="labelCols">
|
||||||
|
<label for="" class="search-box-label">
|
||||||
|
<v-icon v-if="icon" x-small :color="required ? '#fb8200' : 'primary'" class="mr-1"
|
||||||
|
>mdi-record-circle</v-icon
|
||||||
|
>
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
</v-col>
|
||||||
|
<v-col :cols="textCols" @click="modifyValue">
|
||||||
|
<v-checkbox
|
||||||
|
v-model="chkValue"
|
||||||
|
:disabled="disabledFlag"
|
||||||
|
:readonly="readonly || false"
|
||||||
|
:required="required || false"
|
||||||
|
:false-value="false"
|
||||||
|
:color="isDarkMode ? '#fff' : '#4777d9'"
|
||||||
|
@change="modifyValue"
|
||||||
|
|
||||||
|
></v-checkbox>
|
||||||
|
</v-col>
|
||||||
|
<v-col v-if="location == 'rear'" :cols="labelCols">
|
||||||
|
<label for="" class="search-box-label">
|
||||||
|
<v-icon v-if="icon" x-small :color="required ? '#fb8200' : 'primary'" class="mr-1"
|
||||||
|
>mdi-record-circle</v-icon
|
||||||
|
>
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations } from 'vuex';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
require: false,
|
||||||
|
},
|
||||||
|
isDarkMode: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
readonly: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
valueNm: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
labelCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 4,
|
||||||
|
},
|
||||||
|
textCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 7,
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
location: {
|
||||||
|
type: String,
|
||||||
|
require: false,
|
||||||
|
default: 'front'
|
||||||
|
},
|
||||||
|
disabledCheckOption: {
|
||||||
|
type: String,
|
||||||
|
require: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chkValue: false,
|
||||||
|
testData: false,
|
||||||
|
disabledFlag: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
searchParam: state => state.pageData,
|
||||||
|
myBindingData(state) {
|
||||||
|
return state.pageData[this.parentPrgmId][this.valueNm];
|
||||||
|
},
|
||||||
|
bindingDisabledCheckOption(state) {
|
||||||
|
if(state.pageData[this.parentPrgmId][this.disabledCheckOption]!=undefined){
|
||||||
|
return state.pageData[this.parentPrgmId][this.disabledCheckOption];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
myBindingData: {
|
||||||
|
deep: true,
|
||||||
|
handler(val) {
|
||||||
|
this.chkValue = val;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
bindingDisabledCheckOption(val) {
|
||||||
|
this.disabledFlag = val;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.chkValue = this.searchParam[this.parentPrgmId][this.valueNm];
|
||||||
|
if(this.searchParam[this.parentPrgmId][this.disabledCheckOption]!=undefined){
|
||||||
|
this.disabledFlag = this.searchParam[this.parentPrgmId][this.disabledCheckOption]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({ setPageData: 'setPageData' }),
|
||||||
|
modifyValue(e) {
|
||||||
|
if(this.disabledFlag==true&&e.target != undefined){
|
||||||
|
alert('기간이 한 시간 이내일 경우만 선택할 수 있습니다.')
|
||||||
|
}else{
|
||||||
|
if(e.target == undefined){
|
||||||
|
return this.setPageData({ [this.valueNm]: e });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
98
components/common/CommonRadio.vue
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<template>
|
||||||
|
<!-- <v-col v-if="label" :cols="labelCols">
|
||||||
|
<label for="" class="search-box-label">
|
||||||
|
<v-icon x-small color="primary" class="mr-1">mdi-record-circle</v-icon>
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
</v-col> -->
|
||||||
|
<v-radio-group
|
||||||
|
v-model="selected"
|
||||||
|
required:rules="radioRules"
|
||||||
|
row
|
||||||
|
hide-details
|
||||||
|
dense
|
||||||
|
>
|
||||||
|
<v-radio
|
||||||
|
v-for="item in radioList"
|
||||||
|
:key="item.label"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
:ripple="false"
|
||||||
|
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
|
||||||
|
on-icon="mdi-record-circle"
|
||||||
|
></v-radio>
|
||||||
|
</v-radio-group>
|
||||||
|
<!-- @change="updateBlocCode($event)" -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations, mapActions } from 'vuex';
|
||||||
|
import Utility from '~/plugins/utility';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
labelCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 4,
|
||||||
|
},
|
||||||
|
textCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 7,
|
||||||
|
},
|
||||||
|
radioList: {
|
||||||
|
type: Array,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
radioValue: {
|
||||||
|
type: String,
|
||||||
|
require: false,
|
||||||
|
default: 'commRadio',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
labelPrepend: true,
|
||||||
|
// selected:"CYC_DAY"
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
isDarkMode: 'isDarkMode',
|
||||||
|
searchParam: state => state.pageData,
|
||||||
|
}),
|
||||||
|
selected: {
|
||||||
|
get() {
|
||||||
|
return this.searchParam[this.parentPrgmId][this.radioValue];
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
return this.setPageData({ [this.radioValue]: value });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
selected(value) {
|
||||||
|
// 주기에 따른 오늘 기준 기본 날짜 세팅
|
||||||
|
this.setDefaultDate(value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// this.setDefaultDate(this.searchParam[this.parentPrgmId].cmCycle);
|
||||||
|
},
|
||||||
|
async mounted() {},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({ setPageData: 'setPageData' }),
|
||||||
|
...mapActions({}),
|
||||||
|
setDefaultDate(value) {
|
||||||
|
this.setPageData({ [this.radioValue]: value });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
442
components/common/Datepicker.vue
Normal file
@ -0,0 +1,442 @@
|
|||||||
|
<template>
|
||||||
|
<v-row class="search-box" align="center" no-gutters>
|
||||||
|
<v-col v-if="label" :cols="labelCols">
|
||||||
|
<label for="" class="search-box-label">
|
||||||
|
<v-icon x-small :color="required ? '#fb8200' : 'primary'" class="mr-1"
|
||||||
|
>mdi-record-circle</v-icon
|
||||||
|
>
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
</v-col>
|
||||||
|
<v-col :cols="label ? textCols : ''">
|
||||||
|
<div class="datepicker-container">
|
||||||
|
<v-text-field
|
||||||
|
id="startpicker"
|
||||||
|
ref="startpicker"
|
||||||
|
v-model="fromDtValue"
|
||||||
|
:class="isRange ? 'v-input__custom half' : 'v-input__custom'"
|
||||||
|
:hide-details="true"
|
||||||
|
readonly
|
||||||
|
outlined
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<v-icon size="20">$icoCalendar</v-icon>
|
||||||
|
</template>
|
||||||
|
<template #append-outer>
|
||||||
|
<div ref="startpicker-container" id="startpicker-container"></div>
|
||||||
|
</template>
|
||||||
|
</v-text-field>
|
||||||
|
<div v-show="isRange" class="mx-3" :style="{ lineHeight: 0 }">~</div>
|
||||||
|
<v-text-field
|
||||||
|
v-show="isRange"
|
||||||
|
id="endpicker"
|
||||||
|
ref="endpicker"
|
||||||
|
v-model="toDtValue"
|
||||||
|
:class="isRange ? 'v-input__custom half' : 'v-input__custom'"
|
||||||
|
:hide-details="true"
|
||||||
|
readonly
|
||||||
|
outlined
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<v-icon size="20">$icoCalendar</v-icon>
|
||||||
|
</template>
|
||||||
|
<template #append-outer>
|
||||||
|
<div ref="endpicker-container" id="endpicker-container"></div>
|
||||||
|
</template>
|
||||||
|
</v-text-field>
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations } from 'vuex';
|
||||||
|
import TuiDatepicker from 'tui-date-picker';
|
||||||
|
import Utility from '~/plugins/utility';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
require: false,
|
||||||
|
},
|
||||||
|
timePicker: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
labelCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 4,
|
||||||
|
},
|
||||||
|
textCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 8,
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
isRangeOption:{
|
||||||
|
type:Boolean,
|
||||||
|
require:false,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
today: new Date(),
|
||||||
|
startDatepickerInstance: null,
|
||||||
|
endDatepickerInstance: null,
|
||||||
|
startDtValue: null,
|
||||||
|
endDtValue: null,
|
||||||
|
cmCycleFlag: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
searchParam(state) {
|
||||||
|
return state.pageData[this.parentPrgmId];
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
myCmCycle() {
|
||||||
|
return this.searchParam.cmCycle;
|
||||||
|
},
|
||||||
|
myOptions() {
|
||||||
|
let returnObj = {};
|
||||||
|
switch (this.myCmCycle) {
|
||||||
|
case 'CYC_YEAR':
|
||||||
|
returnObj = {
|
||||||
|
type: 'year',
|
||||||
|
viewFormat: 'YYYY',
|
||||||
|
pickerFormat: 'YYYY',
|
||||||
|
sendFormat: 'YYYY',
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CYC_MONTH':
|
||||||
|
returnObj = {
|
||||||
|
type: 'month',
|
||||||
|
viewFormat: 'YYYY-MM',
|
||||||
|
pickerFormat: 'YYYY-MM',
|
||||||
|
sendFormat: 'YYYYMM',
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CYC_DAY':
|
||||||
|
returnObj = {
|
||||||
|
type: 'date',
|
||||||
|
viewFormat: 'YYYY-MM-DD',
|
||||||
|
pickerFormat: 'yyyy-MM-dd',
|
||||||
|
sendFormat: 'YYYYMMDD',
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CYC_HOUR':
|
||||||
|
returnObj = {
|
||||||
|
type: 'date',
|
||||||
|
viewFormat: 'YYYY-MM-DD' + (this.timePicker ? ' HH:mm:ss' : ''),
|
||||||
|
pickerFormat: 'yyyy-MM-dd' + (this.timePicker ? ' HH:mm A' : ''),
|
||||||
|
sendFormat: this.timePicker ? 'YYYY-MM-DD HH:mm:ss' : 'YYYYMMDD',
|
||||||
|
};
|
||||||
|
// returnObj = { type: "day", format: "YYYY-MM-DD HH:mm:ss" };
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return returnObj;
|
||||||
|
},
|
||||||
|
// maxDate() {
|
||||||
|
// return Utility.setFormatDate("today", this.myOptions.format);
|
||||||
|
// },
|
||||||
|
fromDtValue() {
|
||||||
|
return Utility.setFormatDate(
|
||||||
|
this.searchParam.fromDt,
|
||||||
|
this.myOptions.viewFormat,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
toDtValue() {
|
||||||
|
return Utility.setFormatDate(
|
||||||
|
this.searchParam.toDt,
|
||||||
|
this.myOptions.viewFormat,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
toDtChange(){
|
||||||
|
return {
|
||||||
|
isCheck:this.searchParam.isCheck ,
|
||||||
|
toDt : Utility.setFormatDate(
|
||||||
|
this.searchParam.toDt,
|
||||||
|
this.myOptions.viewFormat,
|
||||||
|
)};
|
||||||
|
},
|
||||||
|
fromDtChange(){
|
||||||
|
return {
|
||||||
|
isCheck:this.searchParam.isCheck ,
|
||||||
|
fromDt : Utility.setFormatDate(
|
||||||
|
this.searchParam.fromDt,
|
||||||
|
this.myOptions.viewFormat,
|
||||||
|
)};
|
||||||
|
},
|
||||||
|
defaultRange() {
|
||||||
|
return this.searchParam.defaultRange
|
||||||
|
? this.searchParam.defaultRange[this.myCmCycle]
|
||||||
|
: null;
|
||||||
|
},
|
||||||
|
isRange() {
|
||||||
|
return (
|
||||||
|
(this.defaultRange !== null && this.defaultRange > 0 && this.isRangeOption) ||
|
||||||
|
this.defaultRange === 'no limite'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
myCmCycle() {
|
||||||
|
this.cmCycleFlag = false;
|
||||||
|
this.startDatepickerInstance.setDate(new Date(this.fromDtValue));
|
||||||
|
this.startDatepickerInstance.setType(this.myOptions.type);
|
||||||
|
this.endDatepickerInstance.setType(this.myOptions.type);
|
||||||
|
},
|
||||||
|
fromDtValue(newVal, oldVal) {
|
||||||
|
if (
|
||||||
|
this.isRange &&
|
||||||
|
this.defaultRange !== 'no limite' &&
|
||||||
|
newVal !== 'Invalid Date' &&
|
||||||
|
newVal !== oldVal
|
||||||
|
) {
|
||||||
|
this.toDtValueChkRang(newVal);
|
||||||
|
this.startDatepickerInstance.setDate(new Date(newVal));
|
||||||
|
} else {
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toDtValue(newVal, oldVal) {
|
||||||
|
if (
|
||||||
|
this.isRange &&
|
||||||
|
this.defaultRange !== 'no limite' &&
|
||||||
|
newVal !== 'Invalid Date' &&
|
||||||
|
newVal !== oldVal
|
||||||
|
) {
|
||||||
|
this.fromDtValueChkRang(newVal);
|
||||||
|
this.endDatepickerInstance.setDate(new Date(newVal));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fromDtChange:{
|
||||||
|
deep:true,
|
||||||
|
handler(){
|
||||||
|
if(this.fromDtChange.isCheck){
|
||||||
|
this.fromDtChanged(this.fromDtChange.fromDt);
|
||||||
|
this.setPageData({
|
||||||
|
isCheck : false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toDtChange:{
|
||||||
|
deep:true,
|
||||||
|
handler(){
|
||||||
|
if(this.toDtChange.isCheck){
|
||||||
|
this.toDtChanged(this.toDtChange.toDt);
|
||||||
|
this.setPageData({
|
||||||
|
isCheck : false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if (this.timePicker) {
|
||||||
|
this.setPageData({
|
||||||
|
fromDt: Utility.setFormatDate(this.today, 'YYYY-MM-DD') + ' 00:00:00',
|
||||||
|
toDt: Utility.setFormatDate(this.today, 'YYYY-MM-DD') + ' 23:59:59',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const startContainer = document.getElementById('startpicker-container');
|
||||||
|
const startTarget = document.getElementById('startpicker');
|
||||||
|
const endContainer = document.getElementById('endpicker-container');
|
||||||
|
const endTarget = document.getElementById('endpicker');
|
||||||
|
|
||||||
|
// datepicker 생성
|
||||||
|
this.startDatepickerInstance = new TuiDatepicker(startContainer, {
|
||||||
|
date: this.today,
|
||||||
|
language: 'ko',
|
||||||
|
type: this.myOptions.type, // "date", // type: date || month || year
|
||||||
|
input: {
|
||||||
|
element: startTarget,
|
||||||
|
format: this.myOptions.pickerFormat, //"YYYY-MM-DD" //this.format
|
||||||
|
},
|
||||||
|
timePicker: this.timePicker,
|
||||||
|
calendar: {
|
||||||
|
showToday: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// datepicker 생성
|
||||||
|
this.endDatepickerInstance = new TuiDatepicker(endContainer, {
|
||||||
|
date: this.today,
|
||||||
|
language: 'ko',
|
||||||
|
type: this.myOptions.type, // "date", // type: date || month || year
|
||||||
|
input: {
|
||||||
|
element: endTarget,
|
||||||
|
format: this.myOptions.pickerFormat, //"YYYY-MM-DD" //this.format
|
||||||
|
},
|
||||||
|
timePicker: this.timePicker,
|
||||||
|
calendar: {
|
||||||
|
showToday: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// datepicker 생성 끝
|
||||||
|
|
||||||
|
// datepicker 초기값 생성
|
||||||
|
this.startDatepickerInstance.setDate(new Date(this.fromDtValue));
|
||||||
|
// datepicker 초기값 생성 끝
|
||||||
|
|
||||||
|
// datepicker 변경시 이벤트 추가
|
||||||
|
this.startDatepickerInstance.on('change', () => this.getStartDt());
|
||||||
|
this.endDatepickerInstance.on('change', () => this.getEndDt());
|
||||||
|
// datepicker 이벤트는 mount 될때 추가 해주어야 한다.
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({ setPageData: 'setPageData' }),
|
||||||
|
getStartDt() {
|
||||||
|
const dt = this.startDatepickerInstance.getDate();
|
||||||
|
this.setPageData({
|
||||||
|
fromDt: Utility.setFormatDate(dt, this.myOptions.sendFormat),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getEndDt() {
|
||||||
|
const dt = this.endDatepickerInstance.getDate();
|
||||||
|
this.setPageData({
|
||||||
|
toDt: Utility.setFormatDate(dt, this.myOptions.sendFormat),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
toDtChanged(newVal, oldVal) {
|
||||||
|
if (
|
||||||
|
this.isRange &&
|
||||||
|
this.defaultRange !== 'no limite' &&
|
||||||
|
newVal !== 'Invalid Date' &&
|
||||||
|
newVal !== oldVal
|
||||||
|
) {
|
||||||
|
this.fromDtValueChkRang(newVal);
|
||||||
|
this.endDatepickerInstance.setDate(new Date(newVal));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fromDtChanged(newVal, oldVal) {
|
||||||
|
if (
|
||||||
|
this.isRange &&
|
||||||
|
this.defaultRange !== 'no limite' &&
|
||||||
|
newVal !== 'Invalid Date' &&
|
||||||
|
newVal !== oldVal
|
||||||
|
) {
|
||||||
|
this.toDtValueChkRang(newVal);
|
||||||
|
this.startDatepickerInstance.setDate(new Date(newVal));
|
||||||
|
} else {
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fromDtValueChkRang(newDt) {
|
||||||
|
const defaultDt = this.$dayjs(this.fromDtValue);
|
||||||
|
const compareDt = this.$dayjs(newDt);
|
||||||
|
const newDefault = Utility.setNewDefaultRange(
|
||||||
|
this.myCmCycle,
|
||||||
|
this.defaultRange,
|
||||||
|
);
|
||||||
|
const myRange = newDefault.range;
|
||||||
|
const rangeKey = newDefault.key;
|
||||||
|
const rangeGap = compareDt.diff(defaultDt, rangeKey);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(myRange > rangeGap && compareDt.isAfter(defaultDt)) ||
|
||||||
|
defaultDt.format(this.myOptions.sendFormat) ===
|
||||||
|
compareDt.format(this.myOptions.sendFormat)
|
||||||
|
) {
|
||||||
|
// if(this.cmCycleFlag){
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
// }
|
||||||
|
// this.cmCycleFlag = true;
|
||||||
|
} else {
|
||||||
|
this.setPageData({
|
||||||
|
fromDt: Utility.setBeforetDate(
|
||||||
|
this.searchParam,
|
||||||
|
compareDt,
|
||||||
|
this.myOptions.sendFormat,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toDtValueChkRang(newDt) {
|
||||||
|
const defaultDt = this.$dayjs(this.toDtValue);
|
||||||
|
const compareDt = this.$dayjs(newDt);
|
||||||
|
const newDefault = Utility.setNewDefaultRange(
|
||||||
|
this.myCmCycle,
|
||||||
|
this.defaultRange,
|
||||||
|
);
|
||||||
|
const myRange = newDefault.range;
|
||||||
|
const rangeKey = newDefault.key;
|
||||||
|
const rangeGap = defaultDt.diff(compareDt, rangeKey);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(myRange > rangeGap && defaultDt.isAfter(compareDt)) ||
|
||||||
|
defaultDt.format(this.myOptions.sendFormat) ===
|
||||||
|
compareDt.format(this.myOptions.sendFormat)
|
||||||
|
) {
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
} else {
|
||||||
|
this.setPageData({
|
||||||
|
toDt: Utility.setAftertDate(
|
||||||
|
this.searchParam,
|
||||||
|
compareDt,
|
||||||
|
this.myOptions.sendFormat,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.datepicker-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.v-input {
|
||||||
|
.v-input__append-outer {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
|
||||||
|
#startpicker-container,
|
||||||
|
#endpicker-container {
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 36px;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-input__custom {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
&.half {
|
||||||
|
width: calc(50% - 20px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::v-deep {
|
||||||
|
.tui-timepicker-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
background-color: #edf4fc;
|
||||||
|
.tui-timepicker-column.tui-timepicker-colon {
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
525
components/common/DatepickerTimeSelectBox.vue
Normal file
@ -0,0 +1,525 @@
|
|||||||
|
<template>
|
||||||
|
<v-row class="search-box" align="center" no-gutters>
|
||||||
|
<v-col v-if="label" :cols="labelCols">
|
||||||
|
<label for="" class="search-box-label">
|
||||||
|
<v-icon x-small :color="required ? '#fb8200' : 'primary'" class="mr-1"
|
||||||
|
>mdi-record-circle</v-icon
|
||||||
|
>
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
</v-col>
|
||||||
|
<v-col :cols="label ? textCols : ''">
|
||||||
|
<div class="datepicker-container">
|
||||||
|
<v-text-field
|
||||||
|
id="startpicker"
|
||||||
|
ref="startpicker"
|
||||||
|
v-model="fromDtValue"
|
||||||
|
:class="(isRange && !selectBoxTimeItemList.selectTimeValue1) ? 'v-input__custom half' : 'v-input__custom'"
|
||||||
|
:hide-details="true"
|
||||||
|
readonly
|
||||||
|
outlined
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<v-icon size="20">$icoCalendar</v-icon>
|
||||||
|
</template>
|
||||||
|
<template #append-outer>
|
||||||
|
<div ref="startpicker-container" id="startpicker-container"></div>
|
||||||
|
</template>
|
||||||
|
</v-text-field>
|
||||||
|
<component
|
||||||
|
v-if="selectBoxTimeItemList.selectTimeValue1"
|
||||||
|
:parentPrgmId="parentPrgmId"
|
||||||
|
:is="'SelectBoxTime'"
|
||||||
|
ref="SelectBox1"
|
||||||
|
:propsValue="selectTimeValue1"
|
||||||
|
:itemList="selectTimeValueList1"
|
||||||
|
:minInterval="selectBoxTimeItemList.minInterval ? selectBoxTimeItemList.minInterval : 1"
|
||||||
|
@update:propsValue="selectTimeValue1 = $event"
|
||||||
|
/>
|
||||||
|
<div v-show="isRange" class="mx-3" :style="{ lineHeight: 0 }">~</div>
|
||||||
|
<v-text-field
|
||||||
|
v-show="isRange"
|
||||||
|
id="endpicker"
|
||||||
|
ref="endpicker"
|
||||||
|
v-model="toDtValue"
|
||||||
|
:class="(isRange && !selectBoxTimeItemList.selectTimeValue2) ? 'v-input__custom half' : 'v-input__custom'"
|
||||||
|
:hide-details="true"
|
||||||
|
readonly
|
||||||
|
outlined
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<v-icon size="20">$icoCalendar</v-icon>
|
||||||
|
</template>
|
||||||
|
<template #append-outer>
|
||||||
|
<div ref="endpicker-container" id="endpicker-container"></div>
|
||||||
|
</template>
|
||||||
|
</v-text-field>
|
||||||
|
<component
|
||||||
|
v-if="selectBoxTimeItemList.selectTimeValue2"
|
||||||
|
:parentPrgmId="parentPrgmId"
|
||||||
|
:is="'SelectBoxTime'"
|
||||||
|
ref="SelectBox2"
|
||||||
|
:propsValue="selectTimeValue2"
|
||||||
|
:itemList="selectTimeValueList2"
|
||||||
|
:minInterval="selectBoxTimeItemList.minInterval ? selectBoxTimeItemList.minInterval : 1"
|
||||||
|
@update:propsValue="selectTimeValue2 = $event"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations } from 'vuex';
|
||||||
|
import TuiDatepicker from 'tui-date-picker';
|
||||||
|
import Utility from '~/plugins/utility';
|
||||||
|
import SelectBoxTime from '@/components/common/select/SelectBoxTime';
|
||||||
|
import DateUtility from '~/plugins/dateUtility'
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
require: false,
|
||||||
|
},
|
||||||
|
timePicker: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
labelCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 4,
|
||||||
|
},
|
||||||
|
textCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 8,
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
isRangeOption:{
|
||||||
|
type:Boolean,
|
||||||
|
require:false,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
selectBoxTimeItemList: {
|
||||||
|
type: Object,
|
||||||
|
require: false,
|
||||||
|
default: () => {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectFromDtUntilTodayFg: {
|
||||||
|
type:Boolean,
|
||||||
|
require:false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
selectToDtUntilTodayFg: {
|
||||||
|
type:Boolean,
|
||||||
|
require:false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
SelectBoxTime
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
today: new Date(),
|
||||||
|
startDatepickerInstance: null,
|
||||||
|
endDatepickerInstance: null,
|
||||||
|
startDtValue: null,
|
||||||
|
endDtValue: null,
|
||||||
|
fromDtOldVal: null,
|
||||||
|
toDtOldVal: null,
|
||||||
|
cmCycleFlag: false,
|
||||||
|
selectTimeValue1: this.selectBoxTimeItemList.selectTimeValue1 != undefined ? this.selectBoxTimeItemList.selectTimeValue1 : null, // selectBoxTime에 필요한 prop
|
||||||
|
selectTimeValueList1: this.selectBoxTimeItemList.selectTimeValueList1 != undefined ? this.selectBoxTimeItemList.selectTimeValueList1 : [], // selectBoxTime에 필요한 prop
|
||||||
|
selectTimeValue2: this.selectBoxTimeItemList.selectTimeValue2 != undefined ? this.selectBoxTimeItemList.selectTimeValue2 : null, // selectBoxTime에 필요한 prop
|
||||||
|
selectTimeValueList2: this.selectBoxTimeItemList.selectTimeValueList2 != undefined ? this.selectBoxTimeItemList.selectTimeValueList2 : [], // selectBoxTime에 필요한 prop
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
searchParam(state) {
|
||||||
|
return state.pageData[this.parentPrgmId];
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
myCmCycle() {
|
||||||
|
return this.searchParam.cmCycle;
|
||||||
|
},
|
||||||
|
myOptions() {
|
||||||
|
let returnObj = {};
|
||||||
|
switch (this.myCmCycle) {
|
||||||
|
case 'CYC_YEAR':
|
||||||
|
returnObj = {
|
||||||
|
type: 'year',
|
||||||
|
viewFormat: 'YYYY',
|
||||||
|
pickerFormat: 'YYYY',
|
||||||
|
sendFormat: 'YYYY',
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CYC_MONTH':
|
||||||
|
returnObj = {
|
||||||
|
type: 'month',
|
||||||
|
viewFormat: 'YYYY-MM',
|
||||||
|
pickerFormat: 'YYYY-MM',
|
||||||
|
sendFormat: 'YYYYMM',
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CYC_DAY':
|
||||||
|
returnObj = {
|
||||||
|
type: 'date',
|
||||||
|
viewFormat: 'YYYY-MM-DD',
|
||||||
|
pickerFormat: 'yyyy-MM-dd',
|
||||||
|
sendFormat: 'YYYYMMDD',
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CYC_HOUR':
|
||||||
|
returnObj = {
|
||||||
|
type: 'date',
|
||||||
|
viewFormat: 'YYYY-MM-DD' + (this.timePicker ? ' HH:mm:ss' : ''),
|
||||||
|
pickerFormat: 'yyyy-MM-dd' + (this.timePicker ? ' HH:mm A' : ''),
|
||||||
|
sendFormat: this.timePicker ? 'YYYY-MM-DD HH:mm:ss' : 'YYYYMMDD',
|
||||||
|
};
|
||||||
|
// returnObj = { type: "day", format: "YYYY-MM-DD HH:mm:ss" };
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return returnObj;
|
||||||
|
},
|
||||||
|
// maxDate() {
|
||||||
|
// return Utility.setFormatDate("today", this.myOptions.format);
|
||||||
|
// },
|
||||||
|
fromDtValue(val) {
|
||||||
|
let selectVal = Utility.setFormatDate(
|
||||||
|
this.searchParam.fromDt,
|
||||||
|
this.myOptions.viewFormat,
|
||||||
|
);
|
||||||
|
if(this.selectFromDtUntilTodayFg){
|
||||||
|
let today = Utility.setFormatDate(new Date(), "YYYY-MM-DD");
|
||||||
|
let dayDiff = DateUtility.diff(selectVal,today,'days');
|
||||||
|
if(dayDiff < 0){
|
||||||
|
alert('오늘 날짜까지 검색이 가능합니다.');
|
||||||
|
selectVal = today;
|
||||||
|
if(this.fromDtOldVal == today){
|
||||||
|
this.toDtValueChkRang(selectVal);
|
||||||
|
this.startDatepickerInstance.setDate(new Date(selectVal));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(this.fromDtOldVal == null){
|
||||||
|
this.fromDtOldVal = selectVal;
|
||||||
|
}
|
||||||
|
return selectVal;
|
||||||
|
// console.log('fromDtValue!!!',);
|
||||||
|
// return Utility.setFormatDate(
|
||||||
|
// this.searchParam.fromDt,
|
||||||
|
// this.myOptions.viewFormat,
|
||||||
|
// );
|
||||||
|
},
|
||||||
|
toDtValue() {
|
||||||
|
let selectVal = Utility.setFormatDate(
|
||||||
|
this.searchParam.toDt,
|
||||||
|
this.myOptions.viewFormat,
|
||||||
|
);
|
||||||
|
if(this.selectToDtUntilTodayFg){
|
||||||
|
let today = Utility.setFormatDate(new Date(), "YYYY-MM-DD");
|
||||||
|
let dayDiff = DateUtility.diff(selectVal,today,'days');
|
||||||
|
if(dayDiff < 0){
|
||||||
|
alert('오늘 날짜까지 검색이 가능합니다.');
|
||||||
|
selectVal = today;
|
||||||
|
if(this.toDtOldVal == today){
|
||||||
|
this.fromDtValueChkRang(selectVal);
|
||||||
|
this.endDatepickerInstance.setDate(new Date(selectVal));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(this.toDtOldVal == null){
|
||||||
|
this.toDtOldVal = selectVal;
|
||||||
|
}
|
||||||
|
return selectVal;
|
||||||
|
// return Utility.setFormatDate(
|
||||||
|
// this.searchParam.toDt,
|
||||||
|
// this.myOptions.viewFormat,
|
||||||
|
// );
|
||||||
|
},
|
||||||
|
defaultRange() {
|
||||||
|
return this.searchParam.defaultRange
|
||||||
|
? this.searchParam.defaultRange[this.myCmCycle]
|
||||||
|
: null;
|
||||||
|
},
|
||||||
|
isRange() {
|
||||||
|
return (
|
||||||
|
(this.defaultRange !== null && this.defaultRange > 0 && this.isRangeOption) ||
|
||||||
|
this.defaultRange === 'no limite'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
selectTimeValue1(val){
|
||||||
|
if(this.selectBoxTimeItemList.selectTimeValue2 != undefined){
|
||||||
|
this.setSelectTimeValue2(val);
|
||||||
|
}else{
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selectTimeValue2(val){
|
||||||
|
this.setSelectTimeValue1(val);
|
||||||
|
// this.setPageData({ isFind: true });
|
||||||
|
},
|
||||||
|
myCmCycle() {
|
||||||
|
this.cmCycleFlag = false;
|
||||||
|
this.startDatepickerInstance.setDate(new Date(this.fromDtValue));
|
||||||
|
this.startDatepickerInstance.setType(this.myOptions.type);
|
||||||
|
this.endDatepickerInstance.setType(this.myOptions.type);
|
||||||
|
},
|
||||||
|
fromDtValue(newVal, oldVal) {
|
||||||
|
if (
|
||||||
|
this.isRange &&
|
||||||
|
this.defaultRange !== 'no limite' &&
|
||||||
|
newVal !== 'Invalid Date' &&
|
||||||
|
newVal !== oldVal
|
||||||
|
) {
|
||||||
|
this.toDtValueChkRang(newVal);
|
||||||
|
this.startDatepickerInstance.setDate(new Date(newVal));
|
||||||
|
this.fromDtOldVal = newVal;
|
||||||
|
this.setSelectTimeValue1(this.selectTimeValue2, 'check');
|
||||||
|
this.setSelectTimeValue2(this.selectTimeValue1, 'check');
|
||||||
|
} else {
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toDtValue(newVal, oldVal) {
|
||||||
|
if (
|
||||||
|
this.isRange &&
|
||||||
|
this.defaultRange !== 'no limite' &&
|
||||||
|
newVal !== 'Invalid Date' &&
|
||||||
|
newVal !== oldVal
|
||||||
|
) {
|
||||||
|
this.fromDtValueChkRang(newVal);
|
||||||
|
this.endDatepickerInstance.setDate(new Date(newVal));
|
||||||
|
this.toDtOldVal = newVal;
|
||||||
|
this.setSelectTimeValue1(this.selectTimeValue2, 'check');
|
||||||
|
this.setSelectTimeValue2(this.selectTimeValue1, 'check');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if (this.timePicker) {
|
||||||
|
this.setPageData({
|
||||||
|
fromDt: Utility.setFormatDate(this.today, 'YYYY-MM-DD') + ' 00:00:00',
|
||||||
|
toDt: Utility.setFormatDate(this.today, 'YYYY-MM-DD') + ' 23:59:59',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const startContainer = document.getElementById('startpicker-container');
|
||||||
|
const startTarget = document.getElementById('startpicker');
|
||||||
|
const endContainer = document.getElementById('endpicker-container');
|
||||||
|
const endTarget = document.getElementById('endpicker');
|
||||||
|
|
||||||
|
// datepicker 생성
|
||||||
|
this.startDatepickerInstance = new TuiDatepicker(startContainer, {
|
||||||
|
date: this.today,
|
||||||
|
language: 'ko',
|
||||||
|
type: this.myOptions.type, // "date", // type: date || month || year
|
||||||
|
input: {
|
||||||
|
element: startTarget,
|
||||||
|
format: this.myOptions.pickerFormat, //"YYYY-MM-DD" //this.format
|
||||||
|
},
|
||||||
|
timePicker: this.timePicker,
|
||||||
|
calendar: {
|
||||||
|
showToday: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// datepicker 생성
|
||||||
|
this.endDatepickerInstance = new TuiDatepicker(endContainer, {
|
||||||
|
date: this.today,
|
||||||
|
language: 'ko',
|
||||||
|
type: this.myOptions.type, // "date", // type: date || month || year
|
||||||
|
input: {
|
||||||
|
element: endTarget,
|
||||||
|
format: this.myOptions.pickerFormat, //"YYYY-MM-DD" //this.format
|
||||||
|
},
|
||||||
|
timePicker: this.timePicker,
|
||||||
|
calendar: {
|
||||||
|
showToday: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// datepicker 생성 끝
|
||||||
|
|
||||||
|
// datepicker 초기값 생성
|
||||||
|
this.startDatepickerInstance.setDate(new Date(this.fromDtValue));
|
||||||
|
// datepicker 초기값 생성 끝
|
||||||
|
|
||||||
|
// datepicker 변경시 이벤트 추가
|
||||||
|
this.startDatepickerInstance.on('change', () => this.getStartDt());
|
||||||
|
this.endDatepickerInstance.on('change', () => this.getEndDt());
|
||||||
|
// datepicker 이벤트는 mount 될때 추가 해주어야 한다.
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({ setPageData: 'setPageData' }),
|
||||||
|
getStartDt() {
|
||||||
|
const dt = this.startDatepickerInstance.getDate();
|
||||||
|
this.setPageData({
|
||||||
|
fromDt: Utility.setFormatDate(dt, this.myOptions.sendFormat),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getEndDt() {
|
||||||
|
const dt = this.endDatepickerInstance.getDate();
|
||||||
|
this.setPageData({
|
||||||
|
toDt: Utility.setFormatDate(dt, this.myOptions.sendFormat),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fromDtValueChkRang(newDt) {
|
||||||
|
const defaultDt = this.$dayjs(this.fromDtValue);
|
||||||
|
const compareDt = this.$dayjs(newDt);
|
||||||
|
const newDefault = Utility.setNewDefaultRange(
|
||||||
|
this.myCmCycle,
|
||||||
|
this.defaultRange,
|
||||||
|
);
|
||||||
|
const myRange = newDefault.range;
|
||||||
|
const rangeKey = newDefault.key;
|
||||||
|
const rangeGap = compareDt.diff(defaultDt, rangeKey);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(myRange > rangeGap && compareDt.isAfter(defaultDt)) ||
|
||||||
|
defaultDt.format(this.myOptions.sendFormat) ===
|
||||||
|
compareDt.format(this.myOptions.sendFormat)
|
||||||
|
) {
|
||||||
|
// if(this.cmCycleFlag){
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
// }
|
||||||
|
// this.cmCycleFlag = true;
|
||||||
|
} else {
|
||||||
|
this.setPageData({
|
||||||
|
fromDt: Utility.setBeforetDate(
|
||||||
|
this.searchParam,
|
||||||
|
compareDt,
|
||||||
|
this.myOptions.sendFormat,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toDtValueChkRang(newDt) {
|
||||||
|
const defaultDt = this.$dayjs(this.toDtValue);
|
||||||
|
const compareDt = this.$dayjs(newDt);
|
||||||
|
const newDefault = Utility.setNewDefaultRange(
|
||||||
|
this.myCmCycle,
|
||||||
|
this.defaultRange,
|
||||||
|
);
|
||||||
|
const myRange = newDefault.range;
|
||||||
|
const rangeKey = newDefault.key;
|
||||||
|
const rangeGap = defaultDt.diff(compareDt, rangeKey);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(myRange > rangeGap && defaultDt.isAfter(compareDt)) ||
|
||||||
|
defaultDt.format(this.myOptions.sendFormat) ===
|
||||||
|
compareDt.format(this.myOptions.sendFormat)
|
||||||
|
) {
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
} else {
|
||||||
|
this.setPageData({
|
||||||
|
toDt: Utility.setAftertDate(
|
||||||
|
this.searchParam,
|
||||||
|
compareDt,
|
||||||
|
this.myOptions.sendFormat,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setSelectTimeValue2(val, type='default'){
|
||||||
|
this.setPageData({selectTimeValue1:val});
|
||||||
|
let toDt = this.toDtOldVal;
|
||||||
|
let fromDt = this.fromDtOldVal;
|
||||||
|
let dayDiff = DateUtility.diff(fromDt,toDt,'days');
|
||||||
|
let selectTimeValueList2 = this.selectTimeValueList2.map(item => {
|
||||||
|
return item.value;
|
||||||
|
});
|
||||||
|
if(dayDiff <= 0 && selectTimeValueList2.indexOf(this.selectTimeValue2) < selectTimeValueList2.indexOf(val)){
|
||||||
|
// this.selectTimeValue2 = selectTimeValueList2[selectTimeValueList2.indexOf(val)];
|
||||||
|
this.selectTimeValue2 = val;
|
||||||
|
this.setPageData({selectTimeValue2:val});
|
||||||
|
}else{
|
||||||
|
if(type=='default'){
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setSelectTimeValue1(val, type='default'){
|
||||||
|
this.setPageData({selectTimeValue2:val});
|
||||||
|
let toDt = this.toDtOldVal;
|
||||||
|
let fromDt = this.fromDtOldVal;
|
||||||
|
let dayDiff = DateUtility.diff(fromDt,toDt,'days');
|
||||||
|
let selectTimeValueList2 = this.selectTimeValueList2.map(item => {
|
||||||
|
return item.value;
|
||||||
|
});
|
||||||
|
if(dayDiff <= 0 && selectTimeValueList2.indexOf(val) < selectTimeValueList2.indexOf(this.selectTimeValue1)){
|
||||||
|
// this.selectTimeValue1 = selectTimeValueList2[selectTimeValueList2.indexOf(val)];
|
||||||
|
this.selectTimeValue1 = val;
|
||||||
|
// this.selectTimeValue1 = this.selectTimeValueList2[selectTimeValueList2.indexOf(val) + 1]
|
||||||
|
this.setPageData({selectTimeValue1:val});
|
||||||
|
}else{
|
||||||
|
if(type=='default'){
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.datepicker-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.v-input {
|
||||||
|
.v-input__append-outer {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
|
||||||
|
#startpicker-container,
|
||||||
|
#endpicker-container {
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 36px;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-input__custom {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
&.half {
|
||||||
|
width: calc(50% - 20px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::v-deep {
|
||||||
|
.tui-timepicker-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
background-color: #edf4fc;
|
||||||
|
.tui-timepicker-column.tui-timepicker-colon {
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
442
components/common/DatepickerTopView.vue
Normal file
@ -0,0 +1,442 @@
|
|||||||
|
<template>
|
||||||
|
<v-row class="search-box" align="center" no-gutters>
|
||||||
|
<v-col v-if="label" :cols="labelCols">
|
||||||
|
<label for="" class="search-box-label">
|
||||||
|
<v-icon x-small :color="required ? '#fb8200' : 'primary'" class="mr-1"
|
||||||
|
>mdi-record-circle</v-icon
|
||||||
|
>
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
</v-col>
|
||||||
|
<v-col :cols="label ? textCols : ''">
|
||||||
|
<div class="datepicker-container">
|
||||||
|
<v-text-field
|
||||||
|
id="startpicker"
|
||||||
|
ref="startpicker"
|
||||||
|
v-model="fromDtValue"
|
||||||
|
:class="isRange ? 'v-input__custom half' : 'v-input__custom'"
|
||||||
|
:hide-details="true"
|
||||||
|
readonly
|
||||||
|
outlined
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<v-icon size="20">$icoCalendar</v-icon>
|
||||||
|
</template>
|
||||||
|
<template #append-outer>
|
||||||
|
<div ref="startpicker-container" id="startpicker-container"></div>
|
||||||
|
</template>
|
||||||
|
</v-text-field>
|
||||||
|
<div v-show="isRange" class="mx-3" :style="{ lineHeight: 0 }">~</div>
|
||||||
|
<v-text-field
|
||||||
|
v-show="isRange"
|
||||||
|
id="endpicker"
|
||||||
|
ref="endpicker"
|
||||||
|
v-model="toDtValue"
|
||||||
|
:class="isRange ? 'v-input__custom half' : 'v-input__custom'"
|
||||||
|
:hide-details="true"
|
||||||
|
readonly
|
||||||
|
outlined
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<v-icon size="20">$icoCalendar</v-icon>
|
||||||
|
</template>
|
||||||
|
<template #append-outer>
|
||||||
|
<div ref="endpicker-container" id="endpicker-container"></div>
|
||||||
|
</template>
|
||||||
|
</v-text-field>
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations } from 'vuex';
|
||||||
|
import TuiDatepicker from 'tui-date-picker';
|
||||||
|
import Utility from '~/plugins/utility';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
require: false,
|
||||||
|
},
|
||||||
|
timePicker: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
labelCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 4,
|
||||||
|
},
|
||||||
|
textCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 8,
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
isRangeOption:{
|
||||||
|
type:Boolean,
|
||||||
|
require:false,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
today: new Date(),
|
||||||
|
startDatepickerInstance: null,
|
||||||
|
endDatepickerInstance: null,
|
||||||
|
startDtValue: null,
|
||||||
|
endDtValue: null,
|
||||||
|
cmCycleFlag: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
searchParam(state) {
|
||||||
|
return state.pageData[this.parentPrgmId];
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
myCmCycle() {
|
||||||
|
return this.searchParam.cmCycle;
|
||||||
|
},
|
||||||
|
myOptions() {
|
||||||
|
let returnObj = {};
|
||||||
|
switch (this.myCmCycle) {
|
||||||
|
case 'CYC_YEAR':
|
||||||
|
returnObj = {
|
||||||
|
type: 'year',
|
||||||
|
viewFormat: 'YYYY',
|
||||||
|
pickerFormat: 'YYYY',
|
||||||
|
sendFormat: 'YYYY',
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CYC_MONTH':
|
||||||
|
returnObj = {
|
||||||
|
type: 'month',
|
||||||
|
viewFormat: 'YYYY-MM',
|
||||||
|
pickerFormat: 'YYYY-MM',
|
||||||
|
sendFormat: 'YYYYMM',
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CYC_DAY':
|
||||||
|
returnObj = {
|
||||||
|
type: 'date',
|
||||||
|
viewFormat: 'YYYY-MM-DD',
|
||||||
|
pickerFormat: 'yyyy-MM-dd',
|
||||||
|
sendFormat: 'YYYYMMDD',
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CYC_HOUR':
|
||||||
|
returnObj = {
|
||||||
|
type: 'date',
|
||||||
|
viewFormat: 'YYYY-MM-DD' + (this.timePicker ? ' HH:mm:ss' : ''),
|
||||||
|
pickerFormat: 'yyyy-MM-dd' + (this.timePicker ? ' HH:mm A' : ''),
|
||||||
|
sendFormat: this.timePicker ? 'YYYY-MM-DD HH:mm:ss' : 'YYYYMMDD',
|
||||||
|
};
|
||||||
|
// returnObj = { type: "day", format: "YYYY-MM-DD HH:mm:ss" };
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return returnObj;
|
||||||
|
},
|
||||||
|
// maxDate() {
|
||||||
|
// return Utility.setFormatDate("today", this.myOptions.format);
|
||||||
|
// },
|
||||||
|
fromDtValue() {
|
||||||
|
return Utility.setFormatDate(
|
||||||
|
this.searchParam.fromDt,
|
||||||
|
this.myOptions.viewFormat,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
toDtValue() {
|
||||||
|
return Utility.setFormatDate(
|
||||||
|
this.searchParam.toDt,
|
||||||
|
this.myOptions.viewFormat,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
toDtChange(){
|
||||||
|
return {
|
||||||
|
isCheck:this.searchParam.isCheck ,
|
||||||
|
toDt : Utility.setFormatDate(
|
||||||
|
this.searchParam.toDt,
|
||||||
|
this.myOptions.viewFormat,
|
||||||
|
)};
|
||||||
|
},
|
||||||
|
fromDtChange(){
|
||||||
|
return {
|
||||||
|
isCheck:this.searchParam.isCheck ,
|
||||||
|
fromDt : Utility.setFormatDate(
|
||||||
|
this.searchParam.fromDt,
|
||||||
|
this.myOptions.viewFormat,
|
||||||
|
)};
|
||||||
|
},
|
||||||
|
defaultRange() {
|
||||||
|
return this.searchParam.defaultRange
|
||||||
|
? this.searchParam.defaultRange[this.myCmCycle]
|
||||||
|
: null;
|
||||||
|
},
|
||||||
|
isRange() {
|
||||||
|
return (
|
||||||
|
(this.defaultRange !== null && this.defaultRange > 0 && this.isRangeOption) ||
|
||||||
|
this.defaultRange === 'no limite'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
myCmCycle() {
|
||||||
|
this.cmCycleFlag = false;
|
||||||
|
this.startDatepickerInstance.setDate(new Date(this.fromDtValue));
|
||||||
|
this.startDatepickerInstance.setType(this.myOptions.type);
|
||||||
|
this.endDatepickerInstance.setType(this.myOptions.type);
|
||||||
|
},
|
||||||
|
fromDtValue(newVal, oldVal) {
|
||||||
|
if (
|
||||||
|
this.isRange &&
|
||||||
|
this.defaultRange !== 'no limite' &&
|
||||||
|
newVal !== 'Invalid Date' &&
|
||||||
|
newVal !== oldVal
|
||||||
|
) {
|
||||||
|
this.toDtValueChkRang(newVal);
|
||||||
|
this.startDatepickerInstance.setDate(new Date(newVal));
|
||||||
|
} else {
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toDtValue(newVal, oldVal) {
|
||||||
|
if (
|
||||||
|
this.isRange &&
|
||||||
|
this.defaultRange !== 'no limite' &&
|
||||||
|
newVal !== 'Invalid Date' &&
|
||||||
|
newVal !== oldVal
|
||||||
|
) {
|
||||||
|
this.fromDtValueChkRang(newVal);
|
||||||
|
this.endDatepickerInstance.setDate(new Date(newVal));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fromDtChange:{
|
||||||
|
deep:true,
|
||||||
|
handler(){
|
||||||
|
if(this.fromDtChange.isCheck){
|
||||||
|
this.fromDtChanged(this.fromDtChange.fromDt);
|
||||||
|
this.setPageData({
|
||||||
|
isCheck : false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toDtChange:{
|
||||||
|
deep:true,
|
||||||
|
handler(){
|
||||||
|
if(this.toDtChange.isCheck){
|
||||||
|
this.toDtChanged(this.toDtChange.toDt);
|
||||||
|
this.setPageData({
|
||||||
|
isCheck : false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if (this.timePicker) {
|
||||||
|
this.setPageData({
|
||||||
|
fromDt: Utility.setFormatDate(this.today, 'YYYY-MM-DD') + ' 00:00:00',
|
||||||
|
toDt: Utility.setFormatDate(this.today, 'YYYY-MM-DD') + ' 23:59:59',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const startContainer = document.getElementById('startpicker-container');
|
||||||
|
const startTarget = document.getElementById('startpicker');
|
||||||
|
const endContainer = document.getElementById('endpicker-container');
|
||||||
|
const endTarget = document.getElementById('endpicker');
|
||||||
|
|
||||||
|
// datepicker 생성
|
||||||
|
this.startDatepickerInstance = new TuiDatepicker(startContainer, {
|
||||||
|
date: this.today,
|
||||||
|
language: 'ko',
|
||||||
|
type: this.myOptions.type, // "date", // type: date || month || year
|
||||||
|
input: {
|
||||||
|
element: startTarget,
|
||||||
|
format: this.myOptions.pickerFormat, //"YYYY-MM-DD" //this.format
|
||||||
|
},
|
||||||
|
timePicker: this.timePicker,
|
||||||
|
calendar: {
|
||||||
|
showToday: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// datepicker 생성
|
||||||
|
this.endDatepickerInstance = new TuiDatepicker(endContainer, {
|
||||||
|
date: this.today,
|
||||||
|
language: 'ko',
|
||||||
|
type: this.myOptions.type, // "date", // type: date || month || year
|
||||||
|
input: {
|
||||||
|
element: endTarget,
|
||||||
|
format: this.myOptions.pickerFormat, //"YYYY-MM-DD" //this.format
|
||||||
|
},
|
||||||
|
timePicker: this.timePicker,
|
||||||
|
calendar: {
|
||||||
|
showToday: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// datepicker 생성 끝
|
||||||
|
|
||||||
|
// datepicker 초기값 생성
|
||||||
|
this.startDatepickerInstance.setDate(new Date(this.fromDtValue));
|
||||||
|
// datepicker 초기값 생성 끝
|
||||||
|
|
||||||
|
// datepicker 변경시 이벤트 추가
|
||||||
|
this.startDatepickerInstance.on('change', () => this.getStartDt());
|
||||||
|
this.endDatepickerInstance.on('change', () => this.getEndDt());
|
||||||
|
// datepicker 이벤트는 mount 될때 추가 해주어야 한다.
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({ setPageData: 'setPageData' }),
|
||||||
|
getStartDt() {
|
||||||
|
const dt = this.startDatepickerInstance.getDate();
|
||||||
|
this.setPageData({
|
||||||
|
fromDt: Utility.setFormatDate(dt, this.myOptions.sendFormat),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getEndDt() {
|
||||||
|
const dt = this.endDatepickerInstance.getDate();
|
||||||
|
this.setPageData({
|
||||||
|
toDt: Utility.setFormatDate(dt, this.myOptions.sendFormat),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
toDtChanged(newVal, oldVal) {
|
||||||
|
if (
|
||||||
|
this.isRange &&
|
||||||
|
this.defaultRange !== 'no limite' &&
|
||||||
|
newVal !== 'Invalid Date' &&
|
||||||
|
newVal !== oldVal
|
||||||
|
) {
|
||||||
|
this.fromDtValueChkRang(newVal);
|
||||||
|
this.endDatepickerInstance.setDate(new Date(newVal));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fromDtChanged(newVal, oldVal) {
|
||||||
|
if (
|
||||||
|
this.isRange &&
|
||||||
|
this.defaultRange !== 'no limite' &&
|
||||||
|
newVal !== 'Invalid Date' &&
|
||||||
|
newVal !== oldVal
|
||||||
|
) {
|
||||||
|
this.toDtValueChkRang(newVal);
|
||||||
|
this.startDatepickerInstance.setDate(new Date(newVal));
|
||||||
|
} else {
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fromDtValueChkRang(newDt) {
|
||||||
|
const defaultDt = this.$dayjs(this.fromDtValue);
|
||||||
|
const compareDt = this.$dayjs(newDt);
|
||||||
|
const newDefault = Utility.setNewDefaultRange(
|
||||||
|
this.myCmCycle,
|
||||||
|
this.defaultRange,
|
||||||
|
);
|
||||||
|
const myRange = newDefault.range;
|
||||||
|
const rangeKey = newDefault.key;
|
||||||
|
const rangeGap = compareDt.diff(defaultDt, rangeKey);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(myRange > rangeGap && compareDt.isAfter(defaultDt)) ||
|
||||||
|
defaultDt.format(this.myOptions.sendFormat) ===
|
||||||
|
compareDt.format(this.myOptions.sendFormat)
|
||||||
|
) {
|
||||||
|
// if(this.cmCycleFlag){
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
// }
|
||||||
|
// this.cmCycleFlag = true;
|
||||||
|
} else {
|
||||||
|
this.setPageData({
|
||||||
|
fromDt: Utility.setBeforetDate(
|
||||||
|
this.searchParam,
|
||||||
|
compareDt,
|
||||||
|
this.myOptions.sendFormat,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toDtValueChkRang(newDt) {
|
||||||
|
const defaultDt = this.$dayjs(this.toDtValue);
|
||||||
|
const compareDt = this.$dayjs(newDt);
|
||||||
|
const newDefault = Utility.setNewDefaultRange(
|
||||||
|
this.myCmCycle,
|
||||||
|
this.defaultRange,
|
||||||
|
);
|
||||||
|
const myRange = newDefault.range;
|
||||||
|
const rangeKey = newDefault.key;
|
||||||
|
const rangeGap = defaultDt.diff(compareDt, rangeKey);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(myRange > rangeGap && defaultDt.isAfter(compareDt)) ||
|
||||||
|
defaultDt.format(this.myOptions.sendFormat) ===
|
||||||
|
compareDt.format(this.myOptions.sendFormat)
|
||||||
|
) {
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
} else {
|
||||||
|
this.setPageData({
|
||||||
|
toDt: Utility.setAftertDate(
|
||||||
|
this.searchParam,
|
||||||
|
compareDt,
|
||||||
|
this.myOptions.sendFormat,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.datepicker-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.v-input {
|
||||||
|
.v-input__append-outer {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
|
||||||
|
#startpicker-container,
|
||||||
|
#endpicker-container {
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: -260px;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-input__custom {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
&.half {
|
||||||
|
width: calc(50% - 20px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::v-deep {
|
||||||
|
.tui-timepicker-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
background-color: #edf4fc;
|
||||||
|
.tui-timepicker-column.tui-timepicker-colon {
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
396
components/common/DatepickerWidget.vue
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
<template>
|
||||||
|
<v-row class="search-box" align="center" no-gutters>
|
||||||
|
<v-col v-if="label" :cols="labelCols">
|
||||||
|
<label for="" class="search-box-label">
|
||||||
|
<v-icon x-small color="primary" class="mr-1">mdi-record-circle</v-icon>
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
</v-col>
|
||||||
|
<v-col :cols="label ? textCols : ''">
|
||||||
|
<div class="datepicker-container">
|
||||||
|
<v-text-field
|
||||||
|
id="startpicker"
|
||||||
|
ref="startpicker"
|
||||||
|
v-model="fromDtValue"
|
||||||
|
:class="isRange ? 'v-input__custom half' : 'v-input__custom'"
|
||||||
|
:hide-details="true"
|
||||||
|
readonly
|
||||||
|
outlined
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<v-icon size="20">$icoCalendar</v-icon>
|
||||||
|
</template>
|
||||||
|
<template #append-outer>
|
||||||
|
<div ref="startpicker-container" id="startpicker-container"></div>
|
||||||
|
</template>
|
||||||
|
</v-text-field>
|
||||||
|
<div v-show="isRange" class="mx-3" :style="{ lineHeight: 0 }">~</div>
|
||||||
|
<v-text-field
|
||||||
|
v-show="isRange"
|
||||||
|
id="endpicker"
|
||||||
|
ref="endpicker"
|
||||||
|
v-model="toDtValue"
|
||||||
|
:class="isRange ? 'v-input__custom half' : 'v-input__custom'"
|
||||||
|
:hide-details="true"
|
||||||
|
readonly
|
||||||
|
outlined
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<v-icon size="20">$icoCalendar</v-icon>
|
||||||
|
</template>
|
||||||
|
<template #append-outer>
|
||||||
|
<div ref="endpicker-container" id="endpicker-container"></div>
|
||||||
|
</template>
|
||||||
|
</v-text-field>
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations } from 'vuex';
|
||||||
|
import TuiDatepicker from 'tui-date-picker';
|
||||||
|
import Utility from '~/plugins/utility';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
require: false,
|
||||||
|
},
|
||||||
|
timePicker: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
labelCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 4,
|
||||||
|
},
|
||||||
|
textCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 8,
|
||||||
|
},
|
||||||
|
widgetPage: {
|
||||||
|
type: String,
|
||||||
|
require: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
today: new Date(),
|
||||||
|
startDatepickerInstance: null,
|
||||||
|
endDatepickerInstance: null,
|
||||||
|
startDtValue: null,
|
||||||
|
endDtValue: null,
|
||||||
|
cmCycleFlag: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
searchParam(state) {
|
||||||
|
return state.pageData[this.parentPrgmId][this.widgetPage][
|
||||||
|
this.widgetPage + 'Data'
|
||||||
|
];
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
myCmCycle() {
|
||||||
|
return this.$store.state.pageData[this.parentPrgmId][this.widgetPage][
|
||||||
|
this.widgetPage + 'Data'
|
||||||
|
].cmCycle;
|
||||||
|
},
|
||||||
|
myOptions() {
|
||||||
|
let returnObj = {};
|
||||||
|
switch (this.myCmCycle) {
|
||||||
|
case 'CYC_YEAR':
|
||||||
|
returnObj = {
|
||||||
|
type: 'year',
|
||||||
|
viewFormat: 'YYYY',
|
||||||
|
pickerFormat: 'YYYY',
|
||||||
|
sendFormat: 'YYYY',
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CYC_MONTH':
|
||||||
|
returnObj = {
|
||||||
|
type: 'month',
|
||||||
|
viewFormat: 'YYYY-MM',
|
||||||
|
pickerFormat: 'YYYY-MM',
|
||||||
|
sendFormat: 'YYYYMM',
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CYC_DAY':
|
||||||
|
returnObj = {
|
||||||
|
type: 'date',
|
||||||
|
viewFormat: 'YYYY-MM-DD',
|
||||||
|
pickerFormat: 'yyyy-MM-dd',
|
||||||
|
sendFormat: 'YYYYMMDD',
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CYC_HOUR':
|
||||||
|
returnObj = {
|
||||||
|
type: 'date',
|
||||||
|
viewFormat: 'YYYY-MM-DD' + (this.timePicker ? ' HH:mm:ss' : ''),
|
||||||
|
pickerFormat: 'yyyy-MM-dd' + (this.timePicker ? ' HH:mm A' : ''),
|
||||||
|
sendFormat: this.timePicker ? 'YYYY-MM-DD HH:mm:ss' : 'YYYYMMDD',
|
||||||
|
};
|
||||||
|
// returnObj = { type: "day", format: "YYYY-MM-DD HH:mm:ss" };
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return returnObj;
|
||||||
|
},
|
||||||
|
// maxDate() {
|
||||||
|
// return Utility.setFormatDate("today", this.myOptions.format);
|
||||||
|
// },
|
||||||
|
fromDtValue() {
|
||||||
|
return Utility.setFormatDate(
|
||||||
|
this.$store.state.pageData[this.parentPrgmId][this.widgetPage][
|
||||||
|
this.widgetPage + 'Data'
|
||||||
|
].fromDt,
|
||||||
|
this.myOptions.viewFormat,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
toDtValue() {
|
||||||
|
return Utility.setFormatDate(
|
||||||
|
// this.$store.state.pageData[this.parentPrgmId][this.widgetPage][this.widgetPage+'Data'].toDt,
|
||||||
|
this.$store.state.pageData[this.parentPrgmId][this.widgetPage][
|
||||||
|
this.widgetPage + 'Data'
|
||||||
|
].toDt,
|
||||||
|
this.myOptions.viewFormat,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
defaultRange() {
|
||||||
|
return this.$store.state.pageData[this.parentPrgmId][this.widgetPage][
|
||||||
|
this.widgetPage + 'Data'
|
||||||
|
].defaultRange
|
||||||
|
? this.$store.state.pageData[this.parentPrgmId][this.widgetPage][
|
||||||
|
this.widgetPage + 'Data'
|
||||||
|
].defaultRange[this.myCmCycle]
|
||||||
|
: null;
|
||||||
|
},
|
||||||
|
isRange() {
|
||||||
|
return (
|
||||||
|
(this.defaultRange !== null && this.defaultRange > 0) ||
|
||||||
|
this.defaultRange === 'no limite'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
myCmCycle() {
|
||||||
|
this.cmCycleFlag = false;
|
||||||
|
this.startDatepickerInstance.setDate(new Date(this.fromDtValue));
|
||||||
|
this.startDatepickerInstance.setType(this.myOptions.type);
|
||||||
|
this.endDatepickerInstance.setType(this.myOptions.type);
|
||||||
|
},
|
||||||
|
fromDtValue(newVal, oldVal) {
|
||||||
|
if (
|
||||||
|
this.isRange &&
|
||||||
|
this.defaultRange !== 'no limite' &&
|
||||||
|
newVal !== 'Invalid Date' &&
|
||||||
|
newVal !== oldVal
|
||||||
|
) {
|
||||||
|
this.toDtValueChkRang(newVal);
|
||||||
|
this.startDatepickerInstance.setDate(new Date(newVal));
|
||||||
|
} else {
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toDtValue(newVal, oldVal) {
|
||||||
|
if (
|
||||||
|
this.isRange &&
|
||||||
|
this.defaultRange !== 'no limite' &&
|
||||||
|
newVal !== 'Invalid Date' &&
|
||||||
|
newVal !== oldVal
|
||||||
|
) {
|
||||||
|
this.fromDtValueChkRang(newVal);
|
||||||
|
this.endDatepickerInstance.setDate(new Date(newVal));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if (this.timePicker) {
|
||||||
|
this.setPageData({
|
||||||
|
fromDt: Utility.setFormatDate(this.today, 'YYYY-MM-DD') + ' 00:00:00',
|
||||||
|
toDt: Utility.setFormatDate(this.today, 'YYYY-MM-DD') + ' 23:59:59',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const startContainer = document.getElementById('startpicker-container');
|
||||||
|
const startTarget = document.getElementById('startpicker');
|
||||||
|
const endContainer = document.getElementById('endpicker-container');
|
||||||
|
const endTarget = document.getElementById('endpicker');
|
||||||
|
|
||||||
|
// datepicker 생성
|
||||||
|
this.startDatepickerInstance = new TuiDatepicker(startContainer, {
|
||||||
|
date: this.today,
|
||||||
|
language: 'ko',
|
||||||
|
type: this.myOptions.type, // "date", // type: date || month || year
|
||||||
|
input: {
|
||||||
|
element: startTarget,
|
||||||
|
format: this.myOptions.pickerFormat, //"YYYY-MM-DD" //this.format
|
||||||
|
},
|
||||||
|
timePicker: this.timePicker,
|
||||||
|
calendar: {
|
||||||
|
showToday: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// datepicker 생성
|
||||||
|
this.endDatepickerInstance = new TuiDatepicker(endContainer, {
|
||||||
|
date: this.today,
|
||||||
|
language: 'ko',
|
||||||
|
type: this.myOptions.type, // "date", // type: date || month || year
|
||||||
|
input: {
|
||||||
|
element: endTarget,
|
||||||
|
format: this.myOptions.pickerFormat, //"YYYY-MM-DD" //this.format
|
||||||
|
},
|
||||||
|
timePicker: this.timePicker,
|
||||||
|
calendar: {
|
||||||
|
showToday: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// datepicker 생성 끝
|
||||||
|
|
||||||
|
// datepicker 초기값 생성
|
||||||
|
this.startDatepickerInstance.setDate(new Date(this.fromDtValue));
|
||||||
|
// datepicker 초기값 생성 끝
|
||||||
|
|
||||||
|
// datepicker 변경시 이벤트 추가
|
||||||
|
this.startDatepickerInstance.on('change', () => this.getStartDt());
|
||||||
|
this.endDatepickerInstance.on('change', () => this.getEndDt());
|
||||||
|
// datepicker 이벤트는 mount 될때 추가 해주어야 한다.
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({ setPageData: 'setPageData' }),
|
||||||
|
getStartDt() {
|
||||||
|
const dt = this.startDatepickerInstance.getDate();
|
||||||
|
this.setPageData({
|
||||||
|
fromDt: Utility.setFormatDate(dt, this.myOptions.sendFormat),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getEndDt() {
|
||||||
|
const dt = this.endDatepickerInstance.getDate();
|
||||||
|
this.setPageData({
|
||||||
|
toDt: Utility.setFormatDate(dt, this.myOptions.sendFormat),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fromDtValueChkRang(newDt) {
|
||||||
|
const defaultDt = this.$dayjs(this.fromDtValue);
|
||||||
|
const compareDt = this.$dayjs(newDt);
|
||||||
|
const newDefault = Utility.setNewDefaultRange(
|
||||||
|
this.myCmCycle,
|
||||||
|
this.defaultRange,
|
||||||
|
);
|
||||||
|
const myRange = newDefault.range;
|
||||||
|
const rangeKey = newDefault.key;
|
||||||
|
const rangeGap = compareDt.diff(defaultDt, rangeKey);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(myRange > rangeGap && compareDt.isAfter(defaultDt)) ||
|
||||||
|
defaultDt.format(this.myOptions.sendFormat) ===
|
||||||
|
compareDt.format(this.myOptions.sendFormat)
|
||||||
|
) {
|
||||||
|
// if(this.cmCycleFlag){
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
// }
|
||||||
|
// this.cmCycleFlag = true;
|
||||||
|
} else {
|
||||||
|
// this.setPageData({
|
||||||
|
// fromDt: Utility.setBeforetDate(
|
||||||
|
// this.$store.state.pageData[this.parentPrgmId][this.widgetPage][this.widgetPage+'Data'].fromDt,
|
||||||
|
// compareDt,
|
||||||
|
// this.myOptions.sendFormat
|
||||||
|
// )
|
||||||
|
// });
|
||||||
|
this.$store.state.pageData[this.parentPrgmId][this.widgetPage][
|
||||||
|
this.widgetPage + 'Data'
|
||||||
|
].fromDt = Utility.setBeforetDate(
|
||||||
|
this.$store.state.pageData[this.parentPrgmId][this.widgetPage][
|
||||||
|
this.widgetPage + 'Data'
|
||||||
|
],
|
||||||
|
compareDt,
|
||||||
|
this.myOptions.sendFormat,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toDtValueChkRang(newDt) {
|
||||||
|
const defaultDt = this.$dayjs(this.toDtValue);
|
||||||
|
const compareDt = this.$dayjs(newDt);
|
||||||
|
const newDefault = Utility.setNewDefaultRange(
|
||||||
|
this.myCmCycle,
|
||||||
|
this.defaultRange,
|
||||||
|
);
|
||||||
|
const myRange = newDefault.range;
|
||||||
|
const rangeKey = newDefault.key;
|
||||||
|
const rangeGap = defaultDt.diff(compareDt, rangeKey);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(myRange > rangeGap && defaultDt.isAfter(compareDt)) ||
|
||||||
|
defaultDt.format(this.myOptions.sendFormat) ===
|
||||||
|
compareDt.format(this.myOptions.sendFormat)
|
||||||
|
) {
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
} else {
|
||||||
|
this.setPageData({
|
||||||
|
toDt: Utility.setAftertDate(
|
||||||
|
this.$store.state.pageData[this.parentPrgmId][this.widgetPage][
|
||||||
|
this.widgetPage + 'Data'
|
||||||
|
],
|
||||||
|
compareDt,
|
||||||
|
this.myOptions.sendFormat,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.datepicker-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.v-input {
|
||||||
|
.v-input__append-outer {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
|
||||||
|
#startpicker-container,
|
||||||
|
#endpicker-container {
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 36px;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-input__custom {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
&.half {
|
||||||
|
width: calc(50% - 20px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::v-deep {
|
||||||
|
.tui-timepicker-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
background-color: #edf4fc;
|
||||||
|
.tui-timepicker-column.tui-timepicker-colon {
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
711
components/common/Grid.vue
Normal file
@ -0,0 +1,711 @@
|
|||||||
|
<template>
|
||||||
|
<tui-grid
|
||||||
|
:ref="['tuigrid' + gridName]"
|
||||||
|
:data="chkGridData"
|
||||||
|
:columns="chkGridColumns"
|
||||||
|
:options="chkGridOptions"
|
||||||
|
@focusChange="focusChangeEvt"
|
||||||
|
@click="startEditing"
|
||||||
|
@editingFinish="editingFinish"
|
||||||
|
@dblclick="dblClick"
|
||||||
|
@mouseover="mouseoverEvent"
|
||||||
|
@mouseout="mouseoutEvent"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations } from 'vuex';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
gridName: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
dataPath: {
|
||||||
|
type: Object,
|
||||||
|
require: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
editorGrid: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
require: false,
|
||||||
|
},
|
||||||
|
innerTabGridInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
selectedRowDataWatchFlag: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
preventFocusChangeEventFlag: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
// gridInstance Array
|
||||||
|
preventFocusChangeEventTargetGridList: {
|
||||||
|
type: Array,
|
||||||
|
require: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
columnClickEventFlag: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
mouseoverEvent: {
|
||||||
|
type: Function,
|
||||||
|
default() {
|
||||||
|
return 'Default Function';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mouseoutEvent: {
|
||||||
|
type: Function,
|
||||||
|
default() {
|
||||||
|
return 'Default Function';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
gridInstance: null,
|
||||||
|
gridHeight: null,
|
||||||
|
selecrRowKey: null,
|
||||||
|
originData: [],
|
||||||
|
editorStartKey: null,
|
||||||
|
editorEndKey: null,
|
||||||
|
scrollBody: null,
|
||||||
|
gridScrollTop: 0,
|
||||||
|
gridScrollLeft: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
pageData: state => state.pageData,
|
||||||
|
gridData(state) {
|
||||||
|
return this.dataPath
|
||||||
|
? this.dataPath[this.gridName]
|
||||||
|
: state.pageData[this.parentPrgmId][this.gridName];
|
||||||
|
},
|
||||||
|
drawer: state => state.drawer,
|
||||||
|
activePrgmId(state) {
|
||||||
|
return state.activeMenuInfo.prgmId;
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
chkGridData() {
|
||||||
|
// return this.pageData[this.parentPrgmId][this.gridName].data;
|
||||||
|
return this.gridData.data;
|
||||||
|
},
|
||||||
|
chkGridColumns() {
|
||||||
|
return this.gridData.column;
|
||||||
|
},
|
||||||
|
chkGridOptions() {
|
||||||
|
const options = {
|
||||||
|
...this.gridData.option,
|
||||||
|
};
|
||||||
|
options.treeColumnOptions = {
|
||||||
|
useIcon: false,
|
||||||
|
...options.treeColumnOptions,
|
||||||
|
};
|
||||||
|
|
||||||
|
return options;
|
||||||
|
},
|
||||||
|
defaultRow() {
|
||||||
|
return this.gridData.defaultRow;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
chkGridData(val) {
|
||||||
|
this.$refs['tuigrid' + this.gridName].invoke('resetData', val);
|
||||||
|
},
|
||||||
|
innerTabGridInfo(val) {
|
||||||
|
const _this = this;
|
||||||
|
setTimeout(() => {
|
||||||
|
_this.refreshLayout();
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
activePrgmId(val) {
|
||||||
|
const _this = this;
|
||||||
|
setTimeout(() => {
|
||||||
|
_this.refreshLayout();
|
||||||
|
}, 700);
|
||||||
|
if (val == this.parentPrgmId) {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!_this.innerTabGridInfo) {
|
||||||
|
//_this.refreshLayout();
|
||||||
|
_this.scrollBody.scrollTop = _this.gridScrollTop;
|
||||||
|
_this.scrollBody.scrollLeft = _this.gridScrollLeft;
|
||||||
|
} else {
|
||||||
|
if (_this.innerTabGridInfo.tab == _this.innerTabGridInfo.idx) {
|
||||||
|
//_this.refreshLayout();
|
||||||
|
_this.scrollBody.scrollTop = _this.gridScrollTop;
|
||||||
|
_this.scrollBody.scrollLeft = _this.gridScrollLeft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
drawer() {
|
||||||
|
const _this = this;
|
||||||
|
setTimeout(() => {
|
||||||
|
_this.refreshLayout();
|
||||||
|
}, 500);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {},
|
||||||
|
async mounted() {
|
||||||
|
// console.log(this.dataPath);
|
||||||
|
if (this.gridName) {
|
||||||
|
this.gridInstance = this.$refs['tuigrid' + this.gridName];
|
||||||
|
|
||||||
|
this.scrollBody = document
|
||||||
|
.getElementsByClassName('tui-grid-rside-area')
|
||||||
|
[
|
||||||
|
document.getElementsByClassName('tui-grid-rside-area').length - 1
|
||||||
|
].getElementsByClassName('tui-grid-body-area')[0];
|
||||||
|
|
||||||
|
this.scrollBody.addEventListener('scroll', e => {
|
||||||
|
this.gridScrollTop = e.target.scrollTop;
|
||||||
|
this.gridScrollLeft = e.target.scrollLeft;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({
|
||||||
|
setPageData: 'setPageData',
|
||||||
|
setGridData: 'setGridData',
|
||||||
|
}),
|
||||||
|
// true : 현재 행 혹은 연결된 그리드가 수정중인 상태
|
||||||
|
checkGridState() {
|
||||||
|
var rowStatList = ['I', 'U', 'D'];
|
||||||
|
var row = this.gridInstance.invoke('getFocusedCell');
|
||||||
|
|
||||||
|
if (row) {
|
||||||
|
var rowData = this.gridInstance.invoke('getRow', row.rowKey);
|
||||||
|
if (rowData) {
|
||||||
|
var rowStat = rowData['rowStat'];
|
||||||
|
if (rowStatList.includes(rowStat)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.preventFocusChangeEventTargetGridList) {
|
||||||
|
for (var gridInstance of this.preventFocusChangeEventTargetGridList) {
|
||||||
|
var dataArr = gridInstance.save();
|
||||||
|
|
||||||
|
if (dataArr.length > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
preventFocusChangeEvent(e) {
|
||||||
|
var result = false;
|
||||||
|
|
||||||
|
if (this.preventFocusChangeEventFlag) {
|
||||||
|
if (this.checkGridState()) {
|
||||||
|
e.stop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
columnClickEvent(e) {
|
||||||
|
var result = false;
|
||||||
|
|
||||||
|
if (this.columnClickEventFlag) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
getCheckedRowsEvt() {
|
||||||
|
const checkedRowDataList = this.gridInstance.invoke('getCheckedRows');
|
||||||
|
return checkedRowDataList;
|
||||||
|
},
|
||||||
|
dblClick(nativeEvent) {
|
||||||
|
if (this.preventFocusChangeEvent(nativeEvent)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$emit(
|
||||||
|
'dblClick',
|
||||||
|
this.gridInstance.invoke('dblclick'),
|
||||||
|
nativeEvent,
|
||||||
|
this.gridName,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
uncheckEvt(rowData, instance) {
|
||||||
|
this.gridInstance.invoke('uncheck', rowData.rowKey, instance);
|
||||||
|
},
|
||||||
|
checkEvt(rowData, instance) {
|
||||||
|
this.gridInstance.invoke('check', rowData.rowKey, instance);
|
||||||
|
},
|
||||||
|
setSelectionRange(rowKey) {
|
||||||
|
const rowDatas = this.gridInstance.invoke('getData');
|
||||||
|
rowDatas.forEach(item => {
|
||||||
|
if (item.rowKey == rowKey) {
|
||||||
|
this.gridInstance.invoke(
|
||||||
|
'addRowClassName',
|
||||||
|
item.rowKey,
|
||||||
|
'row-selected',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.gridInstance.invoke(
|
||||||
|
'removeRowClassName',
|
||||||
|
item.rowKey,
|
||||||
|
'row-selected',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
focusChangeEvt(e) {
|
||||||
|
// console.log('focusChangeEvt1...')
|
||||||
|
if (this.preventFocusChangeEvent(e)) {
|
||||||
|
// console.log('prevent focusChangeEvt')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// console.log('focusChangeEvt2...')
|
||||||
|
// cell 선택시 row 선택 method
|
||||||
|
if (e.rowKey >= 0) {
|
||||||
|
this.$emit(
|
||||||
|
'getRowsData',
|
||||||
|
this.gridInstance.invoke('getRow', e.rowKey),
|
||||||
|
this.gridName,
|
||||||
|
e.columnName,
|
||||||
|
);
|
||||||
|
this.selecrRowKey = e.rowKey;
|
||||||
|
this.setSelectionRange(e.rowKey);
|
||||||
|
}
|
||||||
|
this.sendSelectedRowData(e.rowKey);
|
||||||
|
},
|
||||||
|
startEditing(e) {
|
||||||
|
// console.log('startEditing1...')
|
||||||
|
if (this.preventFocusChangeEvent(e)) {
|
||||||
|
// console.log('prevent startEditing')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.columnClickEvent(e)) {
|
||||||
|
this.$emit('columnClick', e, this.gridName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('startEditing2...')
|
||||||
|
if (this.editorGrid && e.rowKey >= 0) {
|
||||||
|
this.editorStartKey = e.rowKey;
|
||||||
|
// console.log("E::", this.gridInstance.invoke("getRow", e.rowKey));
|
||||||
|
this.gridInstance.invoke('startEditing', e.rowKey, e.columnName);
|
||||||
|
this.$emit(
|
||||||
|
'getRowsData',
|
||||||
|
this.gridInstance.invoke('getRow', e.rowKey),
|
||||||
|
this.gridName,
|
||||||
|
e.columnName,
|
||||||
|
);
|
||||||
|
this.setSelectionRange(e.rowKey);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async editingFinish(e) {
|
||||||
|
// console.log("Editing END E::", e);
|
||||||
|
// editor 간 이동시 수정되는 문제 수정
|
||||||
|
// e.rowEditingFg: grid의 한 row를 한번에 수정할 시 각각의 cell 마다 click 이벤트가 발생하지 않아 this.editorStartKey값이 제대로 입력 되지 않는 경우를 대비하여 만든 Fg
|
||||||
|
if (this.editorGrid) {
|
||||||
|
this.editorEndKey = Number.isInteger(e.rowKey) ? e.rowKey : null;
|
||||||
|
if (e.rowEditingFg == undefined && this.editorStartKey >= 0) {
|
||||||
|
if (this.editorStartKey != this.editorEndKey) {
|
||||||
|
this.editorStartKey = null;
|
||||||
|
this.editorEndKey = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const rowIdxKey = this.editorGrid ? this.editorEndKey : this.gridInstance.invoke('getFocusedCell').rowKey
|
||||||
|
// editor 간 이동시 수정되는 문제 수정 끝
|
||||||
|
|
||||||
|
const columnName = e.columnName;
|
||||||
|
const value = e.value;
|
||||||
|
const editingData = {
|
||||||
|
...e,
|
||||||
|
rowKey: rowIdxKey,
|
||||||
|
};
|
||||||
|
const isBaseRow = this.isBaseDataRow(rowIdxKey);
|
||||||
|
// console.log("END E::", rowIdxKey, e);
|
||||||
|
const rowStat = this.gridInstance.invoke('getRow', rowIdxKey).rowStat;
|
||||||
|
if (rowStat == 'D') {
|
||||||
|
this.gridInstance.invoke(
|
||||||
|
'removeRowClassName',
|
||||||
|
rowIdxKey,
|
||||||
|
'row-removed',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.gridInstance.invoke(
|
||||||
|
e.rowEditingFg != undefined ? 'setValue' : this.editorGrid ? 'finishEditing' : 'setValue',
|
||||||
|
rowIdxKey,
|
||||||
|
columnName,
|
||||||
|
value,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (isBaseRow) {
|
||||||
|
const isSameData = await this.compareData(editingData);
|
||||||
|
if (isSameData) {
|
||||||
|
this.gridInstance.invoke(
|
||||||
|
'removeRowClassName',
|
||||||
|
rowIdxKey,
|
||||||
|
'row-modify',
|
||||||
|
);
|
||||||
|
this.updateData('clear', rowIdxKey);
|
||||||
|
} else {
|
||||||
|
this.gridInstance.invoke('addRowClassName', rowIdxKey, 'row-modify');
|
||||||
|
this.updateData('modify', rowIdxKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
e.ignoreUpdateDataInfoFlag === undefined ||
|
||||||
|
e.ignoreUpdateDataInfoFlag === false
|
||||||
|
) {
|
||||||
|
this.$emit('updateDataInfo', {
|
||||||
|
rowIdxKey: rowIdxKey,
|
||||||
|
rowStat: rowStat,
|
||||||
|
columnName: columnName,
|
||||||
|
value: value,
|
||||||
|
rowData: this.gridInstance.invoke('getRow', rowIdxKey),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.sendSelectedRowData();
|
||||||
|
},
|
||||||
|
async addRow(setData, argRowKey) {
|
||||||
|
// 그리드가 수정중인 상태면 addRow를 하지 않음
|
||||||
|
if (this.preventFocusChangeEventFlag) {
|
||||||
|
if (this.checkGridState()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const addData = !setData
|
||||||
|
? this.defaultRow
|
||||||
|
: Object.assign(this.defaultRow, setData);
|
||||||
|
// 열 앞에 데이터 추가
|
||||||
|
// if (argRowKey != undefined && argRowKey != null) {
|
||||||
|
this.gridInstance.invoke('appendRow', addData, {
|
||||||
|
focus: true,
|
||||||
|
});
|
||||||
|
// } else {
|
||||||
|
// this.gridInstance.invoke('prependRow', addData, {
|
||||||
|
// focus: true,
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// this.gridInstance.invoke('prependRow', addData, {
|
||||||
|
// focus: true,
|
||||||
|
// });
|
||||||
|
this.$nextTick(() => {
|
||||||
|
var addRowKey = this.gridInstance.invoke('getFocusedCell').rowKey;
|
||||||
|
if (argRowKey) {
|
||||||
|
addRowKey = argRowKey;
|
||||||
|
}
|
||||||
|
this.gridInstance.invoke(
|
||||||
|
'removeRowClassName',
|
||||||
|
addRowKey,
|
||||||
|
'row-removed',
|
||||||
|
);
|
||||||
|
this.gridInstance.invoke('addRowClassName', addRowKey, 'row-insert');
|
||||||
|
this.updateData('insert', addRowKey);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async appendRow() {
|
||||||
|
this.gridInstance.invoke('appendRow', {
|
||||||
|
focus: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async addTreeRow(setData) {
|
||||||
|
// tree append의 경우 무한루프가 발행하는 버그현상으로 appendRows로 추가
|
||||||
|
const addData = !setData
|
||||||
|
? this.defaultRow
|
||||||
|
: Object.assign(this.defaultRow, setData);
|
||||||
|
|
||||||
|
this.gridInstance.invoke('appendRows', [addData]);
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const rowDatas = this.gridInstance.invoke('getData');
|
||||||
|
const addRowKey = rowDatas[rowDatas.length - 1].rowKey;
|
||||||
|
this.gridInstance.invoke(
|
||||||
|
'removeRowClassName',
|
||||||
|
addRowKey,
|
||||||
|
'row-removed',
|
||||||
|
);
|
||||||
|
this.gridInstance.invoke('addRowClassName', addRowKey, 'row-insert');
|
||||||
|
this.updateData('insert', addRowKey);
|
||||||
|
this.gridInstance.invoke('focus', addRowKey);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async removeRow(delType, argRowKey) {
|
||||||
|
var rowIdxKey = this.gridInstance.invoke('getFocusedCell').rowKey;
|
||||||
|
if (typeof argRowKey == 'number') {
|
||||||
|
rowIdxKey = argRowKey;
|
||||||
|
}
|
||||||
|
const rowStat = this.gridInstance.invoke('getRow', rowIdxKey).rowStat;
|
||||||
|
if (rowStat === 'D') {
|
||||||
|
this.gridInstance.invoke(
|
||||||
|
'removeRowClassName',
|
||||||
|
rowIdxKey,
|
||||||
|
'row-removed',
|
||||||
|
);
|
||||||
|
this.updateData('clear', rowIdxKey);
|
||||||
|
} else {
|
||||||
|
if (!this.isBaseDataRow(rowIdxKey)) {
|
||||||
|
this.gridInstance.invoke('removeRow', rowIdxKey);
|
||||||
|
let nextFocus = Number(rowIdxKey) - 1;
|
||||||
|
if (!this.isBaseDataRow(nextFocus)) nextFocus = 0;
|
||||||
|
this.gridInstance.invoke('focus', nextFocus);
|
||||||
|
} else {
|
||||||
|
this.gridInstance.invoke('addRowClassName', rowIdxKey, 'row-removed');
|
||||||
|
this.updateData('delete', rowIdxKey);
|
||||||
|
|
||||||
|
if (delType == 'immediately')
|
||||||
|
this.gridInstance.invoke('removeRow', rowIdxKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async removeTreeRow(delType) {
|
||||||
|
const rowIdxKey = this.gridInstance.invoke('getFocusedCell').rowKey;
|
||||||
|
const rowStat = this.gridInstance.invoke('getRow', rowIdxKey).rowStat;
|
||||||
|
if (rowStat === 'D') {
|
||||||
|
this.gridInstance.invoke(
|
||||||
|
'removeRowClassName',
|
||||||
|
rowIdxKey,
|
||||||
|
'row-removed',
|
||||||
|
);
|
||||||
|
this.updateData('clear', rowIdxKey);
|
||||||
|
} else {
|
||||||
|
if (!this.isBaseDataRow(rowIdxKey)) {
|
||||||
|
this.updateData('clear', rowIdxKey);
|
||||||
|
this.gridInstance.invoke('removeRow', rowIdxKey);
|
||||||
|
let nextFocus = Number(rowIdxKey) - 1;
|
||||||
|
if (!this.isBaseDataRow(nextFocus)) nextFocus = 0;
|
||||||
|
this.gridInstance.invoke('focus', nextFocus);
|
||||||
|
} else {
|
||||||
|
this.gridInstance.invoke('addRowClassName', rowIdxKey, 'row-removed');
|
||||||
|
this.updateData('delete', rowIdxKey);
|
||||||
|
|
||||||
|
if (delType == 'immediately')
|
||||||
|
this.gridInstance.invoke('removeRow', rowIdxKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isBaseDataRow(rowKey) {
|
||||||
|
// 기존데이터 여부 확인 (추가된 데이터 X)
|
||||||
|
const findRow = this.gridInstance.invoke('findRows', { rowKey: rowKey });
|
||||||
|
return findRow && findRow[0] && findRow[0].rowStat != 'I' ? true : false;
|
||||||
|
},
|
||||||
|
compareData(data) {
|
||||||
|
// rowStat key값 제거
|
||||||
|
const dataKeyArr = Object.keys(this.defaultRow);
|
||||||
|
const rowStatIdx = dataKeyArr.indexOf('rowStat');
|
||||||
|
dataKeyArr.splice(rowStatIdx, 1);
|
||||||
|
// rowStat key값 제거 끝
|
||||||
|
|
||||||
|
const selectedRowData = this.gridInstance.invoke('getRow', data.rowKey);
|
||||||
|
this.getOriginData();
|
||||||
|
|
||||||
|
const rowData = this.originData.find(item => {
|
||||||
|
return item.rowKey == data.rowKey;
|
||||||
|
});
|
||||||
|
let count = 0;
|
||||||
|
// console.log("dataKeyArr", dataKeyArr);
|
||||||
|
// console.log("selectedRowData", selectedRowData);
|
||||||
|
for (let i = 0; i < dataKeyArr.length; i++) {
|
||||||
|
// console.log(dataKeyArr[i], selectedRowData[dataKeyArr[i]], rowData[dataKeyArr[i]]);
|
||||||
|
if (selectedRowData[dataKeyArr[i]] == rowData[dataKeyArr[i]]) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dataKeyArr.length == count ? true : false;
|
||||||
|
},
|
||||||
|
getOriginData() {
|
||||||
|
this.chkGridData.forEach(item => {
|
||||||
|
this.originData.push(item);
|
||||||
|
if (item._children) {
|
||||||
|
this.getChildrenData(item._children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getChildrenData(children) {
|
||||||
|
children.forEach(item => {
|
||||||
|
this.originData.push(item);
|
||||||
|
if (item._children) {
|
||||||
|
this.getChildrenData(item._children);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateData(updateType, rowIdxKey) {
|
||||||
|
let type = '';
|
||||||
|
switch (updateType) {
|
||||||
|
case 'insert':
|
||||||
|
type = 'I';
|
||||||
|
break;
|
||||||
|
case 'modify':
|
||||||
|
type = 'U';
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
type = 'D';
|
||||||
|
break;
|
||||||
|
case 'clear':
|
||||||
|
type = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.gridInstance.invoke('setValue', rowIdxKey, 'rowStat', type);
|
||||||
|
},
|
||||||
|
// 지정 로우 선택상태
|
||||||
|
focus(rowInfo) {
|
||||||
|
this.gridInstance.invoke(
|
||||||
|
'focus',
|
||||||
|
rowInfo.rowKey,
|
||||||
|
rowInfo.columnName,
|
||||||
|
rowInfo.setScroll,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// 트리 전체 접기
|
||||||
|
expandAll() {
|
||||||
|
this.gridInstance.invoke('expandAll');
|
||||||
|
},
|
||||||
|
// 트리 전체 펼치기
|
||||||
|
collapseAll() {
|
||||||
|
this.gridInstance.invoke('collapseAll');
|
||||||
|
},
|
||||||
|
save() {
|
||||||
|
const saveTargetRows = this.gridInstance.invoke('getModifiedRows');
|
||||||
|
// createdRows | deletedRows | updatedRows
|
||||||
|
const createdRows = saveTargetRows.createdRows;
|
||||||
|
const deletedRows = saveTargetRows.deletedRows;
|
||||||
|
const updatedRows = saveTargetRows.updatedRows;
|
||||||
|
const dataArr = [...createdRows, ...deletedRows, ...updatedRows]
|
||||||
|
.filter(item => item.rowStat)
|
||||||
|
.map(item => {
|
||||||
|
delete item.rowKey;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
// console.log("dataArr::", dataArr, saveTargetRows);
|
||||||
|
return dataArr;
|
||||||
|
},
|
||||||
|
getData() {
|
||||||
|
return this.gridInstance.invoke('getData');
|
||||||
|
},
|
||||||
|
getCheckedRows() {
|
||||||
|
return this.gridInstance.invoke('getCheckedRows');
|
||||||
|
},
|
||||||
|
getCheckedRowKeys() {
|
||||||
|
return this.gridInstance.invoke('getCheckedRowKeys');
|
||||||
|
},
|
||||||
|
setCheck(list) {
|
||||||
|
// console.log("setCheck:: ", list);
|
||||||
|
list.map(item => this.gridInstance.invoke('check', item));
|
||||||
|
},
|
||||||
|
refreshLayout() {
|
||||||
|
this.gridInstance.invoke('refreshLayout');
|
||||||
|
},
|
||||||
|
refreshGrid(){
|
||||||
|
// console.log("refreshLayout",this.$refs['tuigrid' + this.gridName])
|
||||||
|
var store = this.$refs['tuigrid' + this.gridName].gridInstance.store;
|
||||||
|
var containerEl = this.$refs['tuigrid' + this.gridName].$el;
|
||||||
|
// var containerEl = document.querySelector('.tui-grid-container')
|
||||||
|
var parentEl = containerEl.parentElement;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// console.log("containerEl : ",containerEl);
|
||||||
|
// console.log('parentEl : ', parentEl)
|
||||||
|
// function refreshLayout(store, containerEl, parentEl) {
|
||||||
|
var dimension = store.dimension;
|
||||||
|
var autoWidth = dimension.autoWidth, fitToParentHeight = dimension.fitToParentHeight;
|
||||||
|
var clientHeight = containerEl.clientHeight, clientWidth = containerEl.clientWidth, scrollTop = containerEl.scrollTop, scrollLeft = containerEl.scrollLeft;
|
||||||
|
var _a = containerEl.getBoundingClientRect(), top = _a.top, left = _a.left;
|
||||||
|
this.setOffsetTop(store, top + scrollTop);
|
||||||
|
// store.dimension.setOffsetTop = top + scrollTop;
|
||||||
|
this.setOffsetLeft(store, left + scrollLeft);
|
||||||
|
// store.dimension.headerHeight = left + scrollLeft;
|
||||||
|
this.setWidth(store, clientWidth, autoWidth);
|
||||||
|
// store.dimension.autoWidth = autoWidth;
|
||||||
|
// store.dimension.width = clientWidth;
|
||||||
|
// console.log("###",getComputedStyle(parentEl));
|
||||||
|
// console.log("fitToParentHeight : ",fitToParentHeight);
|
||||||
|
// console.log("parentEl : ",parentEl)
|
||||||
|
// console.log("parentEl.clientHeight" , parentEl.clientHeight)
|
||||||
|
// console.log("clientHeight : ",clientHeight);
|
||||||
|
if (parentEl && parentEl.clientHeight !== clientHeight) {
|
||||||
|
var _b = getComputedStyle(parentEl), paddingTop = _b.paddingTop, paddingBottom = _b.paddingBottom;
|
||||||
|
this.setHeight(store, parentEl.clientHeight - (parseFloat(paddingTop) + parseFloat(paddingBottom)));
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
setOffsetTop(store, offsetTop) {
|
||||||
|
// console.log("setOffsetTop");
|
||||||
|
store.dimension.offsetTop = offsetTop;
|
||||||
|
},
|
||||||
|
setWidth(_a, width, autoWidth) {
|
||||||
|
// console.log("setWidth");
|
||||||
|
var dimension = _a.dimension;
|
||||||
|
dimension.autoWidth = autoWidth;
|
||||||
|
dimension.width = width;
|
||||||
|
},
|
||||||
|
setHeaderHeight(store, height) {
|
||||||
|
// console.log("setHeaderHeight")
|
||||||
|
store.dimension.headerHeight = height;
|
||||||
|
},
|
||||||
|
setOffsetLeft(store, offsetLeft) {
|
||||||
|
// console.log("setOffsetLeft")
|
||||||
|
store.dimension.offsetLeft = offsetLeft;
|
||||||
|
},
|
||||||
|
setHeight(_a,height){
|
||||||
|
// console.log("setHeight");
|
||||||
|
var dimension = _a.dimension;
|
||||||
|
var headerHeight = dimension.headerHeight, summaryHeight = dimension.summaryHeight, tableBorderWidth = dimension.tableBorderWidth;
|
||||||
|
dimension.bodyHeight = height - headerHeight - summaryHeight - tableBorderWidth;
|
||||||
|
},
|
||||||
|
sendSelectedRowData(eventRowKey) {
|
||||||
|
if (this.selectedRowDataWatchFlag) {
|
||||||
|
var rowKey =
|
||||||
|
eventRowKey === undefined
|
||||||
|
? this.gridInstance.invoke('getFocusedCell').rowKey
|
||||||
|
: eventRowKey;
|
||||||
|
var rowData = this.gridInstance.invoke('getRow', rowKey);
|
||||||
|
this.$emit('sendSelectedRowStatInfo', rowData);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
disableRow(rowKey, withCheckBox = false) {
|
||||||
|
this.gridInstance.invoke('disableRow', rowKey, withCheckBox);
|
||||||
|
},
|
||||||
|
async disabledRow(addRowKey) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.gridInstance.invoke(
|
||||||
|
'removeRowClassName',
|
||||||
|
addRowKey,
|
||||||
|
'row-removed',
|
||||||
|
);
|
||||||
|
this.gridInstance.invoke('addRowClassName', addRowKey, 'row-disabled');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// resetData() {
|
||||||
|
// // console.log("resetData = ", this.tuigridProps.data);
|
||||||
|
// this.$refs.tuigrid.invoke("resetData", this.tuigridProps.data);
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
::v-deep .tui-grid-container {
|
||||||
|
.tui-grid-content-area {
|
||||||
|
.tui-grid-cell-content {
|
||||||
|
input[type='number'] {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
245
components/common/Grid2.vue
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
<template>
|
||||||
|
<tui-grid
|
||||||
|
:ref="['tuigrid' + gridName]"
|
||||||
|
:data="chkGridData"
|
||||||
|
:columns="chkGridColumns"
|
||||||
|
:options="chkGridOptions"
|
||||||
|
@focusChange="focusChangeEvt"
|
||||||
|
@click="startEditing"
|
||||||
|
@editingFinish="editingFinish"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations, mapActions } from 'vuex';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
gridName: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
dataPath: {
|
||||||
|
type: Object,
|
||||||
|
require: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
editorGrid: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
require: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
gridInstance: null,
|
||||||
|
gridHeight: null,
|
||||||
|
selecrRowKey: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
// pageData: state => state.pageData
|
||||||
|
pageData(state) {
|
||||||
|
return this.dataPath
|
||||||
|
? this.dataPath[this.gridName]
|
||||||
|
: state.pageData[this.parentPrgmId][this.gridName];
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
chkGridData() {
|
||||||
|
return this.pageData.data;
|
||||||
|
},
|
||||||
|
chkGridColumns() {
|
||||||
|
return this.pageData.column;
|
||||||
|
},
|
||||||
|
chkGridOptions() {
|
||||||
|
return this.pageData.option;
|
||||||
|
},
|
||||||
|
defaultRow() {
|
||||||
|
return this.pageData.defaultRow;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
chkGridData(val) {
|
||||||
|
this.$refs['tuigrid' + this.gridName].invoke('resetData', val);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {},
|
||||||
|
async mounted() {
|
||||||
|
// console.log(this.dataPath);
|
||||||
|
if (this.gridName) {
|
||||||
|
this.gridInstance = this.$refs['tuigrid' + this.gridName];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({
|
||||||
|
setPageData: 'setPageData',
|
||||||
|
setGridData: 'setGridData',
|
||||||
|
}),
|
||||||
|
getCheckedRowsEvt() {
|
||||||
|
const checkedRowDataList = this.gridInstance.invoke('getCheckedRows');
|
||||||
|
return checkedRowDataList;
|
||||||
|
},
|
||||||
|
uncheckEvt(rowData, instance) {
|
||||||
|
this.gridInstance.invoke('uncheck', rowData.rowKey, instance);
|
||||||
|
},
|
||||||
|
checkEvt(rowData, instance) {
|
||||||
|
this.gridInstance.invoke('check', rowData.rowKey, instance);
|
||||||
|
},
|
||||||
|
focusChangeEvt(e) {
|
||||||
|
// cell 선택시 row 선택 method
|
||||||
|
if (!this.editorGrid) {
|
||||||
|
this.$emit('getRowsData', this.gridInstance.invoke('getRow', e.rowKey));
|
||||||
|
this.selecrRowKey = e.rowKey;
|
||||||
|
const rowIndxKey = this.gridInstance.invoke('getIndexOfRow', e.rowKey);
|
||||||
|
this.gridInstance.invoke('setSelectionRange', {
|
||||||
|
start: [rowIndxKey, 0],
|
||||||
|
end: [rowIndxKey, this.gridInstance.columns.length],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
startEditing(e) {
|
||||||
|
if (this.editorGrid) {
|
||||||
|
this.gridInstance.invoke('startEditing', e.rowKey, e.columnName);
|
||||||
|
const rowIndxKey = this.gridInstance.invoke('getIndexOfRow', e.rowKey);
|
||||||
|
this.gridInstance.invoke('setSelectionRange', {
|
||||||
|
start: [rowIndxKey, 0],
|
||||||
|
end: [rowIndxKey, this.gridInstance.columns.length],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
editingFinish(e) {
|
||||||
|
// console.log("editingFinish::e", e);
|
||||||
|
const rowIdxKey = e.rowKey;
|
||||||
|
const columnName = e.columnName;
|
||||||
|
const value = e.value;
|
||||||
|
const isAddRow = this.isBaseDataRow(rowIdxKey);
|
||||||
|
|
||||||
|
this.gridInstance.invoke('setValue', rowIdxKey, columnName, value);
|
||||||
|
if (isAddRow != -1) {
|
||||||
|
const isSameData = this.compareData(e);
|
||||||
|
if (!isSameData) {
|
||||||
|
this.gridInstance.invoke('addRowClassName', rowIdxKey, 'row-modify');
|
||||||
|
this.updateData('modify', rowIdxKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async addRow() {
|
||||||
|
// 열 앞에 데이터 추가
|
||||||
|
this.gridInstance.invoke('prependRow', this.defaultRow, {
|
||||||
|
focus: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// const aa = this.gridInstance.invoke("getModifiedRows");
|
||||||
|
// console.log("this.gridInstance", this.gridInstance, aa);
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const addRowKey = this.gridInstance.invoke('getFocusedCell').rowKey;
|
||||||
|
// console.log("addRowKey :: ", addRowKey);
|
||||||
|
this.gridInstance.invoke('addRowClassName', addRowKey, 'row-insert');
|
||||||
|
this.updateData('insert', addRowKey);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
removeRow() {
|
||||||
|
const rowIdxKey = this.gridInstance.invoke('getFocusedCell').rowKey;
|
||||||
|
this.gridInstance.invoke('addRowClassName', rowIdxKey, 'row-removed');
|
||||||
|
this.gridInstance.invoke('disableRow', rowIdxKey);
|
||||||
|
|
||||||
|
this.updateData('delete', rowIdxKey);
|
||||||
|
},
|
||||||
|
externalDataEdit(obj) {
|
||||||
|
const rowIdxKey = this.gridInstance.invoke('getFocusedCell').rowKey;
|
||||||
|
const columnName = obj.name;
|
||||||
|
const value = obj.value;
|
||||||
|
const isAddRow = this.isBaseDataRow(rowIdxKey);
|
||||||
|
|
||||||
|
this.gridInstance.invoke('setValue', rowIdxKey, columnName, value);
|
||||||
|
if (isAddRow != -1) {
|
||||||
|
this.gridInstance.invoke('addRowClassName', rowIdxKey, 'row-modify');
|
||||||
|
this.updateData('modify', rowIdxKey);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isBaseDataRow(rowKey) {
|
||||||
|
// 기존데이터 여부 확인 (추가된 데이터 X)
|
||||||
|
return this.chkGridData.map(item => item.rowKey).indexOf(rowKey);
|
||||||
|
},
|
||||||
|
compareData(data) {
|
||||||
|
const rowData = this.chkGridData.filter(item => {
|
||||||
|
return item.rowKey == data.rowKey;
|
||||||
|
})[0];
|
||||||
|
// console.log(rowData);
|
||||||
|
return rowData[data.columnName] == data.value;
|
||||||
|
},
|
||||||
|
updateData(updateType, rowIdxKey) {
|
||||||
|
let type = '';
|
||||||
|
switch (updateType) {
|
||||||
|
case 'insert':
|
||||||
|
type = 'I';
|
||||||
|
break;
|
||||||
|
case 'modify':
|
||||||
|
type = 'U';
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
type = 'D';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.gridInstance.invoke('setValue', rowIdxKey, 'rowStat', type);
|
||||||
|
},
|
||||||
|
// 지정 로우 선택상태
|
||||||
|
focus(rowInfo) {
|
||||||
|
this.gridInstance.invoke(
|
||||||
|
'focus',
|
||||||
|
rowInfo.rowKey,
|
||||||
|
rowInfo.columnName,
|
||||||
|
rowInfo.setScroll,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
// 트리 전체 접기
|
||||||
|
expandAll() {
|
||||||
|
this.gridInstance.invoke('expandAll');
|
||||||
|
},
|
||||||
|
// 트리 전체 펼치기
|
||||||
|
collapseAll() {
|
||||||
|
this.gridInstance.invoke('collapseAll');
|
||||||
|
},
|
||||||
|
save() {
|
||||||
|
const saveTargetRows = this.gridInstance.invoke('getModifiedRows');
|
||||||
|
// createdRows | deletedRows | updatedRows
|
||||||
|
const createdRows = saveTargetRows.createdRows.map(item => {
|
||||||
|
delete item.rowKey;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
const deletedRows = saveTargetRows.deletedRows.map(item => {
|
||||||
|
delete item.rowKey;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
const updatedRows = saveTargetRows.updatedRows.map(item => {
|
||||||
|
delete item.rowKey;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
const dataArr = createdRows.concat(deletedRows).concat(updatedRows);
|
||||||
|
return dataArr;
|
||||||
|
// this.$emit("saveGrid", saveTargetRows);
|
||||||
|
},
|
||||||
|
// resetData() {
|
||||||
|
// // console.log("resetData = ", this.tuigridProps.data);
|
||||||
|
// this.$refs.tuigrid.invoke("resetData", this.tuigridProps.data);
|
||||||
|
// }
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
::v-deep .tui-grid-cell {
|
||||||
|
&.row-insert {
|
||||||
|
background-color: #13636c !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
&.row-modify {
|
||||||
|
background-color: #13636c;
|
||||||
|
}
|
||||||
|
&.row-removed {
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
354
components/common/PastRsltDatePicker.vue
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
<template>
|
||||||
|
<v-row class="search-box" align="center" no-gutters>
|
||||||
|
<v-col v-if="label" :cols="labelCols">
|
||||||
|
<label for="" class="search-box-label">
|
||||||
|
<v-icon x-small color="primary" class="mr-1">mdi-record-circle</v-icon>
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
</v-col>
|
||||||
|
<v-col :cols="label ? textCols : ''">
|
||||||
|
<div class="datepicker-container">
|
||||||
|
<v-text-field
|
||||||
|
id="startpicker"
|
||||||
|
ref="startpicker"
|
||||||
|
v-model="fromDtValue"
|
||||||
|
:class="isRange ? 'v-input__custom half' : 'v-input__custom'"
|
||||||
|
:hide-details="true"
|
||||||
|
readonly
|
||||||
|
outlined
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<v-icon size="20">$icoCalendar</v-icon>
|
||||||
|
</template>
|
||||||
|
<template #append-outer>
|
||||||
|
<div ref="startpicker-container" id="startpicker-container"></div>
|
||||||
|
</template>
|
||||||
|
</v-text-field>
|
||||||
|
<div v-show="isRange" class="mx-3" :style="{ lineHeight: 0 }">~</div>
|
||||||
|
<v-text-field
|
||||||
|
v-show="isRange"
|
||||||
|
id="endpicker"
|
||||||
|
ref="endpicker"
|
||||||
|
v-model="toDtValue"
|
||||||
|
:class="isRange ? 'v-input__custom half' : 'v-input__custom'"
|
||||||
|
:hide-details="true"
|
||||||
|
readonly
|
||||||
|
outlined
|
||||||
|
>
|
||||||
|
<template #append>
|
||||||
|
<v-icon size="20">$icoCalendar</v-icon>
|
||||||
|
</template>
|
||||||
|
<template #append-outer>
|
||||||
|
<div ref="endpicker-container" id="endpicker-container"></div>
|
||||||
|
</template>
|
||||||
|
</v-text-field>
|
||||||
|
</div>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations } from 'vuex';
|
||||||
|
import TuiDatepicker from 'tui-date-picker';
|
||||||
|
import Utility from '~/plugins/utility';
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
require: false,
|
||||||
|
},
|
||||||
|
timePicker: {
|
||||||
|
type: Boolean,
|
||||||
|
require: false,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
labelCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 4,
|
||||||
|
},
|
||||||
|
textCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
today: new Date(),
|
||||||
|
startDatepickerInstance: null,
|
||||||
|
endDatepickerInstance: null,
|
||||||
|
startDtValue: null,
|
||||||
|
endDtValue: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
searchParam(state) {
|
||||||
|
return state.pageData[this.parentPrgmId];
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
myCmCycle() {
|
||||||
|
return this.searchParam.cmCycle;
|
||||||
|
},
|
||||||
|
myOptions() {
|
||||||
|
let returnObj = {
|
||||||
|
type: 'date',
|
||||||
|
viewFormat: 'YYYY-MM-DD',
|
||||||
|
pickerFormat: 'yyyy-MM-dd',
|
||||||
|
sendFormat: 'YYYYMMDD',
|
||||||
|
};
|
||||||
|
return returnObj;
|
||||||
|
},
|
||||||
|
// maxDate() {
|
||||||
|
// return Utility.setFormatDate("today", this.myOptions.format);
|
||||||
|
// },
|
||||||
|
fromDtValue() {
|
||||||
|
return Utility.setFormatDate(
|
||||||
|
this.searchParam.fromDt,
|
||||||
|
this.myOptions.viewFormat,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
toDtValue() {
|
||||||
|
return Utility.setFormatDate(
|
||||||
|
this.searchParam.toDt,
|
||||||
|
this.myOptions.viewFormat,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
defaultRange() {
|
||||||
|
return this.searchParam.defaultRange
|
||||||
|
? this.searchParam.defaultRange[this.myCmCycle]
|
||||||
|
: null;
|
||||||
|
},
|
||||||
|
isRange() {
|
||||||
|
return (
|
||||||
|
(this.defaultRange !== null && this.defaultRange > 0) ||
|
||||||
|
this.defaultRange === 'no limite'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
myCmCycle() {
|
||||||
|
this.startDatepickerInstance.setDate(new Date(this.fromDtValue));
|
||||||
|
this.startDatepickerInstance.setType(this.myOptions.type);
|
||||||
|
this.endDatepickerInstance.setType(this.myOptions.type);
|
||||||
|
},
|
||||||
|
fromDtValue(newVal, oldVal) {
|
||||||
|
if (
|
||||||
|
this.isRange &&
|
||||||
|
this.defaultRange !== 'no limite' &&
|
||||||
|
newVal !== 'Invalid Date' &&
|
||||||
|
newVal !== oldVal
|
||||||
|
) {
|
||||||
|
this.toDtValueChkRang(newVal);
|
||||||
|
this.startDatepickerInstance.setDate(new Date(newVal));
|
||||||
|
} else {
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toDtValue(newVal, oldVal) {
|
||||||
|
if (
|
||||||
|
this.isRange &&
|
||||||
|
this.defaultRange !== 'no limite' &&
|
||||||
|
newVal !== 'Invalid Date' &&
|
||||||
|
newVal !== oldVal
|
||||||
|
) {
|
||||||
|
this.fromDtValueChkRang(newVal);
|
||||||
|
this.endDatepickerInstance.setDate(new Date(newVal));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if (this.timePicker) {
|
||||||
|
this.setPageData({
|
||||||
|
fromDt: Utility.setFormatDate(this.today, 'YYYY-MM-DD') + ' 00:00:00',
|
||||||
|
toDt: Utility.setFormatDate(this.today, 'YYYY-MM-DD') + ' 23:59:59',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const startContainer = document.getElementById('startpicker-container');
|
||||||
|
const startTarget = document.getElementById('startpicker');
|
||||||
|
const endContainer = document.getElementById('endpicker-container');
|
||||||
|
const endTarget = document.getElementById('endpicker');
|
||||||
|
|
||||||
|
// datepicker 생성
|
||||||
|
this.startDatepickerInstance = new TuiDatepicker(startContainer, {
|
||||||
|
date: this.today,
|
||||||
|
language: 'ko',
|
||||||
|
type: this.myOptions.type, // "date", // type: date || month || year
|
||||||
|
input: {
|
||||||
|
element: startTarget,
|
||||||
|
format: this.myOptions.pickerFormat, //"YYYY-MM-DD" //this.format
|
||||||
|
},
|
||||||
|
timePicker: this.timePicker,
|
||||||
|
calendar: {
|
||||||
|
showToday: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// datepicker 생성
|
||||||
|
this.endDatepickerInstance = new TuiDatepicker(endContainer, {
|
||||||
|
date: this.today,
|
||||||
|
language: 'ko',
|
||||||
|
type: this.myOptions.type, // "date", // type: date || month || year
|
||||||
|
input: {
|
||||||
|
element: endTarget,
|
||||||
|
format: this.myOptions.pickerFormat, //"YYYY-MM-DD" //this.format
|
||||||
|
},
|
||||||
|
timePicker: this.timePicker,
|
||||||
|
calendar: {
|
||||||
|
showToday: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// datepicker 생성 끝
|
||||||
|
|
||||||
|
// datepicker 초기값 생성
|
||||||
|
this.startDatepickerInstance.setDate(new Date(this.fromDtValue));
|
||||||
|
// datepicker 초기값 생성 끝
|
||||||
|
|
||||||
|
// datepicker 변경시 이벤트 추가
|
||||||
|
this.startDatepickerInstance.on('change', () => this.getStartDt());
|
||||||
|
this.endDatepickerInstance.on('change', () => this.getEndDt());
|
||||||
|
// datepicker 이벤트는 mount 될때 추가 해주어야 한다.
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({ setPageData: 'setPageData' }),
|
||||||
|
setDatePicker(type, compareDate, formatDate, formatTime) {
|
||||||
|
let returnDt = null;
|
||||||
|
const dayjs = require('dayjs');
|
||||||
|
|
||||||
|
const compareDt = dayjs(compareDate);
|
||||||
|
const formatType = formatDate + (formatTime ? ' ' + formatTime : '');
|
||||||
|
const defaultRange = this.defaultRange;
|
||||||
|
|
||||||
|
const newDefault = Utility.setNewDefaultRange(
|
||||||
|
this.myCmCycle,
|
||||||
|
defaultRange,
|
||||||
|
);
|
||||||
|
const myRange = newDefault.range;
|
||||||
|
const rangeKey = newDefault.key;
|
||||||
|
|
||||||
|
if (type == 'toDt') {
|
||||||
|
returnDt = compareDt.add(myRange, rangeKey).subtract(1, 'day');
|
||||||
|
} else {
|
||||||
|
returnDt = compareDt.subtract(myRange, rangeKey).add(1, 'day');
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnDt.format(formatType);
|
||||||
|
},
|
||||||
|
getStartDt() {
|
||||||
|
const dt = this.startDatepickerInstance.getDate();
|
||||||
|
this.setPageData({
|
||||||
|
fromDt: Utility.setFormatDate(dt, this.myOptions.sendFormat),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getEndDt() {
|
||||||
|
const dt = this.endDatepickerInstance.getDate();
|
||||||
|
this.setPageData({
|
||||||
|
toDt: Utility.setFormatDate(dt, this.myOptions.sendFormat),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
fromDtValueChkRang(newDt) {
|
||||||
|
const defaultDt = this.$dayjs(this.fromDtValue);
|
||||||
|
const compareDt = this.$dayjs(newDt);
|
||||||
|
const newDefault = Utility.setNewDefaultRange(
|
||||||
|
this.myCmCycle,
|
||||||
|
this.defaultRange,
|
||||||
|
);
|
||||||
|
|
||||||
|
const myRange = newDefault.range;
|
||||||
|
const rangeKey = newDefault.key;
|
||||||
|
const rangeGap = compareDt.diff(defaultDt, rangeKey);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(myRange > rangeGap && compareDt.isAfter(defaultDt)) ||
|
||||||
|
defaultDt.format(this.myOptions.sendFormat) ===
|
||||||
|
compareDt.format(this.myOptions.sendFormat)
|
||||||
|
) {
|
||||||
|
// if(this.cmCycleFlag){
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
// }
|
||||||
|
// this.cmCycleFlag = true;
|
||||||
|
} else {
|
||||||
|
this.setPageData({
|
||||||
|
fromDt: this.setDatePicker(
|
||||||
|
'fromDt',
|
||||||
|
compareDt,
|
||||||
|
this.myOptions.sendFormat,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toDtValueChkRang(newDt) {
|
||||||
|
const defaultDt = this.$dayjs(this.toDtValue);
|
||||||
|
const compareDt = this.$dayjs(newDt);
|
||||||
|
const newDefault = Utility.setNewDefaultRange(
|
||||||
|
this.myCmCycle,
|
||||||
|
this.defaultRange,
|
||||||
|
);
|
||||||
|
const myRange = newDefault.range;
|
||||||
|
const rangeKey = newDefault.key;
|
||||||
|
const rangeGap = defaultDt.diff(compareDt, rangeKey);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(myRange > rangeGap && defaultDt.isAfter(compareDt)) ||
|
||||||
|
defaultDt.format(this.myOptions.sendFormat) ===
|
||||||
|
compareDt.format(this.myOptions.sendFormat)
|
||||||
|
) {
|
||||||
|
this.setPageData({ isFind: true });
|
||||||
|
} else {
|
||||||
|
this.setPageData({
|
||||||
|
toDt: this.setDatePicker(
|
||||||
|
'toDt',
|
||||||
|
compareDt,
|
||||||
|
this.myOptions.sendFormat,
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.datepicker-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.v-input {
|
||||||
|
.v-input__append-outer {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-left: 0;
|
||||||
|
|
||||||
|
#startpicker-container,
|
||||||
|
#endpicker-container {
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 36px;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-input__custom {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
&.half {
|
||||||
|
width: calc(50% - 20px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::v-deep {
|
||||||
|
.tui-timepicker-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
background-color: #edf4fc;
|
||||||
|
.tui-timepicker-column.tui-timepicker-colon {
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
138
components/common/RadioCmCycle.vue
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
<template>
|
||||||
|
<v-row class="search-box" align="center" no-gutters>
|
||||||
|
<v-col v-if="label" :cols="labelCols">
|
||||||
|
<label for="" class="search-box-label">
|
||||||
|
<v-icon x-small color="primary" class="mr-1">mdi-record-circle</v-icon>
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
</v-col>
|
||||||
|
<v-col :cols="label ? 'auto' : ''">
|
||||||
|
<v-radio-group
|
||||||
|
v-model="selected"
|
||||||
|
required:rules="radioRules"
|
||||||
|
row
|
||||||
|
dense
|
||||||
|
:hide-details="true"
|
||||||
|
>
|
||||||
|
<v-radio
|
||||||
|
label="월별"
|
||||||
|
value="CYC_YEAR"
|
||||||
|
:ripple="false"
|
||||||
|
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
|
||||||
|
on-icon="mdi-record-circle"
|
||||||
|
></v-radio>
|
||||||
|
<v-radio
|
||||||
|
label="일별"
|
||||||
|
value="CYC_MONTH"
|
||||||
|
:ripple="false"
|
||||||
|
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
|
||||||
|
on-icon="mdi-record-circle"
|
||||||
|
></v-radio>
|
||||||
|
<v-radio
|
||||||
|
label="시간별"
|
||||||
|
value="CYC_DAY"
|
||||||
|
:ripple="false"
|
||||||
|
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
|
||||||
|
on-icon="mdi-record-circle"
|
||||||
|
></v-radio>
|
||||||
|
</v-radio-group>
|
||||||
|
<!-- @change="updateBlocCode($event)" -->
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations, mapActions } from 'vuex';
|
||||||
|
import Utility from '~/plugins/utility';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
require: false,
|
||||||
|
default: '주기',
|
||||||
|
},
|
||||||
|
labelCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 4,
|
||||||
|
},
|
||||||
|
textCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 7,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
labelPrepend: true,
|
||||||
|
// selected:"CYC_DAY"
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
searchParam: state => state.pageData,
|
||||||
|
isDarkMode: 'isDarkMode',
|
||||||
|
}),
|
||||||
|
selected: {
|
||||||
|
get() {
|
||||||
|
return this.searchParam[this.parentPrgmId].cmCycle;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.setDefaultDate(value);
|
||||||
|
return this.setPageData({ cmCycle: value });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {},
|
||||||
|
created() {
|
||||||
|
// this.setDefaultDate(this.searchParam[this.parentPrgmId].cmCycle);
|
||||||
|
},
|
||||||
|
async mounted() {},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({ setPageData: 'setPageData' }),
|
||||||
|
...mapActions({}),
|
||||||
|
setDefaultDate(value) {
|
||||||
|
// console.log("주기에 따른 오늘 기준 기본 날짜 세팅");
|
||||||
|
const today = Utility.setFormatDate('today', 'YYYY-MM-DD');
|
||||||
|
let srartDate = '';
|
||||||
|
let endDate = '';
|
||||||
|
// console.log(value);
|
||||||
|
switch (value) {
|
||||||
|
case 'CYC_YEAR':
|
||||||
|
// endDate = today;
|
||||||
|
srartDate = Utility.setFormatDate(today, 'YYYY');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CYC_MONTH':
|
||||||
|
// endDate = today;
|
||||||
|
srartDate = Utility.setFormatDate(today, 'YYYY-MM');
|
||||||
|
// endDate = today;
|
||||||
|
// srartDate = Utility.setBeforetDate(
|
||||||
|
// this.searchParam[this.parentPrgmId],
|
||||||
|
// endDate,
|
||||||
|
// "YYYYMMDD"
|
||||||
|
// );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'CYC_DAY':
|
||||||
|
// endDate = today;
|
||||||
|
srartDate = today;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.setPageData({ fromDt: srartDate });
|
||||||
|
// console.log(this.searchParam[this.parentPrgmId].cmCycle);
|
||||||
|
// console.log(this.searchParam[this.parentPrgmId].dateRange);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
113
components/common/RadioStandard.vue
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<template>
|
||||||
|
<v-row class="search-box" align="center" no-gutters>
|
||||||
|
<v-col v-if="label" :cols="labelCols">
|
||||||
|
<label for="" class="search-box-label">
|
||||||
|
<v-icon x-small color="primary" class="mr-1">mdi-record-circle</v-icon>
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
</v-col>
|
||||||
|
<v-col :cols="label ? textCols : ''">
|
||||||
|
<v-radio-group
|
||||||
|
v-model="selected"
|
||||||
|
required:rules="radioRules"
|
||||||
|
row
|
||||||
|
hide-details
|
||||||
|
dense
|
||||||
|
>
|
||||||
|
<v-radio
|
||||||
|
label="태그"
|
||||||
|
value="tag"
|
||||||
|
:ripple="false"
|
||||||
|
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
|
||||||
|
on-icon="mdi-record-circle"
|
||||||
|
></v-radio>
|
||||||
|
<v-radio
|
||||||
|
label="검침개소"
|
||||||
|
value="readPlc"
|
||||||
|
:ripple="false"
|
||||||
|
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
|
||||||
|
on-icon="mdi-record-circle"
|
||||||
|
></v-radio>
|
||||||
|
<v-radio
|
||||||
|
label="공정"
|
||||||
|
value="ecc"
|
||||||
|
:ripple="false"
|
||||||
|
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
|
||||||
|
on-icon="mdi-record-circle"
|
||||||
|
></v-radio>
|
||||||
|
<v-radio
|
||||||
|
label="설비"
|
||||||
|
value="eqpm"
|
||||||
|
:ripple="false"
|
||||||
|
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
|
||||||
|
on-icon="mdi-record-circle"
|
||||||
|
></v-radio>
|
||||||
|
</v-radio-group>
|
||||||
|
<!-- @change="updateBlocCode($event)" -->
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations, mapActions } from 'vuex';
|
||||||
|
import Utility from '~/plugins/utility';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
labelCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 4,
|
||||||
|
},
|
||||||
|
textCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 7,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
label: '기준',
|
||||||
|
labelPrepend: true,
|
||||||
|
// selected:"CYC_DAY"
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
isDarkMode: 'isDarkMode',
|
||||||
|
searchParam: state => state.pageData,
|
||||||
|
}),
|
||||||
|
selected: {
|
||||||
|
get() {
|
||||||
|
return this.searchParam[this.parentPrgmId].rdbStandard;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
return this.setPageData({ rdbStandard: value });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
selected(value) {
|
||||||
|
// 주기에 따른 오늘 기준 기본 날짜 세팅
|
||||||
|
this.setDefaultDate(value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// this.setDefaultDate(this.searchParam[this.parentPrgmId].cmCycle);
|
||||||
|
},
|
||||||
|
async mounted() {},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({ setPageData: 'setPageData' }),
|
||||||
|
...mapActions({}),
|
||||||
|
setDefaultDate(value) {
|
||||||
|
this.setPageData({ rdbStandard: value });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
99
components/common/RadioUseCost.vue
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<template>
|
||||||
|
<v-row class="search-box" align="center" no-gutters>
|
||||||
|
<v-col v-if="label" :cols="labelCols">
|
||||||
|
<label for="" class="search-box-label">
|
||||||
|
<v-icon x-small color="primary" class="mr-1">mdi-record-circle</v-icon>
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
</v-col>
|
||||||
|
<v-col :cols="label ? textCols : ''">
|
||||||
|
<v-radio-group
|
||||||
|
v-model="selected"
|
||||||
|
required:rules="radioRules"
|
||||||
|
row
|
||||||
|
hide-details
|
||||||
|
dense
|
||||||
|
>
|
||||||
|
<v-radio
|
||||||
|
label="사용량"
|
||||||
|
value="use"
|
||||||
|
:ripple="false"
|
||||||
|
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
|
||||||
|
on-icon="mdi-record-circle"
|
||||||
|
></v-radio>
|
||||||
|
<v-radio
|
||||||
|
label="비용"
|
||||||
|
value="cost"
|
||||||
|
:ripple="false"
|
||||||
|
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
|
||||||
|
on-icon="mdi-record-circle"
|
||||||
|
></v-radio>
|
||||||
|
</v-radio-group>
|
||||||
|
<!-- @change="updateBlocCode($event)" -->
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations, mapActions } from 'vuex';
|
||||||
|
import Utility from '~/plugins/utility';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
labelCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 4,
|
||||||
|
},
|
||||||
|
textCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 7,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
label: '구분',
|
||||||
|
labelPrepend: true,
|
||||||
|
// selected:"CYC_DAY"
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
isDarkMode: 'isDarkMode',
|
||||||
|
searchParam: state => state.pageData,
|
||||||
|
}),
|
||||||
|
selected: {
|
||||||
|
get() {
|
||||||
|
return this.searchParam[this.parentPrgmId].rdbUseCost;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
return this.setPageData({ rdbUseCost: value });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
selected(value) {
|
||||||
|
// 주기에 따른 오늘 기준 기본 날짜 세팅
|
||||||
|
this.setDefaultDate(value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// this.setDefaultDate(this.searchParam[this.parentPrgmId].cmCycle);
|
||||||
|
},
|
||||||
|
async mounted() {},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({ setPageData: 'setPageData' }),
|
||||||
|
...mapActions({}),
|
||||||
|
setDefaultDate(value) {
|
||||||
|
this.setPageData({ rdbUseCost: value });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
97
components/common/RadioView.vue
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<v-row class="search-box" align="center" no-gutters>
|
||||||
|
<v-col v-if="label" :cols="labelCols">
|
||||||
|
<label for="" class="search-box-label">
|
||||||
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
</v-col>
|
||||||
|
<v-col :cols="label ? textCols : ''">
|
||||||
|
<v-radio-group
|
||||||
|
v-model="selectedView"
|
||||||
|
required:rules="radioRules"
|
||||||
|
row
|
||||||
|
dense
|
||||||
|
:hide-details="true"
|
||||||
|
>
|
||||||
|
<v-radio
|
||||||
|
label="전체"
|
||||||
|
value="viewAll"
|
||||||
|
:ripple="false"
|
||||||
|
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
|
||||||
|
on-icon="mdi-record-circle"
|
||||||
|
></v-radio>
|
||||||
|
<v-radio
|
||||||
|
label="차트"
|
||||||
|
value="viewChart"
|
||||||
|
:ripple="false"
|
||||||
|
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
|
||||||
|
on-icon="mdi-record-circle"
|
||||||
|
></v-radio>
|
||||||
|
<v-radio
|
||||||
|
label="그리드"
|
||||||
|
value="viewGrid"
|
||||||
|
:ripple="false"
|
||||||
|
:color="isDarkMode ? '#1b74d7' : '#4777d9'"
|
||||||
|
on-icon="mdi-record-circle"
|
||||||
|
></v-radio>
|
||||||
|
</v-radio-group>
|
||||||
|
<!-- @change="updateBlocCode($event)" -->
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations, mapActions } from 'vuex';
|
||||||
|
import Utility from '~/plugins/utility';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
parentPrgmId: {
|
||||||
|
type: String,
|
||||||
|
require: true,
|
||||||
|
},
|
||||||
|
labelCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 4,
|
||||||
|
},
|
||||||
|
textCols: {
|
||||||
|
type: Number,
|
||||||
|
require: false,
|
||||||
|
default: 8,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
label: '',
|
||||||
|
labelPrepend: true,
|
||||||
|
// selected:"CYC_DAY"
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
searchParam: state => state.pageData,
|
||||||
|
isDarkMode: 'isDarkMode',
|
||||||
|
}),
|
||||||
|
selectedView: {
|
||||||
|
get() {
|
||||||
|
return this.searchParam[this.parentPrgmId].viewCheck;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
return this.setPageData({ viewCheck: value });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {},
|
||||||
|
created() {
|
||||||
|
// this.setDefaultDate(this.searchParam[this.parentPrgmId].cmCycle);
|
||||||
|
},
|
||||||
|
async mounted() {},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({ setPageData: 'setPageData' }),
|
||||||
|
...mapActions({}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
89
components/common/ThemeSwitch.vue
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<template>
|
||||||
|
<v-switch
|
||||||
|
class="theme-switch"
|
||||||
|
v-model="mode"
|
||||||
|
@change="themeChange"
|
||||||
|
></v-switch>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapState, mapMutations } from 'vuex';
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
mode: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
isDarkMode: 'isDarkMode',
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.mode = this.isDarkMode;
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations({
|
||||||
|
setThemeChange: 'setThemeChange',
|
||||||
|
}),
|
||||||
|
themeChange() {
|
||||||
|
this.$vuetify.theme.isDark = this.mode;
|
||||||
|
this.setThemeChange(this.mode);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.theme-switch {
|
||||||
|
display: inline-flex;
|
||||||
|
width: 47px;
|
||||||
|
height: 30px;
|
||||||
|
::v-deep {
|
||||||
|
.v-input__control,
|
||||||
|
.v-input__slot {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.v-input--selection-controls__input {
|
||||||
|
width: 100%;
|
||||||
|
margin-right: 0;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.v-input--switch__track {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 50px;
|
||||||
|
position: initial;
|
||||||
|
background-color: #f1f0f8;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
min-height: initial;
|
||||||
|
}
|
||||||
|
.v-input--selection-controls__ripple {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.v-input--switch__thumb {
|
||||||
|
position: absolute;
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
top: 2px;
|
||||||
|
left: 0;
|
||||||
|
background-image: url(../../assets/images/icon/ico-theme-light.png);
|
||||||
|
background-size: 18px 18px;
|
||||||
|
background-position: center center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.v-input--is-label-active {
|
||||||
|
::v-deep {
|
||||||
|
.v-input--switch__track {
|
||||||
|
background-color: #383f5d;
|
||||||
|
}
|
||||||
|
.v-input--switch__thumb {
|
||||||
|
transform: translate(38px, 0);
|
||||||
|
background-image: url(../../assets/images/icon/ico-theme-dark.png);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|