clone code
This commit is contained in:
parent
c9597d1e38
commit
d57bcd1719
362 changed files with 104804 additions and 0 deletions
4
.env.production
Normal file
4
.env.production
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
VITE_COMPETITIVE_EXAM_PANEL=VITE_COMPETITIVE_EXAM_PANEL
|
||||||
|
VITE_QUALIFY_DISABLE_EMAM_PANEL=VITE_QUALIFY_DISABLE_EMAM_PANEL
|
||||||
|
VITE_QUALIFY_EXAM_PANEL=VITE_QUALIFY_EXAM_PANEL
|
||||||
|
VITE_S3CLUSTER_PUBLIC_URL=VITE_S3CLUSTER_PUBLIC_URL
|
||||||
21
.eslintrc.cjs
Normal file
21
.eslintrc.cjs
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* eslint-env node */
|
||||||
|
require("@rushstack/eslint-patch/modern-module-resolution");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
extends: [
|
||||||
|
"plugin:vue/vue3-essential",
|
||||||
|
"eslint:recommended",
|
||||||
|
"@vue/eslint-config-typescript/recommended",
|
||||||
|
"@vue/eslint-config-prettier/recommended",
|
||||||
|
],
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: ["cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}"],
|
||||||
|
extends: ["plugin:cypress/recommended"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: "latest",
|
||||||
|
},
|
||||||
|
};
|
||||||
39
.github/workflows/build-local.yaml
vendored
Normal file
39
.github/workflows/build-local.yaml
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
# use for local build with act
|
||||||
|
name: build-local
|
||||||
|
run-name: build-local ${{ github.actor }}
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
env:
|
||||||
|
REGISTRY: docker.frappet.com
|
||||||
|
IMAGE_NAME: demo/bma-ehr-app
|
||||||
|
jobs:
|
||||||
|
# act workflow_dispatch -W .github/workflows/build-local.yaml --input IMAGE_VER=test-v1
|
||||||
|
build-local:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
# skip Set up QEMU because it fail on act and container
|
||||||
|
- name: Gen Version
|
||||||
|
id: gen_ver
|
||||||
|
run: |
|
||||||
|
if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||||
|
IMAGE_VER='${GITHUB_REF/refs\/tags\//}'
|
||||||
|
else
|
||||||
|
IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||||
|
fi
|
||||||
|
if [[ $IMAGE_VER == '' ]]; then
|
||||||
|
IMAGE_VER='test-vBeta'
|
||||||
|
fi
|
||||||
|
echo '::set-output name=image_ver::'$IMAGE_VER
|
||||||
|
- name: Test Version
|
||||||
|
run: |
|
||||||
|
echo $GITHUB_REF
|
||||||
|
echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||||
|
|
||||||
|
- name: Build and load local docker image
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
platforms: linux/amd64
|
||||||
|
load: true
|
||||||
|
tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest
|
||||||
86
.github/workflows/release.yaml
vendored
Normal file
86
.github/workflows/release.yaml
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
name: release-test
|
||||||
|
run-name: release-test ${{ github.actor }}
|
||||||
|
on:
|
||||||
|
# push:
|
||||||
|
# tags:
|
||||||
|
# - 'v[0-9]+.[0-9]+.[0-9]+'
|
||||||
|
# tags-ignore:
|
||||||
|
# - '2.*'
|
||||||
|
# Allow run workflow manually from Action tab
|
||||||
|
workflow_dispatch:
|
||||||
|
env:
|
||||||
|
REGISTRY: docker.frappet.com
|
||||||
|
IMAGE_NAME: ehr/bma-ehr-app
|
||||||
|
DEPLOY_HOST: frappet.com
|
||||||
|
COMPOSE_PATH: /home/frappet/docker/bma-ehr
|
||||||
|
TOKEN_LINE: uxuK5hDzS2DsoC5piJBrWRLiz8GgY7iMZZldOWsDDF0
|
||||||
|
jobs:
|
||||||
|
# # act workflow_dispatch -W .github/workflows/release.yaml --input IMAGE_VER=test-v1 -s DOCKER_USER=sorawit -s DOCKER_PASS=P@ssword -s SSH_PASSWORD=P@ssw0rd
|
||||||
|
# release-test:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v3
|
||||||
|
# # skip Set up QEMU because it fail on act and container
|
||||||
|
# # Gen Version try to get version from tag or inut
|
||||||
|
# - name: Gen Version
|
||||||
|
# id: gen_ver
|
||||||
|
# run: |
|
||||||
|
# if [[ $GITHUB_REF == 'refs/tags/'* ]]; then
|
||||||
|
# IMAGE_VER='${GITHUB_REF/refs\/tags\//}'
|
||||||
|
# else
|
||||||
|
# IMAGE_VER=${{ github.event.inputs.IMAGE_VER }}
|
||||||
|
# fi
|
||||||
|
# if [[ $IMAGE_VER == '' ]]; then
|
||||||
|
# IMAGE_VER='test-vBeta'
|
||||||
|
# fi
|
||||||
|
# echo '::set-output name=image_ver::'$IMAGE_VER
|
||||||
|
# - name: Check Version
|
||||||
|
# run: |
|
||||||
|
# echo $GITHUB_REF
|
||||||
|
# echo ${{ steps.gen_ver.outputs.image_ver }}
|
||||||
|
|
||||||
|
# - name: Set up Docker Buildx
|
||||||
|
# uses: docker/setup-buildx-action@v2
|
||||||
|
# - name: Login in to registry
|
||||||
|
# uses: docker/login-action@v2
|
||||||
|
# with:
|
||||||
|
# registry: ${{env.REGISTRY}}
|
||||||
|
# username: ${{secrets.DOCKER_USER}}
|
||||||
|
# password: ${{secrets.DOCKER_PASS}}
|
||||||
|
# - name: Build and push docker image
|
||||||
|
# uses: docker/build-push-action@v3
|
||||||
|
# with:
|
||||||
|
# context: .
|
||||||
|
# platforms: linux/amd64
|
||||||
|
# push: true
|
||||||
|
# tags: ${{env.REGISTRY}}/${{env.IMAGE_NAME}}:${{ steps.gen_ver.outputs.image_ver }},${{env.REGISTRY}}/${{env.IMAGE_NAME}}:latest
|
||||||
|
# - name: Remote Deployment
|
||||||
|
# uses: appleboy/ssh-action@v0.1.8
|
||||||
|
# with:
|
||||||
|
# host: ${{env.DEPLOY_HOST}}
|
||||||
|
# username: frappet
|
||||||
|
# password: ${{ secrets.SSH_PASSWORD }}
|
||||||
|
# port: 22
|
||||||
|
# script: |
|
||||||
|
# cd "${{env.COMPOSE_PATH}}"
|
||||||
|
# docker-compose pull
|
||||||
|
# docker-compose up -d
|
||||||
|
# echo "${{ steps.gen_ver.outputs.image_ver }}"> success
|
||||||
|
# - uses: snow-actions/line-notify@v1.1.0
|
||||||
|
# if: success()
|
||||||
|
# with:
|
||||||
|
# access_token: ${{ env.TOKEN_LINE }}
|
||||||
|
# message: |
|
||||||
|
# -Success✅✅✅
|
||||||
|
# Image: ${{env.IMAGE_NAME}}
|
||||||
|
# Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||||
|
# By: ${{secrets.DOCKER_USER}}
|
||||||
|
# - uses: snow-actions/line-notify@v1.1.0
|
||||||
|
# if: failure()
|
||||||
|
# with:
|
||||||
|
# access_token: ${{ env.TOKEN_LINE }}
|
||||||
|
# message: |
|
||||||
|
# -Failure❌❌❌
|
||||||
|
# Image: ${{env.IMAGE_NAME}}
|
||||||
|
# Version: ${{ github.event.inputs.IMAGE_VER }}
|
||||||
|
# By: ${{secrets.DOCKER_USER}}
|
||||||
28
.gitignore
vendored
Normal file
28
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
coverage
|
||||||
|
*.local
|
||||||
|
|
||||||
|
/cypress/videos/
|
||||||
|
/cypress/screenshots/
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
1
.prettierrc.json
Normal file
1
.prettierrc.json
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
{}
|
||||||
3
.vscode/extensions.json
vendored
Normal file
3
.vscode/extensions.json
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
|
||||||
|
}
|
||||||
21
Dockerfile
Normal file
21
Dockerfile
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
# docker build . -t docker.frappet.com/demo/fe:latest
|
||||||
|
FROM node:latest as build-stage
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package*.json ./
|
||||||
|
RUN npm install
|
||||||
|
COPY ./ .
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
FROM nginx as production-stage
|
||||||
|
|
||||||
|
RUN mkdir /app
|
||||||
|
COPY --from=build-stage /app/dist /app
|
||||||
|
COPY nginx.conf /etc/nginx/nginx.conf
|
||||||
|
|
||||||
|
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
|
RUN chmod u+x /usr/local/bin/entrypoint.sh
|
||||||
|
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||||
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
8
cypress.config.ts
Normal file
8
cypress.config.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { defineConfig } from 'cypress'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
e2e: {
|
||||||
|
specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
|
||||||
|
baseUrl: 'http://localhost:4173'
|
||||||
|
}
|
||||||
|
})
|
||||||
8
cypress/e2e/example.cy.ts
Normal file
8
cypress/e2e/example.cy.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
// https://docs.cypress.io/api/introduction/api.html
|
||||||
|
|
||||||
|
describe('My First Test', () => {
|
||||||
|
it('visits the app root url', () => {
|
||||||
|
cy.visit('/')
|
||||||
|
cy.contains('h1', 'You did it!')
|
||||||
|
})
|
||||||
|
})
|
||||||
10
cypress/e2e/tsconfig.json
Normal file
10
cypress/e2e/tsconfig.json
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"extends": "@vue/tsconfig/tsconfig.web.json",
|
||||||
|
"include": ["./**/*", "../support/**/*"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"isolatedModules": false,
|
||||||
|
"target": "es5",
|
||||||
|
"lib": ["es5", "dom"],
|
||||||
|
"types": ["cypress"]
|
||||||
|
}
|
||||||
|
}
|
||||||
5
cypress/fixtures/example.json
Normal file
5
cypress/fixtures/example.json
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name": "Using fixtures to represent data",
|
||||||
|
"email": "hello@cypress.io",
|
||||||
|
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||||
|
}
|
||||||
39
cypress/support/commands.ts
Normal file
39
cypress/support/commands.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
/// <reference types="cypress" />
|
||||||
|
// ***********************************************
|
||||||
|
// This example commands.ts shows you how to
|
||||||
|
// create various custom commands and overwrite
|
||||||
|
// existing commands.
|
||||||
|
//
|
||||||
|
// For more comprehensive examples of custom
|
||||||
|
// commands please read more here:
|
||||||
|
// https://on.cypress.io/custom-commands
|
||||||
|
// ***********************************************
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a parent command --
|
||||||
|
// Cypress.Commands.add('login', (email, password) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a child command --
|
||||||
|
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This is a dual command --
|
||||||
|
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// -- This will overwrite an existing command --
|
||||||
|
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
|
||||||
|
//
|
||||||
|
// declare global {
|
||||||
|
// namespace Cypress {
|
||||||
|
// interface Chainable {
|
||||||
|
// login(email: string, password: string): Chainable<void>
|
||||||
|
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
|
||||||
|
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
|
||||||
|
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
export {}
|
||||||
20
cypress/support/e2e.ts
Normal file
20
cypress/support/e2e.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
// ***********************************************************
|
||||||
|
// This example support/index.js is processed and
|
||||||
|
// loaded automatically before your test files.
|
||||||
|
//
|
||||||
|
// This is a great place to put global configuration and
|
||||||
|
// behavior that modifies Cypress.
|
||||||
|
//
|
||||||
|
// You can change the location of this file or turn off
|
||||||
|
// automatically serving support files with the
|
||||||
|
// 'supportFile' configuration option.
|
||||||
|
//
|
||||||
|
// You can read more here:
|
||||||
|
// https://on.cypress.io/configuration
|
||||||
|
// ***********************************************************
|
||||||
|
|
||||||
|
// Import commands.js using ES2015 syntax:
|
||||||
|
import './commands'
|
||||||
|
|
||||||
|
// Alternatively you can use CommonJS syntax:
|
||||||
|
// require('./commands')
|
||||||
19
entrypoint.sh
Normal file
19
entrypoint.sh
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
ROOT_DIR=/app
|
||||||
|
|
||||||
|
# Replace env vars in JavaScript files
|
||||||
|
echo "Replacing env constants in JS"
|
||||||
|
for file in $ROOT_DIR/assets/app.*.js* $ROOT_DIR/js/app.*.js* $ROOT_DIR/index.html $ROOT_DIR/precache-manifest*.js;
|
||||||
|
do
|
||||||
|
echo "Processing $file ...";
|
||||||
|
|
||||||
|
sed -i 's|VITE_COMPETITIVE_EXAM_PANEL|'${VITE_COMPETITIVE_EXAM_PANEL}'|g' $file
|
||||||
|
sed -i 's|VITE_QUALIFY_DISABLE_EMAM_PANEL|'${VITE_QUALIFY_DISABLE_EMAM_PANEL}'|g' $file
|
||||||
|
sed -i 's|VITE_QUALIFY_EXAM_PANEL|'${VITE_QUALIFY_EXAM_PANEL}'|g' $file
|
||||||
|
sed -i 's|VITE_S3CLUSTER_PUBLIC_URL|'${VITE_S3CLUSTER_PUBLIC_URL}'|g' $file
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Starting Nginx"
|
||||||
|
nginx -g 'daemon off;'
|
||||||
1
env.d.ts
vendored
Normal file
1
env.d.ts
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/// <reference types="vite/client" />
|
||||||
13
index.html
Normal file
13
index.html
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="icon" href="/favicon.ico">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>ระบบทรัพยากรบุคคล</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
30
nginx.conf
Normal file
30
nginx.conf
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
user nginx;
|
||||||
|
worker_processes 1;
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
access_log /var/log/nginx/access.log main;
|
||||||
|
sendfile on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
location / {
|
||||||
|
root /app;
|
||||||
|
index index.html;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14326
package-lock.json
generated
Normal file
14326
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
62
package.json
Normal file
62
package.json
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
{
|
||||||
|
"name": "ehr",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "run-p type-check build-only",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"test:unit": "vitest --environment jsdom --root src/",
|
||||||
|
"test:e2e": "start-server-and-test preview :4173 'cypress run --e2e'",
|
||||||
|
"test:e2e:dev": "start-server-and-test 'vite dev --port 4173' :4173 'cypress open --e2e'",
|
||||||
|
"build-only": "vite build",
|
||||||
|
"type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
|
||||||
|
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@fullcalendar/core": "^6.0.1",
|
||||||
|
"@fullcalendar/daygrid": "^6.0.1",
|
||||||
|
"@fullcalendar/interaction": "^6.0.2",
|
||||||
|
"@fullcalendar/list": "^6.0.2",
|
||||||
|
"@fullcalendar/react": "^6.0.1",
|
||||||
|
"@fullcalendar/timegrid": "^6.0.2",
|
||||||
|
"@fullcalendar/vue3": "^6.0.1",
|
||||||
|
"@quasar/extras": "^1.15.8",
|
||||||
|
"@vuepic/vue-datepicker": "^3.6.3",
|
||||||
|
"bma-org-chart": "^0.0.7",
|
||||||
|
"keycloak-js": "^20.0.2",
|
||||||
|
"moment": "^2.29.4",
|
||||||
|
"pinia": "^2.0.29",
|
||||||
|
"quasar": "^2.11.1",
|
||||||
|
"structure-chart": "^0.0.9",
|
||||||
|
"vue": "^3.2.45",
|
||||||
|
"vue-router": "^4.1.6",
|
||||||
|
"vue3-datepicker": "^0.3.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@quasar/vite-plugin": "^1.3.0",
|
||||||
|
"@rushstack/eslint-patch": "^1.1.4",
|
||||||
|
"@types/jsdom": "^20.0.1",
|
||||||
|
"@types/node": "^18.11.12",
|
||||||
|
"@vitejs/plugin-vue": "^4.0.0",
|
||||||
|
"@vitejs/plugin-vue-jsx": "^3.0.0",
|
||||||
|
"@vue/eslint-config-prettier": "^7.0.0",
|
||||||
|
"@vue/eslint-config-typescript": "^11.0.0",
|
||||||
|
"@vue/test-utils": "^2.2.6",
|
||||||
|
"@vue/tsconfig": "^0.1.3",
|
||||||
|
"cypress": "^12.0.2",
|
||||||
|
"eslint": "^8.22.0",
|
||||||
|
"eslint-plugin-cypress": "^2.12.1",
|
||||||
|
"eslint-plugin-vue": "^9.3.0",
|
||||||
|
"jsdom": "^20.0.3",
|
||||||
|
"npm-run-all": "^4.1.5",
|
||||||
|
"prettier": "^2.7.1",
|
||||||
|
"sass": "^1.32.12",
|
||||||
|
"start-server-and-test": "^1.15.2",
|
||||||
|
"typescript": "~4.7.4",
|
||||||
|
"vite": "^4.0.0",
|
||||||
|
"vitest": "^0.25.6",
|
||||||
|
"vue-table-to-excel": "^1.0.6",
|
||||||
|
"vue-tsc": "^1.0.12"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1 MiB |
15
src/App.vue
Normal file
15
src/App.vue
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div id="azay-admin-app">
|
||||||
|
<router-view v-slot="{ Component }">
|
||||||
|
<transition>
|
||||||
|
<component :is="Component" />
|
||||||
|
</transition>
|
||||||
|
</router-view>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
14
src/api/02_organizational/api.chart.ts
Normal file
14
src/api/02_organizational/api.chart.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
/**
|
||||||
|
* API Structure + Org Chart
|
||||||
|
*/
|
||||||
|
import env from "../index"
|
||||||
|
|
||||||
|
const treeRoot = `${env.API_URI}/Organization/treeroot`
|
||||||
|
const structChart = `${env.API_URI}/Organization/struct-chart/`
|
||||||
|
const orgChart = `${env.API_URI}/Organization/org-chart/`
|
||||||
|
|
||||||
|
export default {
|
||||||
|
chartGetTreeRoot: `${treeRoot}`,
|
||||||
|
chartGetStructure: (id: string) => `${structChart}${id}`,
|
||||||
|
chartGetOrg: (id: string) => `${orgChart}${id}`
|
||||||
|
}
|
||||||
80
src/api/02_organizational/api.treelist.ts
Normal file
80
src/api/02_organizational/api.treelist.ts
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
* api ระบบจัดการ Tree
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import env from "../index";
|
||||||
|
//Dropdown เพิ่มโครงร้างหน่วยงาน
|
||||||
|
// const organizationAgency = `${env.API_URI_ORG_SERVICE}/organization-agency/`;
|
||||||
|
// const organizationGovernmentAgency = `${env.API_URI_ORG_SERVICE}/organization-government-agency/`;
|
||||||
|
// const organizationPath = `${env.API_URI}/Organization/tree`;
|
||||||
|
const organizationPath = `${env.API_URI_ORG_SERVICE}/Organization/`;
|
||||||
|
const postionMasterPath = `${env.API_URI_ORG_SERVICE}/PositionMaster`;
|
||||||
|
const organizationPosition = `${env.API_URI_ORG_SERVICE}/OrganizationPosition/`;
|
||||||
|
|
||||||
|
const report = `${env.API_URI}/report/organization/`;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getOCType: `${report}oc-type`,
|
||||||
|
getReportAccount1: (id: string) => `${report}account1/${id}`,
|
||||||
|
getReportAccount2: (id: string) => `${report}account2/${id}`,
|
||||||
|
getReportAccount3: (id: string) => `${report}account3/${id}`,
|
||||||
|
|
||||||
|
/**api หน่วยงานต้นสังกัด/ส่วนราชการต้นสังกัด
|
||||||
|
* @param organizationType หน่วยงาน หรือ ส่วนราชการ
|
||||||
|
* @returns organizationId and organizationName
|
||||||
|
*/
|
||||||
|
listOrganizationAgency: (organizationType: string) =>
|
||||||
|
`${organizationPath}type/${organizationType}`,
|
||||||
|
|
||||||
|
/**api Tree
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
// treeList: `${organizationPath}`,
|
||||||
|
getTreeRoot: `${organizationPath}treeroot`,
|
||||||
|
getDraftTreeRoot: `${organizationPath}history/treeroot`,
|
||||||
|
getTreeHistory: `${organizationPath}publish-history`,
|
||||||
|
getTreeNode: (organizationId: string, keyId: string) =>
|
||||||
|
`${organizationPath}tree?organizationId=${organizationId}&keyId=${keyId}`,
|
||||||
|
getDraftTreeNode: (organizationId: string, keyId: string) =>
|
||||||
|
`${organizationPath}history/tree?organizationId=${organizationId}&keyId=${keyId}`,
|
||||||
|
addTreeDraft: `${organizationPosition}history`,
|
||||||
|
editTreeOrgDraft: (organizationId: string) =>
|
||||||
|
`${organizationPath}history/${organizationId}`,
|
||||||
|
getOrgDraft: (organizationId: string) =>
|
||||||
|
`${organizationPath}history/${organizationId}`,
|
||||||
|
// /api/v1/Organization/history?organizationPositionId=65ab2ddc-b9d2-4422-83d4-b90dd8191b6f
|
||||||
|
delTreeOrgDraft: (organizationId: string) =>
|
||||||
|
`${organizationPath}history?organizationPositionId=${organizationId}`,
|
||||||
|
getPostionMasterDraft: (showAll: boolean) =>
|
||||||
|
`${postionMasterPath}/history?showall=${showAll}`,
|
||||||
|
getPostionMaster: (showAll: boolean) =>
|
||||||
|
`${postionMasterPath}?showall=${showAll}`,
|
||||||
|
editTreePositionDraft: (organizationPositionId: string) =>
|
||||||
|
`${organizationPosition}history?organizationPositionId=${organizationPositionId}`,
|
||||||
|
// /api/v1/OrganizationPosition/history?organizationPositionId=15ec8c2b-796f-4fad-b731-667a232e723e
|
||||||
|
delTreePositionDraft: (organizationPositionId: string) =>
|
||||||
|
`${organizationPosition}history/${organizationPositionId}`,
|
||||||
|
|
||||||
|
//PUT /api/v1/OrganizationPosition/history/publish
|
||||||
|
publishOrgPoDraft: `${organizationPosition}history/publish`,
|
||||||
|
//PUT /api/v1/OrganizationPosition/history/sync
|
||||||
|
delTreeOrgPoDraft: `${organizationPosition}history/sync`,
|
||||||
|
isOrgPohasDraft: `${organizationPosition}history/has-draft`,
|
||||||
|
isOrghasDraft: `${organizationPath}history/has-draft`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api จัดการตำแหน่ง
|
||||||
|
*/
|
||||||
|
getPositionMaster: `${postionMasterPath}/history`,
|
||||||
|
getPositionMasterId: (id: string) => `${postionMasterPath}/history/${id}`,
|
||||||
|
getPositionMasterPublish: `${postionMasterPath}/history/publish`,
|
||||||
|
getPositionMasterSync: `${postionMasterPath}/history/sync`,
|
||||||
|
getPositionMasterHistoryId: (id: string) =>
|
||||||
|
`${postionMasterPath}/history/publish/${id}`,
|
||||||
|
|
||||||
|
getPositionMasterPositionNumber: `${postionMasterPath}/position-number`,
|
||||||
|
getPositionMasterPositionNumberId: (id: string) =>
|
||||||
|
`${postionMasterPath}/position-number/${id}`,
|
||||||
|
getPositionNumberIdByOcId: (OcId: string) =>
|
||||||
|
`${postionMasterPath}/position-number/Oc/${OcId}`,
|
||||||
|
};
|
||||||
6
src/api/05_placement/api.placement.ts
Normal file
6
src/api/05_placement/api.placement.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
/**
|
||||||
|
* api บรรจุ แต่งตั้ง ย้าย โอน
|
||||||
|
*/
|
||||||
|
import env from "../index";
|
||||||
|
|
||||||
|
export default {};
|
||||||
6
src/api/06_retirement/api.retirement.ts
Normal file
6
src/api/06_retirement/api.retirement.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
/**
|
||||||
|
* api พ้นจากราชการ
|
||||||
|
*/
|
||||||
|
import env from "../index";
|
||||||
|
|
||||||
|
export default {};
|
||||||
6
src/api/07_insignia/api.insignia.ts
Normal file
6
src/api/07_insignia/api.insignia.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
/**
|
||||||
|
* api เครื่องราชอิสริยาภรณ์
|
||||||
|
*/
|
||||||
|
import env from "../index";
|
||||||
|
|
||||||
|
export default {};
|
||||||
62
src/api/index.ts
Normal file
62
src/api/index.ts
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**config api */
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
const env = ref<string>(process.env.NODE_ENV || "development");
|
||||||
|
// if (process.env.VUE_APP_TEST) {
|
||||||
|
// env = "test";
|
||||||
|
// }
|
||||||
|
|
||||||
|
const config = ref<any>({
|
||||||
|
development: {
|
||||||
|
// API_URI: "https://localhost:7006/api/v1",
|
||||||
|
API_URI: "https://bma-ehr.frappet.synology.me/api/v1",
|
||||||
|
// API_URI_ORG_SERVICE: "https://localhost:7056/api/v1", //ใช้ชั่วคราว
|
||||||
|
API_URI_ORG_SERVICE: "https://bma-ehr.frappet.synology.me/api/v1", //ใช้ชั่วคราว
|
||||||
|
// API_URI_PROFILE_SERVICE: "https://localhost:7159/api/v1",
|
||||||
|
API_URI_PROFILE_SERVICE: "https://bma-ehr.frappet.synology.me/api/v1", //ใช้ชั่วคราว
|
||||||
|
// API_CANDIDATE_URI: "https://localhost:7007/api/v1",
|
||||||
|
API_CANDIDATE_URI: "https://bma-ehr.frappet.synology.me/api/v1",
|
||||||
|
// API_REPORT_URI: "https://localhost:7187/api/v1",
|
||||||
|
API_REPORT_URI: "https://bma-ehr.frappet.synology.me/api/v1",
|
||||||
|
MEET_URI: "meet.frappet.com",
|
||||||
|
},
|
||||||
|
test: {
|
||||||
|
API_URI: "http://localhost:5010/api/v1",
|
||||||
|
API_CANDIDATE_URI: "https://localhost:7007/api/v1",
|
||||||
|
API_REPORT_URI: "https://localhost:7007/api/v1",
|
||||||
|
MEET_URI: "meet.frappet.com",
|
||||||
|
},
|
||||||
|
production: {
|
||||||
|
// API_URI: "https://localhost:5010",
|
||||||
|
API_URI: `${window.location.protocol}//${window.location.host}/api/v1`,
|
||||||
|
API_URI_ORG_SERVICE: `${window.location.protocol}//${window.location.host}/api/v1`, //ใช้ชั่วคราว
|
||||||
|
API_URI_PROFILE_SERVICE: `${window.location.protocol}//${window.location.host}/api/v1`,
|
||||||
|
API_CANDIDATE_URI: `${window.location.protocol}//${window.location.host}/api/v1`,
|
||||||
|
API_REPORT_URI: `${window.location.protocol}//${window.location.host}/api/v1`,
|
||||||
|
MEET_URI: "meet.frappet.com",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const API_URI = ref<string>(config.value[env.value].API_URI);
|
||||||
|
const API_CANDIDATE_URI = ref<string>(
|
||||||
|
config.value[env.value].API_CANDIDATE_URI
|
||||||
|
);
|
||||||
|
const API_REPORT_URI = ref<string>(config.value[env.value].API_REPORT_URI);
|
||||||
|
const API_URI_ORG_SERVICE = ref<string>(
|
||||||
|
config.value[env.value].API_URI_ORG_SERVICE
|
||||||
|
);
|
||||||
|
const MEET_URI = ref<string>(config.value[env.value].MEET_URI);
|
||||||
|
const API_URI_PROFILE_SERVICE = ref<string>(
|
||||||
|
config.value[env.value].API_URI_PROFILE_SERVICE
|
||||||
|
);
|
||||||
|
|
||||||
|
export default {
|
||||||
|
env: env.value,
|
||||||
|
config: config.value,
|
||||||
|
API_URI: API_URI.value,
|
||||||
|
API_CANDIDATE_URI: API_CANDIDATE_URI.value,
|
||||||
|
API_REPORT_URI: API_REPORT_URI.value,
|
||||||
|
API_URI_ORG_SERVICE: API_URI_ORG_SERVICE.value,
|
||||||
|
API_URI_PROFILE_SERVICE: API_URI_PROFILE_SERVICE.value,
|
||||||
|
MEET_URI: MEET_URI.value,
|
||||||
|
};
|
||||||
23
src/api/manage/api.holiday.ts
Normal file
23
src/api/manage/api.holiday.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
/**
|
||||||
|
* api ระบบจัดการข้อมูลหลัก
|
||||||
|
* เมนูย่อย: ปฏิทินวันหยุด
|
||||||
|
*/
|
||||||
|
import env from "../index";
|
||||||
|
const holiday = `${env.API_URI}/metadata/holiday/`;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
/**
|
||||||
|
* api ชั้นเครื่องราชฯ
|
||||||
|
*/
|
||||||
|
listHolidayHistoryAdd: (category: string) =>
|
||||||
|
`${holiday}range/add/${category}`,
|
||||||
|
listHolidayHistoryEdit: (category: string) =>
|
||||||
|
`${holiday}range/edit/${category}`,
|
||||||
|
listHolidayHistoryDelete: (category: string) =>
|
||||||
|
`${holiday}range/delete/${category}`,
|
||||||
|
listHolidayHistoryYear: (year: number) => `${holiday}${year}`,
|
||||||
|
listHolidayHistoryYearMonth: (year: number, month: number) =>
|
||||||
|
`${holiday}${year}/${month}`,
|
||||||
|
listHolidayCopy: `${holiday}copy`,
|
||||||
|
summaryHolidayHistoryYear: (year: number) => `${holiday}summary/${year}`,
|
||||||
|
};
|
||||||
35
src/api/manage/api.insignia.ts
Normal file
35
src/api/manage/api.insignia.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* api ระบบจัดการข้อมูลหลัก
|
||||||
|
* เมนูย่อย: ข้อมูลเครื่องราชอิสริยาภรณ์
|
||||||
|
*/
|
||||||
|
import env from "../index";
|
||||||
|
const insignia = `${env.API_URI}/metadata/insignia/`;
|
||||||
|
const insigniaType = `${env.API_URI}/metadata/insignia-type/`;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
/**
|
||||||
|
* api ชั้นเครื่องราชฯ
|
||||||
|
*/
|
||||||
|
insignia,
|
||||||
|
listInsigniaHistory: `${insignia}history`,
|
||||||
|
listInsigniaHistoryId: (id: string) => `${insignia}history/${id}`,
|
||||||
|
listInsigniaPublished: `${insignia}history/published`,
|
||||||
|
listInsigniaPublishedHistory: `${insignia}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ประเภท
|
||||||
|
*/
|
||||||
|
insigniaType,
|
||||||
|
listInsigniaTypeHistory: `${insigniaType}history`,
|
||||||
|
listInsigniaTypeHistoryId: (id: string) => `${insigniaType}history/${id}`,
|
||||||
|
listInsigniaTypePublished: `${insigniaType}history/published`,
|
||||||
|
listInsigniaTypePublishedHistory: `${insigniaType}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api เหรียญตรา
|
||||||
|
*/
|
||||||
|
// listInsigniaHistory: `${insignia}history`,
|
||||||
|
// listInsigniaHistoryId: (id: string) => `${insignia}history/${id}`,
|
||||||
|
// listInsigniaPublished: `${insignia}history/published`,
|
||||||
|
// listInsigniaPublishedHistory: `${insignia}history/published-history`,
|
||||||
|
};
|
||||||
130
src/api/manage/api.organization.ts
Normal file
130
src/api/manage/api.organization.ts
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
/**
|
||||||
|
* api ระบบจัดการข้อมูลหลัก
|
||||||
|
* เมนูย่อย: ข้อมูลโครงสร้างหน่วยงาน
|
||||||
|
*/
|
||||||
|
import env from "../index"
|
||||||
|
const organization = `${env.API_URI}/metadata/organization/`
|
||||||
|
const organizationOrganization = `${env.API_URI}/metadata/organization-organization/`
|
||||||
|
const organizationShortName = `${env.API_URI}/metadata/organization-shortname/`
|
||||||
|
const organizationCode = `${env.API_URI_ORG_SERVICE}/PositionMaster/`
|
||||||
|
const organizationType = `${env.API_URI}/metadata/organization-type/`
|
||||||
|
const organizationLevel = `${env.API_URI}/metadata/organization-level/`
|
||||||
|
const organizationStatus = `${env.API_URI}/metadata/organization-status/`
|
||||||
|
const organizationAgency = `${env.API_URI}/metadata/organization-agency/`
|
||||||
|
const organizationGovernmentAgency = `${env.API_URI}/metadata/organization-government-agency/`
|
||||||
|
const organizationTelExternal = `${env.API_URI}/metadata/organization-tel-external/`
|
||||||
|
const organizationTelInternal = `${env.API_URI}/metadata/organization-tel-internal/`
|
||||||
|
const organizationFax = `${env.API_URI}/metadata/organization-fax/`
|
||||||
|
const dashbord = `${env.API_URI}/metadata/dashbord/`
|
||||||
|
|
||||||
|
export default {
|
||||||
|
/**
|
||||||
|
* api จำนวนข้อมูลใน ระบบจัดการข้อมูลหลัก tab ย่อยแต่ละ tab
|
||||||
|
*/
|
||||||
|
organization,
|
||||||
|
countDashbordSubHistory: (type: number) => `${dashbord}${type}`,
|
||||||
|
countDashbordHistory: `${dashbord}`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api หน่วยงาน
|
||||||
|
*/
|
||||||
|
listOrganizationOrganizationHistory: `${organizationOrganization}history`,
|
||||||
|
listOrganizationOrganizationHistoryId: (id: string) =>
|
||||||
|
`${organizationOrganization}history/${id}`,
|
||||||
|
listOrganizationOrganizationPublished: `${organizationOrganization}history/published`,
|
||||||
|
listOrganizationOrganizationPublishedHistory: `${organizationOrganization}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ชื่อย่อหน่วยงาน
|
||||||
|
*/
|
||||||
|
organizationShortName,
|
||||||
|
listOrganizationShortNameHistory: `${organizationShortName}history`,
|
||||||
|
listOrganizationShortNameHistoryId: (id: string) =>
|
||||||
|
`${organizationShortName}history/${id}`,
|
||||||
|
listOrganizationShortNamePublished: `${organizationShortName}history/published`,
|
||||||
|
listOrganizationShortNamePublishedHistory: `${organizationShortName}history/published-history`,
|
||||||
|
organizationCode: `${organizationCode}organization-code`,
|
||||||
|
organizationGovernmentCode: (id: string) =>
|
||||||
|
`${organizationCode}government/${id}`,
|
||||||
|
organizationAgencyCode: (id: string) => `${organizationCode}agency/${id}`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ประเภท
|
||||||
|
*/
|
||||||
|
organizationType,
|
||||||
|
listOrganizationTypeHistory: `${organizationType}history`,
|
||||||
|
listOrganizationTypeHistoryId: (id: string) =>
|
||||||
|
`${organizationType}history/${id}`,
|
||||||
|
listOrganizationTypePublished: `${organizationType}history/published`,
|
||||||
|
listOrganizationTypePublishedHistory: `${organizationType}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ระดับ
|
||||||
|
*/
|
||||||
|
organizationLevel,
|
||||||
|
listOrganizationLevelHistory: `${organizationLevel}history`,
|
||||||
|
listOrganizationLevelHistoryId: (id: string) =>
|
||||||
|
`${organizationLevel}history/${id}`,
|
||||||
|
listOrganizationLevelPublished: `${organizationLevel}history/published`,
|
||||||
|
listOrganizationLevelPublishedHistory: `${organizationLevel}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api สถานะ
|
||||||
|
*/
|
||||||
|
organizationStatus,
|
||||||
|
listOrganizationStatusHistory: `${organizationStatus}history`,
|
||||||
|
listOrganizationStatusHistoryId: (id: string) =>
|
||||||
|
`${organizationStatus}history/${id}`,
|
||||||
|
listOrganizationStatusPublished: `${organizationStatus}history/published`,
|
||||||
|
listOrganizationStatusPublishedHistory: `${organizationStatus}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api หน่วยงานต้นสังกัด
|
||||||
|
*/
|
||||||
|
organizationAgency,
|
||||||
|
listOrganizationAgencyHistory: `${organizationAgency}history`,
|
||||||
|
listOrganizationAgencyHistoryId: (id: string) =>
|
||||||
|
`${organizationAgency}history/${id}`,
|
||||||
|
listOrganizationAgencyPublished: `${organizationAgency}history/published`,
|
||||||
|
listOrganizationAgencyPublishedHistory: `${organizationAgency}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ส่วนราชการต้นสังกัด
|
||||||
|
*/
|
||||||
|
organizationGovernmentAgency,
|
||||||
|
listOrganizationGovernmentAgencyHistory: `${organizationGovernmentAgency}history`,
|
||||||
|
listOrganizationGovernmentAgencyHistoryId: (id: string) =>
|
||||||
|
`${organizationGovernmentAgency}history/${id}`,
|
||||||
|
listOrganizationGovernmentAgencyPublished: `${organizationGovernmentAgency}history/published`,
|
||||||
|
listOrganizationGovernmentAgencyPublishedHistory: `${organizationGovernmentAgency}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api เบอร์ติดต่อภายนอก
|
||||||
|
*/
|
||||||
|
organizationTelExternal,
|
||||||
|
listOrganizationTelExternalHistory: `${organizationTelExternal}history`,
|
||||||
|
listOrganizationTelExternalHistoryId: (id: string) =>
|
||||||
|
`${organizationTelExternal}history/${id}`,
|
||||||
|
listOrganizationTelExternalPublished: `${organizationTelExternal}history/published`,
|
||||||
|
listOrganizationTelExternalPublishedHistory: `${organizationTelExternal}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api เบอร์ติดต่อภายใน
|
||||||
|
*/
|
||||||
|
organizationTelInternal,
|
||||||
|
listOrganizationTelInternalHistory: `${organizationTelInternal}history`,
|
||||||
|
listOrganizationTelInternalHistoryId: (id: string) =>
|
||||||
|
`${organizationTelInternal}history/${id}`,
|
||||||
|
listOrganizationTelInternalPublished: `${organizationTelInternal}history/published`,
|
||||||
|
listOrganizationTelInternalPublishedHistory: `${organizationTelInternal}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api เบอร์โทรสาร
|
||||||
|
*/
|
||||||
|
organizationFax,
|
||||||
|
listOrganizationFaxHistory: `${organizationFax}history`,
|
||||||
|
listOrganizationFaxHistoryId: (id: string) =>
|
||||||
|
`${organizationFax}history/${id}`,
|
||||||
|
listOrganizationFaxPublished: `${organizationFax}history/published`,
|
||||||
|
listOrganizationFaxPublishedHistory: `${organizationFax}history/published-history`,
|
||||||
|
}
|
||||||
108
src/api/manage/api.person.ts
Normal file
108
src/api/manage/api.person.ts
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
/**
|
||||||
|
* api ระบบจัดการข้อมูลหลัก
|
||||||
|
* เมนูย่อย: ข้อมูลเกี่ยวกับบุคคล
|
||||||
|
*/
|
||||||
|
import env from "../index";
|
||||||
|
const person = `${env.API_URI}/metadata/main/`;
|
||||||
|
const province = `${env.API_URI}/metadata/province/`;
|
||||||
|
const district = `${env.API_URI}/metadata/district/`;
|
||||||
|
const subDistrict = `${env.API_URI}/metadata/sub-district/`;
|
||||||
|
const prefix = `${env.API_URI}/metadata/prefix/`;
|
||||||
|
const bloodGroup = `${env.API_URI}/metadata/blood-group/`;
|
||||||
|
const educationLevel = `${env.API_URI}/metadata/education-level/`;
|
||||||
|
const gender = `${env.API_URI}/metadata/gender/`;
|
||||||
|
const relationship = `${env.API_URI}/metadata/relationship/`;
|
||||||
|
const religion = `${env.API_URI}/metadata/religion/`;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
person: `${person}person`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api จังหวัด
|
||||||
|
*/
|
||||||
|
province,
|
||||||
|
listProvinceHistory: `${province}history`,
|
||||||
|
listProvinceHistoryId: (id: string) => `${province}history/${id}`,
|
||||||
|
listProvincePublished: `${province}history/published`,
|
||||||
|
listProvincePublishedHistory: `${province}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api เขต
|
||||||
|
*/
|
||||||
|
listDistrict: (id: string) => `${district}${id}`,
|
||||||
|
listDistrictHistory: `${district}history`,
|
||||||
|
listDistrictHistoryId: (id: string | string[]) => `${district}history/${id}`,
|
||||||
|
listDistrictPublishedId: (id: string) => `${district}history/published/${id}`,
|
||||||
|
listDistrictPublishedHistory: (id: string | string[]) =>
|
||||||
|
`${district}history/published-history/${id}`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api แขวง
|
||||||
|
*/
|
||||||
|
listSubDistrict: (id: string) => `${subDistrict}${id}`,
|
||||||
|
listSubDistrictHistory: `${subDistrict}history`,
|
||||||
|
listSubDistrictHistoryProvinceId: (
|
||||||
|
provinceId: string | string[],
|
||||||
|
district: string | string[]
|
||||||
|
) => `${subDistrict}history/${provinceId}/${district}`,
|
||||||
|
listSubDistrictHistoryId: (id: string | string[]) =>
|
||||||
|
`${subDistrict}history/${id}`,
|
||||||
|
listSubDistrictPublishedId: (id: string) =>
|
||||||
|
`${subDistrict}history/published/${id}`,
|
||||||
|
listSubDistrictPublishedHistory: (id: string | string[]) =>
|
||||||
|
`${subDistrict}history/published-history/${id}`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api คำนำหน้า
|
||||||
|
*/
|
||||||
|
prefix,
|
||||||
|
listPrefixHistory: `${prefix}history`,
|
||||||
|
listPrefixHistoryId: (id: string) => `${prefix}history/${id}`,
|
||||||
|
listPrefixPublished: `${prefix}history/published`,
|
||||||
|
listPrefixPublishedHistory: `${prefix}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api เพศ
|
||||||
|
*/
|
||||||
|
gender,
|
||||||
|
listGenderHistory: `${gender}history`,
|
||||||
|
listGenderHistoryId: (id: string) => `${gender}history/${id}`,
|
||||||
|
listGenderPublished: `${gender}history/published`,
|
||||||
|
listGenderPublishedHistory: `${gender}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api สถานภาพ
|
||||||
|
*/
|
||||||
|
relationship,
|
||||||
|
listRelationshipHistory: `${relationship}history`,
|
||||||
|
listRelationshipHistoryId: (id: string) => `${relationship}history/${id}`,
|
||||||
|
listRelationshipPublished: `${relationship}history/published`,
|
||||||
|
listRelationshipPublishedHistory: `${relationship}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api กลุ่มเลือด
|
||||||
|
*/
|
||||||
|
bloodGroup,
|
||||||
|
listBloodGroupHistory: `${bloodGroup}history`,
|
||||||
|
listBloodGroupHistoryId: (id: string) => `${bloodGroup}history/${id}`,
|
||||||
|
listBloodGroupPublished: `${bloodGroup}history/published`,
|
||||||
|
listBloodGroupPublishedHistory: `${bloodGroup}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ศาสนา
|
||||||
|
*/
|
||||||
|
religion,
|
||||||
|
listReligionHistory: `${religion}history`,
|
||||||
|
listReligionHistoryId: (id: string) => `${religion}history/${id}`,
|
||||||
|
listReligionPublished: `${religion}history/published`,
|
||||||
|
listReligionPublishedHistory: `${religion}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ระดับการศึกษา
|
||||||
|
*/
|
||||||
|
educationLevel,
|
||||||
|
listEducationLevelHistory: `${educationLevel}history`,
|
||||||
|
listEducationLevelHistoryId: (id: string) => `${educationLevel}history/${id}`,
|
||||||
|
listEducationLevelPublished: `${educationLevel}history/published`,
|
||||||
|
listEducationLevelPublishedHistory: `${educationLevel}history/published-history`,
|
||||||
|
};
|
||||||
98
src/api/manage/api.position.ts
Normal file
98
src/api/manage/api.position.ts
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
/**
|
||||||
|
* api ระบบจัดการข้อมูลหลัก
|
||||||
|
* เมนูย่อย: ข้อมูลตำแหน่งของข้าราชการกรุงเทพมหานคร
|
||||||
|
*/
|
||||||
|
import env from "../index";
|
||||||
|
const position = `${env.API_URI}/metadata/main/`;
|
||||||
|
const positionExecutiveSide = `${env.API_URI}/metadata/position-executive-side/`;
|
||||||
|
const positionLevel = `${env.API_URI}/metadata/position-level/`;
|
||||||
|
const positionPath = `${env.API_URI}/metadata/position-path/`;
|
||||||
|
const positionSide = `${env.API_URI}/metadata/position-path-side/`;
|
||||||
|
const positionType = `${env.API_URI}/metadata/position-type/`;
|
||||||
|
const positionStatus = `${env.API_URI}/metadata/position-status/`;
|
||||||
|
const positionLine = `${env.API_URI}/metadata/position-line/`;
|
||||||
|
const positionExecutive = `${env.API_URI}/metadata/position-executive/`;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
position: `${position}position`,
|
||||||
|
/**
|
||||||
|
* api ด้านทางการบริหาร
|
||||||
|
*/
|
||||||
|
positionExecutiveSide,
|
||||||
|
listPositionExecutiveSideHistory: `${positionExecutiveSide}history`,
|
||||||
|
listPositionExecutiveSideHistoryId: (id: string) =>
|
||||||
|
`${positionExecutiveSide}history/${id}`,
|
||||||
|
listPositionExecutiveSidePublished: `${positionExecutiveSide}history/published`,
|
||||||
|
listPositionExecutiveSidePublishedHistory: `${positionExecutiveSide}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ตำแหน่งในสายงาน
|
||||||
|
*/
|
||||||
|
// listPositionHistory: `${position}history`,
|
||||||
|
// listPositionHistoryId: (id: string) => `${position}history/${id}`,
|
||||||
|
// listPositionPublished: `${position}history/published`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ระดับตำแหน่ง
|
||||||
|
*/
|
||||||
|
positionLevel,
|
||||||
|
listPositionLevelHistory: `${positionLevel}history`,
|
||||||
|
listPositionLevelHistoryId: (id: string) => `${positionLevel}history/${id}`,
|
||||||
|
listPositionLevelPublished: `${positionLevel}history/published`,
|
||||||
|
listPositionLevelPublishedHistory: `${positionLevel}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ตำแหน่งในสายงาน
|
||||||
|
*/
|
||||||
|
positionPath,
|
||||||
|
listPositionPathHistory: `${positionPath}history`,
|
||||||
|
listPositionPathHistoryId: (id: string) => `${positionPath}history/${id}`,
|
||||||
|
listPositionPathPublished: `${positionPath}history/published`,
|
||||||
|
listPositionPathPublishedHistory: `${positionPath}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ด้าน/สาขา
|
||||||
|
*/
|
||||||
|
positionSide,
|
||||||
|
listPositionSideHistory: `${positionSide}history`,
|
||||||
|
listPositionSideHistoryId: (id: string) => `${positionSide}history/${id}`,
|
||||||
|
listPositionSidePublished: `${positionSide}history/published`,
|
||||||
|
listPositionSidePublishedHistory: `${positionSide}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ตำแหน่งประเภท
|
||||||
|
*/
|
||||||
|
positionType,
|
||||||
|
listPositionTypeHistory: `${positionType}history`,
|
||||||
|
listPositionTypeHistoryId: (id: string) => `${positionType}history/${id}`,
|
||||||
|
listPositionTypePublished: `${positionType}history/published`,
|
||||||
|
listPositionTypePublishedHistory: `${positionType}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api สถานะของตำแหน่ง
|
||||||
|
*/
|
||||||
|
positionStatus,
|
||||||
|
listPositionStatusHistory: `${positionStatus}history`,
|
||||||
|
listPositionStatusHistoryId: (id: string) => `${positionStatus}history/${id}`,
|
||||||
|
listPositionStatusPublished: `${positionStatus}history/published`,
|
||||||
|
listPositionStatusPublishedHistory: `${positionStatus}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api สายงานของตำแหน่ง
|
||||||
|
*/
|
||||||
|
positionLine,
|
||||||
|
listPositionLineHistory: `${positionLine}history`,
|
||||||
|
listPositionLineHistoryId: (id: string) => `${positionLine}history/${id}`,
|
||||||
|
listPositionLinePublished: `${positionLine}history/published`,
|
||||||
|
listPositionLinePublishedHistory: `${positionLine}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ตำแหน่งทางการบริหาร
|
||||||
|
*/
|
||||||
|
positionExecutive,
|
||||||
|
listPositionExecutiveHistory: `${positionExecutive}history`,
|
||||||
|
listPositionExecutiveHistoryId: (id: string) =>
|
||||||
|
`${positionExecutive}history/${id}`,
|
||||||
|
listPositionExecutivePublished: `${positionExecutive}history/published`,
|
||||||
|
listPositionExecutivePublishedHistory: `${positionExecutive}history/published-history`,
|
||||||
|
};
|
||||||
67
src/api/manage/api.positionEmployee.ts
Normal file
67
src/api/manage/api.positionEmployee.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* api ระบบจัดการข้อมูลหลัก
|
||||||
|
* เมนูย่อย: ข้อมูลตำแหน่งของลูกจ้างกรุงเทพมหานคร
|
||||||
|
*/
|
||||||
|
import env from "../index";
|
||||||
|
const positionEmployeePosition = `${env.API_URI}/metadata/position-employee-position/`;
|
||||||
|
const positionEmployeePositionSide = `${env.API_URI}/metadata/position-employee-position-side/`;
|
||||||
|
const positionEmployeeGroup = `${env.API_URI}/metadata/position-employee-group/`;
|
||||||
|
const positionEmployeeLine = `${env.API_URI}/metadata/position-employee-line/`;
|
||||||
|
const positionEmployeeLevel = `${env.API_URI}/metadata/position-employee-level/`;
|
||||||
|
const positionEmployeeStatus = `${env.API_URI}/metadata/position-employee-status/`;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
/**
|
||||||
|
* api ตำแหน่ง
|
||||||
|
*/
|
||||||
|
listPositionEmployeePositionHistory: `${positionEmployeePosition}history`,
|
||||||
|
listPositionEmployeePositionHistoryId: (id: string) =>
|
||||||
|
`${positionEmployeePosition}history/${id}`,
|
||||||
|
listPositionEmployeePositionPublished: `${positionEmployeePosition}history/published`,
|
||||||
|
listPositionEmployeePositionPublishedHistory: `${positionEmployeePosition}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ด้านของตำแหน่ง
|
||||||
|
*/
|
||||||
|
listPositionEmployeePositionSideHistory: `${positionEmployeePositionSide}history`,
|
||||||
|
listPositionEmployeePositionSideHistoryId: (id: string) =>
|
||||||
|
`${positionEmployeePositionSide}history/${id}`,
|
||||||
|
listPositionEmployeePositionSidePublished: `${positionEmployeePositionSide}history/published`,
|
||||||
|
listPositionEmployeePositionSidePublishedHistory: `${positionEmployeePositionSide}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api กลุ่มงาน
|
||||||
|
*/
|
||||||
|
listPositionEmployeeGroupHistory: `${positionEmployeeGroup}history`,
|
||||||
|
listPositionEmployeeGroupHistoryId: (id: string) =>
|
||||||
|
`${positionEmployeeGroup}history/${id}`,
|
||||||
|
listPositionEmployeeGroupPublished: `${positionEmployeeGroup}history/published`,
|
||||||
|
listPositionEmployeeGroupPublishedHistory: `${positionEmployeeGroup}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api สายงาน
|
||||||
|
*/
|
||||||
|
listPositionEmployeeLineHistory: `${positionEmployeeLine}history`,
|
||||||
|
listPositionEmployeeLineHistoryId: (id: string) =>
|
||||||
|
`${positionEmployeeLine}history/${id}`,
|
||||||
|
listPositionEmployeeLinePublished: `${positionEmployeeLine}history/published`,
|
||||||
|
listPositionEmployeeLinePublishedHistory: `${positionEmployeeLine}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api ระดับชั้นงาน
|
||||||
|
*/
|
||||||
|
listPositionEmployeeLevelHistory: `${positionEmployeeLevel}history`,
|
||||||
|
listPositionEmployeeLevelHistoryId: (id: string) =>
|
||||||
|
`${positionEmployeeLevel}history/${id}`,
|
||||||
|
listPositionEmployeeLevelPublished: `${positionEmployeeLevel}history/published`,
|
||||||
|
listPositionEmployeeLevelPublishedHistory: `${positionEmployeeLevel}history/published-history`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api สถานะของตำแหน่ง
|
||||||
|
*/
|
||||||
|
listPositionEmployeeStatusHistory: `${positionEmployeeStatus}history`,
|
||||||
|
listPositionEmployeeStatusHistoryId: (id: string) =>
|
||||||
|
`${positionEmployeeStatus}history/${id}`,
|
||||||
|
listPositionEmployeeStatusPublished: `${positionEmployeeStatus}history/published`,
|
||||||
|
listPositionEmployeeStatusPublishedHistory: `${positionEmployeeStatus}history/published-history`,
|
||||||
|
};
|
||||||
39
src/api/recruiting/api.disable.ts
Normal file
39
src/api/recruiting/api.disable.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
* api สรรหา
|
||||||
|
*/
|
||||||
|
import env from "../index"
|
||||||
|
const disableExam = `${env.API_CANDIDATE_URI}/candidate/disable-exam/`
|
||||||
|
const diable_report = `${env.API_URI}/report/exam/`
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getDisableCandidates: `${disableExam}candidate`,
|
||||||
|
saveDisableCandidates: `${disableExam}candidate`,
|
||||||
|
deleteDisableCandidates: (id: string) => `${disableExam}candidate/${id}`,
|
||||||
|
getDisableExamDetail: (id: string, examId: string) =>
|
||||||
|
`${disableExam}exam/${id}/${examId}`,
|
||||||
|
|
||||||
|
saveDisableScores: (id: string) => `${disableExam}score/${id}`,
|
||||||
|
|
||||||
|
getDisableExamResultById: (id: string) => `${disableExam}exam/${id}`,
|
||||||
|
|
||||||
|
// จัดการรอบการสอบ
|
||||||
|
saveDisablePeriod: `${disableExam}period`,
|
||||||
|
editDisablePeriod: (id: string) => `${disableExam}period/${id}`,
|
||||||
|
getDisablePeriodById: (id: string) => `${disableExam}period/${id}`,
|
||||||
|
uploadDisableCandidates: (id: string) => `${disableExam}candidate/${id}`,
|
||||||
|
getDisableImportHistory: (id: string) => `${disableExam}history/${id}`,
|
||||||
|
|
||||||
|
// รายงาน
|
||||||
|
downloadDisableExamReport: (id: string, examId: string, type: number = 2) =>
|
||||||
|
`${diable_report}certificate/${type}/${id}/${examId}`,
|
||||||
|
downloadDisableScoreReport: (id: string, examId: string) =>
|
||||||
|
`${diable_report}score/${id}/${examId}`,
|
||||||
|
exportDisableExam: (id: string) => `${disableExam}export/exam/${id}`,
|
||||||
|
exportDisablePassExam: (id: string) => `${disableExam}export/pass-exam/${id}`,
|
||||||
|
exportDisablePassResultExam: (id: string) =>
|
||||||
|
`${disableExam}export/pass/${id}`,
|
||||||
|
|
||||||
|
exportDisableCandidateList: (id: string) => `${diable_report}candidate/${id}`,
|
||||||
|
exportDisablePassExamList: (id: string) => `${diable_report}pass/${id}`,
|
||||||
|
|
||||||
|
}
|
||||||
85
src/api/recruiting/api.period-exam.ts
Normal file
85
src/api/recruiting/api.period-exam.ts
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
/**
|
||||||
|
* api สรรหา
|
||||||
|
*/
|
||||||
|
import env from "../index"
|
||||||
|
const candidate = `${env.API_CANDIDATE_URI}/candidate/`
|
||||||
|
const periodExam = `${env.API_CANDIDATE_URI}/candidate/period-exam/`
|
||||||
|
const exam_report = `${env.API_URI}/report/exam/`
|
||||||
|
|
||||||
|
const cms = `${env.API_CANDIDATE_URI}/cms/`
|
||||||
|
|
||||||
|
export default {
|
||||||
|
/**
|
||||||
|
* api cms
|
||||||
|
*/
|
||||||
|
cms,
|
||||||
|
cmsDeatail: `${cms}detail`,
|
||||||
|
cmsAbout: `${cms}about`,
|
||||||
|
cmsLogo: `${cms}logo`,
|
||||||
|
cmsBanner: `${cms}banner`,
|
||||||
|
cmsAgency: `${cms}agency`,
|
||||||
|
cmsGoverment: `${cms}government`,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api รอบการสอบ
|
||||||
|
*/
|
||||||
|
periodExam: `${periodExam}`,
|
||||||
|
periodExamType: (type: string) => `${periodExam}type/${type}`,
|
||||||
|
periodExamId: (examId: string) => `${periodExam}${examId}`,
|
||||||
|
periodExamDoc: (examId: string) => `${periodExam}doc/${examId}`,
|
||||||
|
periodExamImg: (examId: string) => `${periodExam}img/${examId}`,
|
||||||
|
periodExamStatus: (examId: string) => `${periodExam}status-payment/${examId}`,
|
||||||
|
|
||||||
|
countDashbordPeriodExam: (examId: string) =>
|
||||||
|
`${periodExam}dashboard/${examId}`,
|
||||||
|
|
||||||
|
candidateId: (candidateId: string) => `${candidate}${candidateId}`,
|
||||||
|
candidateInformation: (candidateId: string) =>
|
||||||
|
`${periodExam}information/${candidateId}`,
|
||||||
|
candidateAddress: (candidateId: string) =>
|
||||||
|
`${periodExam}address/${candidateId}`,
|
||||||
|
candidateFamily: (candidateId: string) =>
|
||||||
|
`${periodExam}family/${candidateId}`,
|
||||||
|
candidateOccupation: (candidateId: string) =>
|
||||||
|
`${periodExam}occupation/${candidateId}`,
|
||||||
|
candidateEducation: (candidateId: string) =>
|
||||||
|
`${periodExam}education/${candidateId}`,
|
||||||
|
candidateAdminEducation: (candidateId: string) =>
|
||||||
|
`${candidate}education/${candidateId}`,
|
||||||
|
candidateDocument: (candidateId: string) =>
|
||||||
|
`${periodExam}document/${candidateId}`,
|
||||||
|
candidateCareer: (candidateId: string) =>
|
||||||
|
`${periodExam}career/${candidateId}`,
|
||||||
|
candidateAdminCareer: (candidateId: string) =>
|
||||||
|
`${candidate}career/${candidateId}`,
|
||||||
|
candidateProfile: (candidateId: string) =>
|
||||||
|
`${candidate}profile-image/${candidateId}`,
|
||||||
|
candidateUpload: (candidateId: string) => `${candidate}upload/${candidateId}`,
|
||||||
|
candidateCheckRegister: (candidateId: string) =>
|
||||||
|
`${candidate}check-register/${candidateId}`,
|
||||||
|
candidateRejectRegister: (candidateId: string) =>
|
||||||
|
`${candidate}reject-register/${candidateId}`,
|
||||||
|
candidateCheckPayment: (candidateId: string) =>
|
||||||
|
`${candidate}check-payment/${candidateId}`,
|
||||||
|
candidate,
|
||||||
|
candidateOfPeriodExam: (status: string, examId: string) =>
|
||||||
|
`${periodExam}${status}/${examId}`,
|
||||||
|
candidateCard: (candidateId: string) => `${candidate}card/${candidateId}`,
|
||||||
|
|
||||||
|
periodExamUploadSeat: (examId: string) =>
|
||||||
|
`${periodExam}upload-seat/${examId}`,
|
||||||
|
periodExamUploadPoint: (examId: string) =>
|
||||||
|
`${periodExam}upload-point/${examId}`,
|
||||||
|
periodExamDownload: (examId: string) => `${periodExam}download/${examId}`,
|
||||||
|
periodExamDownloadDetail: (examId: string) =>
|
||||||
|
`${periodExam}download/detail/${examId}`,
|
||||||
|
periodExamDownloadDashboard: (examId: string) =>
|
||||||
|
`${periodExam}download/dashboard/${examId}`,
|
||||||
|
candidatePayment: (candidateId: string) =>
|
||||||
|
`${candidate}payment-image/${candidateId}`,
|
||||||
|
periodExamPayment: (examId: string) => `${periodExam}payment/${examId}`,
|
||||||
|
|
||||||
|
|
||||||
|
exportExamCandidateList: (id: string) => `${exam_report}candidate-exam/${id}`,
|
||||||
|
exportExamPassExamList: (id: string) => `${exam_report}pass-exam/${id}`,
|
||||||
|
}
|
||||||
41
src/api/recruiting/api.recruit.ts
Normal file
41
src/api/recruiting/api.recruit.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* api สรรหา - สอบแข่งขัน
|
||||||
|
*/
|
||||||
|
import env from "../index"
|
||||||
|
const recruit = `${env.API_URI}/recruit/`
|
||||||
|
const recruit_report = `${env.API_URI}/report/recruit/`
|
||||||
|
|
||||||
|
export default {
|
||||||
|
getCandidates: `${recruit}candidate`,
|
||||||
|
saveCandidates: `${recruit}candidate`,
|
||||||
|
deleteCandidates: (id: string) => `${recruit}candidate/${id}`,
|
||||||
|
getExamDetail: (id: string, examId: string) => `${recruit}exam/${id}/${examId}`,
|
||||||
|
|
||||||
|
saveScores: (id: string) => `${recruit}score/${id}`,
|
||||||
|
|
||||||
|
getExamResultById: (id: string) => `${recruit}exam/${id}`,
|
||||||
|
|
||||||
|
// จัดการรอบการสอบ
|
||||||
|
savePeriod: `${recruit}period`,
|
||||||
|
editPeriod: (id: string) => `${recruit}period/${id}`,
|
||||||
|
getPeriodById: (id: string) => `${recruit}period/${id}`,
|
||||||
|
uploadCandidates: (id: string) => `${recruit}candidate/${id}`,
|
||||||
|
getImportHistory: (id: string) => `${recruit}history/${id}`,
|
||||||
|
|
||||||
|
//upload
|
||||||
|
periodRecruitDoc: (examId: string) => `${recruit}doc/${examId}`,
|
||||||
|
periodRecruitImg: (examId: string) => `${recruit}img/${examId}`,
|
||||||
|
periodDeleteDoc: (docId: string) => `${recruit}doc/${docId}`,
|
||||||
|
periodDeleteImg: (docId: string) => `${recruit}img/${docId}`,
|
||||||
|
|
||||||
|
// รายงาน
|
||||||
|
downloadExamReport: (id: string, examId: string, type: number = 2) => `${recruit_report}certificate/${type}/${id}/${examId}`,
|
||||||
|
downloadScoreReport: (id: string, examId: string) => `${recruit_report}score/${id}/${examId}`,
|
||||||
|
exportExam: (id: string) => `${recruit}export/exam/${id}`,
|
||||||
|
exportPassExam: (id: string) => `${recruit}export/pass-exam/${id}`,
|
||||||
|
exportPassResultExam: (id: string) => `${recruit}export/pass/${id}`,
|
||||||
|
|
||||||
|
exportCandidateList: (id: string) => `${recruit_report}candidate/${id}`,
|
||||||
|
exportPassExamList: (id: string) => `${recruit_report}pass/${id}`,
|
||||||
|
|
||||||
|
}
|
||||||
12
src/api/recruiting/api.report2.ts
Normal file
12
src/api/recruiting/api.report2.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
import env from "../index";
|
||||||
|
const report2 = `${env.API_URI_ORG_SERVICE}/report2/`;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
report2Id: (id: string) => `${report2}${id}`,
|
||||||
|
report2TreeId: (organizationId: string) => `${report2}tree/${organizationId}`,
|
||||||
|
report2DoneId: (organizationId: string) => `${report2}done/${organizationId}`,
|
||||||
|
report2HistoryId: (organizationId: string) =>
|
||||||
|
`${report2}history/${organizationId}`,
|
||||||
|
report2HistoryDetailId: (historyId: string) =>
|
||||||
|
`${report2}history/detail/${historyId}`,
|
||||||
|
};
|
||||||
161
src/api/registry/api.profile.ts
Normal file
161
src/api/registry/api.profile.ts
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
/**
|
||||||
|
* api สรรหา - สอบแข่งขัน
|
||||||
|
*/
|
||||||
|
import env from "../index";
|
||||||
|
const profile = `${env.API_URI_PROFILE_SERVICE}/profile/`;
|
||||||
|
const report = `${env.API_REPORT_URI}/report/profile/`;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
profileUser: `${profile}user`,
|
||||||
|
profileValidateId: (profileId: string) => `${profile}validate/${profileId}`,
|
||||||
|
profilePaperDownloadId: (id: string) => `${profile}paper/download/${id}`,
|
||||||
|
profilePaperId: (id: string) => `${profile}paper/${id}`,
|
||||||
|
|
||||||
|
profileMultiId: (id: string) => `${profile}multi-paper/${id}`,
|
||||||
|
profileMultiOId: (id: string) => `${profile}multi-paper-other/${id}`,
|
||||||
|
profileMultiKId: (id: string) => `${profile}multi-paper-kk1/${id}`,
|
||||||
|
|
||||||
|
profileHistoryselfId: (profileId: string) =>
|
||||||
|
`${profile}/historyself${profileId}`,
|
||||||
|
|
||||||
|
profileOrganiNameId: (id: string) => `${profile}organization/name/${id}`,
|
||||||
|
profileOrganiId: (id: string) => `${profile}organization/${id}`,
|
||||||
|
profileOrganiSelectId: (id: string) => `${profile}organization/select/${id}`,
|
||||||
|
profileOrganiRootId: (id: string) => `${profile}organization/root/${id}`,
|
||||||
|
|
||||||
|
profileLeaveOrganiId: (id: string) => `${profile}leave/organization/${id}`,
|
||||||
|
|
||||||
|
profileSearchNewOcId: (id: string) => `${profile}search/new/oc/${id}`,
|
||||||
|
profileSearchNewOcIdType: (id: string, type: string) =>
|
||||||
|
`${profile}search/new/oc/${id}/${type}`,
|
||||||
|
profileSearchId: (id: string) => `${profile}search/${id}`,
|
||||||
|
profileSearchOcId: (id: string) => `${profile}search/oc/${id}`,
|
||||||
|
profileSearchNewOcLeaveId: (id: string) =>
|
||||||
|
`${profile}search/new/oc/leave/${id}`,
|
||||||
|
profileSearchNewOcLeaveIdType: (id: string, type: string) =>
|
||||||
|
`${profile}search/new/oc/leave/${id}/${type}`,
|
||||||
|
profileSearchOcLeaveId: (id: string) => `${profile}search/oc/leave/${id}`,
|
||||||
|
profileSearchNewEmOcId: (id: string) =>
|
||||||
|
`${profile}search/new-employee/oc/${id}`,
|
||||||
|
profileSearchNewEmOcLeaveId: (id: string) =>
|
||||||
|
`${profile}search/new-employee/oc/leave/${id}`,
|
||||||
|
|
||||||
|
profileCoupleId: (profileId: string) => `${profile}couple/${profileId}`,
|
||||||
|
|
||||||
|
profileFatherId: (profileId: string) => `${profile}father/${profileId}`,
|
||||||
|
|
||||||
|
profileMotherId: (profileId: string) => `${profile}mother/${profileId}`,
|
||||||
|
|
||||||
|
profileAdsId: (profileId: string) => `${profile}address/current/${profileId}`,
|
||||||
|
profileAdsCurAdrsId: (profileId: string) =>
|
||||||
|
`${profile}address/currentAdrs/${profileId}`,
|
||||||
|
profileAdsRegisId: (profileId: string) =>
|
||||||
|
`${profile}address/registration/${profileId}`,
|
||||||
|
|
||||||
|
profileInsignId: (profileId: string) => `${profile}insignia/${profileId}`,
|
||||||
|
profileInsignHisId: (profileId: string) =>
|
||||||
|
`${profile}insignia/history/${profileId}`,
|
||||||
|
profileInsignInsignId: (profileId: string) =>
|
||||||
|
`${profile}insignia/insigniadiocesan/${profileId}`,
|
||||||
|
profileInsignToolList: `${profile}insignia/tool/list`,
|
||||||
|
|
||||||
|
profileChildId: (profileId: string) => `${profile}children/${profileId}`,
|
||||||
|
|
||||||
|
profileAssessmentId: (profileId: string) =>
|
||||||
|
`${profile}assessment/${profileId}`,
|
||||||
|
profileAssessmentHisId: (profileId: string) =>
|
||||||
|
`${profile}assessment/history/${profileId}`,
|
||||||
|
|
||||||
|
profileHonorId: (profileId: string) => `${profile}honor/${profileId}`,
|
||||||
|
profileHonorHisId: (profileId: string) =>
|
||||||
|
`${profile}honor/history/${profileId}`,
|
||||||
|
|
||||||
|
profileCertId: (profileId: string) => `${profile}certificate/${profileId}`,
|
||||||
|
profileCertHisId: (profileId: string) =>
|
||||||
|
`${profile}certificate/history/${profileId}`,
|
||||||
|
|
||||||
|
profileAbiliId: (profileId: string) => `${profile}ability/${profileId}`,
|
||||||
|
profileAbiliHisId: (profileId: string) =>
|
||||||
|
`${profile}ability/history/${profileId}`,
|
||||||
|
|
||||||
|
profileDutyId: (profileId: string) => `${profile}duty/${profileId}`,
|
||||||
|
profileDutyHisId: (profileId: string) =>
|
||||||
|
`${profile}duty/history/${profileId}`,
|
||||||
|
|
||||||
|
profileOtherId: (profileId: string) => `${profile}other/${profileId}`,
|
||||||
|
profileOtherHisId: (profileId: string) =>
|
||||||
|
`${profile}other/history/${profileId}`,
|
||||||
|
|
||||||
|
profileNopaidId: (profileId: string) => `${profile}nopaid/${profileId}`,
|
||||||
|
profileNopaidHisId: (profileId: string) =>
|
||||||
|
`${profile}nopaid/history/${profileId}`,
|
||||||
|
|
||||||
|
profileAvaId: (profileId: string) => `${profile}avatar/${profileId}`,
|
||||||
|
profileAvaCurId: (profileId: string) =>
|
||||||
|
`${profile}avatar/current/${profileId}`,
|
||||||
|
|
||||||
|
profileEduId: (profileId: string) => `${profile}education/${profileId}`,
|
||||||
|
profileEduHisId: (profileId: string) =>
|
||||||
|
`${profile}education/history/${profileId}`,
|
||||||
|
|
||||||
|
profileSwapEducation: `${profile}swap_education`,
|
||||||
|
|
||||||
|
profileTrainId: (profileId: string) => `${profile}training/${profileId}`,
|
||||||
|
profileTrainHisId: (profileId: string) =>
|
||||||
|
`${profile}training/history/${profileId}`,
|
||||||
|
|
||||||
|
profileDisId: (profileId: string) => `${profile}discipline/${profileId}`,
|
||||||
|
profileDisHisId: (profileId: string) =>
|
||||||
|
`${profile}discipline/history/${profileId}`,
|
||||||
|
|
||||||
|
profileSwapDiscipline: `${profile}swap_discipline`,
|
||||||
|
|
||||||
|
profileLeaveId: (profileId: string) => `${profile}leave/${profileId}`,
|
||||||
|
profileLeaveHisId: (profileId: string) =>
|
||||||
|
`${profile}leave/history/${profileId}`,
|
||||||
|
|
||||||
|
profileSalaryId: (profileId: string) => `${profile}salary/${profileId}`,
|
||||||
|
profileSalaryHisId: (profileId: string) =>
|
||||||
|
`${profile}salary/history/${profileId}`,
|
||||||
|
profileSalarySwapId: (id: string, direction: string) =>
|
||||||
|
`${profile}salary/swap/${id}/${direction}`,
|
||||||
|
profileSalaryCopyId: (profileId: string) =>
|
||||||
|
`${profile}salary-copy/${profileId}`,
|
||||||
|
|
||||||
|
profileInforId: (profileId: string) => `${profile}information/${profileId}`,
|
||||||
|
profileInforHisId: (profileId: string) =>
|
||||||
|
`${profile}information/history/${profileId}`,
|
||||||
|
|
||||||
|
profileGovId: (profileId: string) => `${profile}government/${profileId}`,
|
||||||
|
profileGovHisId: (profileId: string) =>
|
||||||
|
`${profile}government/history/${profileId}`,
|
||||||
|
|
||||||
|
profileCalGovId: (profileId: string) => `${profile}cal/gov/${profileId}`,
|
||||||
|
|
||||||
|
profileFamiId: (profileId: string) => `${profile}family/${profileId}`,
|
||||||
|
profileFamiHisId: (profileId: string) =>
|
||||||
|
`${profile}family/history/${profileId}`,
|
||||||
|
|
||||||
|
profileAdrsId: (profileId: string) => `${profile}address/${profileId}`,
|
||||||
|
profileAdrsHisId: (profileId: string) =>
|
||||||
|
`${profile}address/history/${profileId}`,
|
||||||
|
searchProfileByOcId: (OcId: string, type: string) =>
|
||||||
|
`${profile}search/new/oc/${OcId}/${type}`,
|
||||||
|
|
||||||
|
profileAvatarId: (profileId: string) => `${profile}avatar/${profileId}`,
|
||||||
|
profileAvatarHistoryId: (profileId: string) =>
|
||||||
|
`${profile}avatar/history/${profileId}`,
|
||||||
|
|
||||||
|
profileCheckId: (profileId: string) => `${profile}check/${profileId}`,
|
||||||
|
|
||||||
|
profileOrganizRoot: `${profile}organization/root`,
|
||||||
|
|
||||||
|
profileCalRetire: `${profile}cal/retire`,
|
||||||
|
profilePositionNumber: `${profile}position-number`,
|
||||||
|
organizationName: (ocId: string) => `${profile}organization/${ocId}`,
|
||||||
|
profileDeactive: (profileId: string) => `${profile}deactive/${profileId}`,
|
||||||
|
profileReactive: (profileId: string) => `${profile}reactive/${profileId}`,
|
||||||
|
|
||||||
|
profileReportId: (profileId: string) => `${report}kk1/${profileId}`,
|
||||||
|
profileKp7ShortId: (profileId: string) => `${report}kp7-short/${profileId}`,
|
||||||
|
};
|
||||||
83
src/app.config.ts
Normal file
83
src/app.config.ts
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
/**ใช้รวมไฟล์ย่อยๆ ของ api แต่ละไฟล์ */
|
||||||
|
|
||||||
|
/** API Metadata */
|
||||||
|
import manageOrganization from "./api/manage/api.organization";
|
||||||
|
import managePerson from "./api/manage/api.person";
|
||||||
|
import managePosition from "./api/manage/api.position";
|
||||||
|
import managePositionEmployee from "./api/manage/api.positionEmployee";
|
||||||
|
import manageInsignia from "./api/manage/api.insignia";
|
||||||
|
import manageHoliday from "./api/manage/api.holiday";
|
||||||
|
|
||||||
|
/** API Tree List */
|
||||||
|
import organizationTreeList from "./api/02_organizational/api.treelist";
|
||||||
|
|
||||||
|
/** API Structure & Org Chart */
|
||||||
|
import organizationChart from "./api/02_organizational/api.chart";
|
||||||
|
|
||||||
|
/** API periodexam List */
|
||||||
|
import periodexam from "./api/recruiting/api.period-exam";
|
||||||
|
import disableexam from "./api/recruiting/api.disable";
|
||||||
|
|
||||||
|
/** API Recruit List */
|
||||||
|
import recruit from "./api/recruiting/api.recruit";
|
||||||
|
|
||||||
|
/** API Profile List */
|
||||||
|
import profile from "./api/registry/api.profile";
|
||||||
|
|
||||||
|
/** API Report2 List */
|
||||||
|
import report2 from "./api/recruiting/api.report2";
|
||||||
|
|
||||||
|
/** API ระบบการบรรจุ แต่งตั้ง ย้าย โอน List */
|
||||||
|
import placement from "./api/05_placement/api.placement";
|
||||||
|
|
||||||
|
/** API ระบบการพ้นจากราชการ List */
|
||||||
|
import retirement from "./api/06_retirement/api.retirement";
|
||||||
|
|
||||||
|
/** API ระบบงานเครื่องราชอิสริยาภรณ์ List */
|
||||||
|
import insignia from "./api/07_insignia/api.insignia";
|
||||||
|
|
||||||
|
// environment variables
|
||||||
|
export const compettitivePanel = import.meta.env.VITE_COMPETITIVE_EXAM_PANEL;
|
||||||
|
export const qualifyDisableExamPanel = import.meta.env
|
||||||
|
.VITE_QUALIFY_DISABLE_EMAM_PANEL;
|
||||||
|
export const qualifyExamPanel = import.meta.env.VITE_QUALIFY_EXAM_PANEL;
|
||||||
|
export const s3ClusterUrl = import.meta.env.VITE_S3CLUSTER_PUBLIC_URL;
|
||||||
|
|
||||||
|
const API = {
|
||||||
|
//Metadata
|
||||||
|
...manageOrganization,
|
||||||
|
...managePerson,
|
||||||
|
...managePosition,
|
||||||
|
...managePositionEmployee,
|
||||||
|
...manageInsignia,
|
||||||
|
...manageHoliday,
|
||||||
|
|
||||||
|
//Tree List
|
||||||
|
...organizationTreeList,
|
||||||
|
...organizationChart,
|
||||||
|
|
||||||
|
//periodexam
|
||||||
|
...periodexam,
|
||||||
|
...disableexam,
|
||||||
|
|
||||||
|
// recruit
|
||||||
|
...recruit,
|
||||||
|
|
||||||
|
//profile
|
||||||
|
...profile,
|
||||||
|
|
||||||
|
//report2
|
||||||
|
...report2,
|
||||||
|
|
||||||
|
...placement,
|
||||||
|
...retirement,
|
||||||
|
...insignia,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
API: API,
|
||||||
|
compettitivePanel,
|
||||||
|
qualifyDisableExamPanel,
|
||||||
|
qualifyExamPanel,
|
||||||
|
s3ClusterUrl,
|
||||||
|
};
|
||||||
BIN
src/assets/avatar_user.jpg
Normal file
BIN
src/assets/avatar_user.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
0
src/assets/base.css
Normal file
0
src/assets/base.css
Normal file
BIN
src/assets/ex_slip.jpeg
Normal file
BIN
src/assets/ex_slip.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
BIN
src/assets/krungthai.png
Normal file
BIN
src/assets/krungthai.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 156 KiB |
BIN
src/assets/logo.png
Normal file
BIN
src/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
1
src/assets/logo.svg
Normal file
1
src/assets/logo.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69" xmlns:v="https://vecta.io/nano"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
|
||||||
|
After Width: | Height: | Size: 308 B |
35
src/assets/main.css
Normal file
35
src/assets/main.css
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
/* @import './base.css'; */
|
||||||
|
|
||||||
|
/* #app {
|
||||||
|
max-width: 1280px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 2rem;
|
||||||
|
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
a,
|
||||||
|
.green {
|
||||||
|
text-decoration: none;
|
||||||
|
color: hsla(160, 100%, 37%, 1);
|
||||||
|
transition: 0.4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (hover: hover) {
|
||||||
|
a:hover {
|
||||||
|
background-color: hsla(160, 100%, 37%, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
place-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
padding: 0 2rem;
|
||||||
|
}
|
||||||
|
} */
|
||||||
11
src/assets/orgChartData.ts
Normal file
11
src/assets/orgChartData.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
const chartData = {
|
||||||
|
personID: "", // Unique ID เป็นเลข ID ที่อ้างอิงไปที่ตัวบุคคล
|
||||||
|
name: "-", // ขื่อบุคคล
|
||||||
|
positionName: "-", // ชื่อตำแหน่ง
|
||||||
|
positionNum: "", // เลขที่ประจำตำแหน่งในโครงสร้าง
|
||||||
|
departmentName: "", // ชื่อหน่วยงานที่สังกัด
|
||||||
|
avatar: "", // ภาพถ่าย
|
||||||
|
children: [], // บุคคลอื่น ๆ ที่อยู่ภายใต้คนนี้ มีโครงสร้างเหมือนกัน
|
||||||
|
};
|
||||||
|
|
||||||
|
export default chartData;
|
||||||
272
src/assets/structChartData.ts
Normal file
272
src/assets/structChartData.ts
Normal file
|
|
@ -0,0 +1,272 @@
|
||||||
|
/**
|
||||||
|
* ข้อมูลจะเริ่มต้นที่ Root ที่มีเพียงอันเดียว แล้วแตกรากลงมา ชื่อฟิลด์ต่าง ๆ จะพยายามให้เหมือนกับ TreeList ฟิลด์ไหนใช้ชื่อต่างกันก็ระบุมาได้นะว่าใน TreeList ใช้อะไร จะได้ใช้ให้เหมือนกัน
|
||||||
|
* - Object ส่วนที่เป็นหน่วยงานประกอบด้วย
|
||||||
|
* - deptID : Unique ID ของสำนัก/ฝ่าย/กอง เป็น Int หรือ String ก็ได้ ขอแค่ระบุให้ชัด
|
||||||
|
* - departmentName : ชื่อสำนัก/ฝ่าย/กอง
|
||||||
|
* - totalPositionCount : จำนวนตำแหน่งทั้งหมดในหน่วยงาน หรือในส่วนงานย่อย
|
||||||
|
* - totalPositionVacant : จำนวนตำแหน่งว่างทั้งหมดในหน่วยงาน
|
||||||
|
* - นอกจากนั้นในแต่ละหน่วยงานยังมี Object ได้อีก 3 แบบคือ
|
||||||
|
* - heads : เป็น Array ของ Object ที่เก็บตำแหน่งระดับหัวหน้า
|
||||||
|
* - offcier : เป็น Array ของ Object ที่เก็บตำแหน่งระดับเจ้าหน้าที่
|
||||||
|
* - children : เป็น Array ของหน่วยงานย่อย ซึ่ง Root ของ children ต้องเป็น Object ของหน่วยงานเสมอ
|
||||||
|
* - Object ส่วนที่เป็นตำแหน่งประกอบด้วย
|
||||||
|
* - positionID : Unique ID ของประเภทตำแหน่งนั้น เงื่อนไขเหมือน deptID
|
||||||
|
* - positionName : ชื่อตำแหน่ง
|
||||||
|
* - positionNum : เลขที่ประจำตำแหน่ง เช่น กทข.
|
||||||
|
* - totalPositionCount : จำนวนตำแหน่งทั้งหมด
|
||||||
|
* - totalPositionVacant : จำนวนตำแหน่งว่างทั้งหมด
|
||||||
|
*/
|
||||||
|
const chartData = { // root ของข้อมูลเป็น Object (ไม่ใช่ Array แบบ TreeList)
|
||||||
|
deptID: 1, // Unique ID ของสำนัก/ฝ่าย/กอง (ถ้ามี?)
|
||||||
|
departmentName: "สำนักงานเลขานุการผู้ว่าราชการกรุงเทพมหานคร", // ชื่อสำนัก/ฝ่าย/กอง
|
||||||
|
totalPositionCount: 75, // จำนวนตำแหน่งทั้งหมดในหน่วยงาน
|
||||||
|
totalPositionVacant: 2, // จำนวนตำแหน่งว่างทั้งหมดในหน่วยงาน
|
||||||
|
heads: [ // Array ของผู้บริหารในหน่วยงานนั้น ๆ (ผู้อำนวยการ/หัวหน้า)
|
||||||
|
{
|
||||||
|
positionID: 2, // Unique ID ของประเภทตำแหน่งนั้น (ถ้ามี?)
|
||||||
|
positionName: "ผู้อำนวยการสูง", // ชื่อตำแหน่ง
|
||||||
|
positionNum: "(หัวหน้าสำนักงาน)", // เลขที่ประจำตำแหน่ง (ถ้ามี) เช่นพวก กทข.
|
||||||
|
totalPositionCount: 1, // จำนวนตำแหน่งทั้งหมด
|
||||||
|
totalPositionVacant: 0 // จำนวนตำแหน่งว่างทั้งหมด
|
||||||
|
}
|
||||||
|
],
|
||||||
|
officer: [ // Array ของเจ้าหน้าที่ในหน่วยงาน (รายการตำแหน่งในหน่วยงานที่ขึ้นตรงกับ deptID นั้น ๆ)
|
||||||
|
],
|
||||||
|
children: [ // Array ของหน่วยงานย่อย เช่น ฝ่าย กอง
|
||||||
|
{ // โครงสร้างที่เหลือจะเหมือนกับส่วน Root ทุกอย่าง คือแต่ละหน่วยงานย่อย มี heads ไว้ระบุหัวหน้า ผู้อำนวยการ มี Officer ไว้ระบุรายการตำแหน่งในหน่วยงาน มี Children ไว้ระบุหน่วยงานย่อย
|
||||||
|
deptID: 3,
|
||||||
|
departmentName: "ฝ่ายบริหารทั่วไป",
|
||||||
|
totalPositionCount: 14,
|
||||||
|
totalPositionVacant: 0,
|
||||||
|
heads: [
|
||||||
|
{
|
||||||
|
positionID: 2,
|
||||||
|
positionName: "นักจัดการงานทั่วไป",
|
||||||
|
positionNum: "ชพ. (หัวหน้าฝ่าย)",
|
||||||
|
totalPositionCount: 1,
|
||||||
|
totalPositionVacant: 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
officer: [
|
||||||
|
{
|
||||||
|
positionID: 3,
|
||||||
|
positionName: "นักจัดการงานทั่วไป",
|
||||||
|
positionNum: "ปก./ชก",
|
||||||
|
totalPositionCount: 1,
|
||||||
|
totalPositionVacant: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
positionID: 4,
|
||||||
|
positionName: "นักทรัพยากรบุคคล",
|
||||||
|
positionNum: "ปก./ชก.",
|
||||||
|
totalPositionCount: 1,
|
||||||
|
totalPositionVacnt: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
positionID: 5,
|
||||||
|
positionName: "นักวิชาการเงินและบัญชี",
|
||||||
|
positionNum: "ปก./ชก.",
|
||||||
|
totalPositionCount: 2,
|
||||||
|
totalPositionVacnt: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
positionID: 6,
|
||||||
|
positionName: "นักวิชาการพัสดุ",
|
||||||
|
positionNum: "ปก./ชก.",
|
||||||
|
totalPositionCount: 1,
|
||||||
|
totalPositionVacnt: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
positionID: 7,
|
||||||
|
positionName: "เจ้าพนักงานการเงินและบัญชี",
|
||||||
|
positionNum: "ปง./ชง.",
|
||||||
|
totalPositionCount: 3,
|
||||||
|
totalPositionVacnt: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
positionID: 8,
|
||||||
|
positionName: "เจ้าพนักงานพัสดุ",
|
||||||
|
positionNum: "ปง./ชง.",
|
||||||
|
totalPositionCount: 1,
|
||||||
|
totalPositionVacnt: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
positionID: 9,
|
||||||
|
positionName: "เจ้าพนักงานธุรการ",
|
||||||
|
positionNum: "ปง./ชง.",
|
||||||
|
totalPositionCount: 4,
|
||||||
|
totalPositionVacnt: 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deptID: 4,
|
||||||
|
departmentName: "ส่วนประสานนโยบาย",
|
||||||
|
totalPositionCount: 15,
|
||||||
|
totalPositionVacant: 0,
|
||||||
|
heads: [
|
||||||
|
{
|
||||||
|
positionID: 10,
|
||||||
|
positionName: "ผู้อำนวยการต้น",
|
||||||
|
positionNum: "(ผู้อำนวยการส่วน)",
|
||||||
|
totalPositionCount: 1,
|
||||||
|
totalPositionVacant: 0,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
deptID: 11,
|
||||||
|
departmentName: "กลุ่มงานประชุม",
|
||||||
|
totalPositionCount: 6,
|
||||||
|
totalPositionVacant: 0,
|
||||||
|
heads: [
|
||||||
|
{
|
||||||
|
positionID: 11,
|
||||||
|
positionName: "นักจัดการงานทั่วไป",
|
||||||
|
positionNum: "ชพ. (หัวหน้ากลุ่มงาน)",
|
||||||
|
totalPositionCount: 1,
|
||||||
|
totalPositionVacant: 0,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
officer: [
|
||||||
|
{
|
||||||
|
positionID: 12,
|
||||||
|
positionName: "นักจัดการงานทั่วไป",
|
||||||
|
positionNum: "ปก./ชก.",
|
||||||
|
totalPositionCount: 4,
|
||||||
|
totalPositionVacant: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
positionID: 13,
|
||||||
|
positionName: "เจ้าพนักงานธุรการ",
|
||||||
|
positionNum: "ปง./ชง.",
|
||||||
|
totalPositionCount: 1,
|
||||||
|
totalPositionVacant: 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deptID: 12,
|
||||||
|
departmentName: "กลุ่มงานการเมืองและประสานนโยบาย",
|
||||||
|
totalPositionCount: 8,
|
||||||
|
totalPositionVacant: 0,
|
||||||
|
heads: [
|
||||||
|
{
|
||||||
|
positionID: 14,
|
||||||
|
positionName: "นักจัดการงานทั่วไป",
|
||||||
|
positionNum: "ชพ. (หัวหน้ากลุ่มงาน)",
|
||||||
|
totalPositionCount: 1,
|
||||||
|
totalPositionVacant: 0,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
officer: [
|
||||||
|
{
|
||||||
|
positionID: 15,
|
||||||
|
positionName: "นักจัดการงานทั่วไป",
|
||||||
|
positionNum: "ปก./ชก.",
|
||||||
|
totalPositionCount: 4,
|
||||||
|
totalPositionVacant: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
positionID: 16,
|
||||||
|
positionName: "เจ้าพนักงานสถิติ",
|
||||||
|
positionNum: "ปง./ชง.",
|
||||||
|
totalPositionCount: 1,
|
||||||
|
totalPositionVacant: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
positionID: 17,
|
||||||
|
positionName: "เจ้าพนักงานธุรการ",
|
||||||
|
positionNum: "ปง./ชง.",
|
||||||
|
totalPositionCount: 2,
|
||||||
|
totalPositionVacant: 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deptID: 14,
|
||||||
|
departmentName: "ส่วนเรื่องราวร้องทุกข์",
|
||||||
|
totalPositionCount: 15,
|
||||||
|
totalPositionVacant: 0,
|
||||||
|
heads: [
|
||||||
|
{
|
||||||
|
positionID: 18,
|
||||||
|
positionName: "ผู้อำนวยการต้น",
|
||||||
|
positionNum: "(ผู้อำนวยการส่วน)",
|
||||||
|
totalPositionCount: 1,
|
||||||
|
totalPositionVacant: 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
deptID: 15,
|
||||||
|
departmentName: "กลุ่มงานรับเรื่องราวร้องทุกข์",
|
||||||
|
totalPositionCount: 7,
|
||||||
|
totalPositionVacant: 0,
|
||||||
|
heads: [
|
||||||
|
{
|
||||||
|
positionID: 19,
|
||||||
|
positionName: "นักจัดการงานทั่วไป",
|
||||||
|
positionNum: "ชพ. (หัวหน้ากลุ่มงาน)",
|
||||||
|
totalPositionCount: 1,
|
||||||
|
totalPositionVacant: 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
officer: [
|
||||||
|
{
|
||||||
|
positionID: 20,
|
||||||
|
positionName: "นักจัดการงานทั่วไป",
|
||||||
|
positionNum: "ปก./ชก.",
|
||||||
|
totalPositionCount: 4,
|
||||||
|
totalPositionVacant: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
positionID: 21,
|
||||||
|
positionName: "เจ้าพนักงานธุรการ",
|
||||||
|
positionNum: "ปง./ชง.",
|
||||||
|
totalPositionCount: 2,
|
||||||
|
totalPositionVacant: 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deptID: 16,
|
||||||
|
departmentName: "กลุ่มงานตรวจสอบ ติดตามและประมวลผล",
|
||||||
|
totalPositionCount: 7,
|
||||||
|
totalPositionVacant: 0,
|
||||||
|
heads: [
|
||||||
|
{
|
||||||
|
positionID: 22,
|
||||||
|
positionName: "นักจัดการงานทั่วไป",
|
||||||
|
positionNum: "ชพ. (หัวหน้ากลุ่มงาน)",
|
||||||
|
totalPositionCount: 1,
|
||||||
|
totalPositionVacant: 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
officer: [
|
||||||
|
{
|
||||||
|
positionID: 23,
|
||||||
|
positionName: "นักจัดการงานทั่วไป",
|
||||||
|
positionNum: "ปก./ชก.",
|
||||||
|
totalPositionCount: 4,
|
||||||
|
totalPositionVacant: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
positionID: 24,
|
||||||
|
positionName: "เจ้าพนักงานธุรการ",
|
||||||
|
positionNum: "ปง./ชง.",
|
||||||
|
totalPositionCount: 2,
|
||||||
|
totalPositionVacant: 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default chartData
|
||||||
8321
src/assets/tree.json
Normal file
8321
src/assets/tree.json
Normal file
File diff suppressed because it is too large
Load diff
90
src/components/CustomDialog.vue
Normal file
90
src/components/CustomDialog.vue
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
<template>
|
||||||
|
<q-dialog ref="dialogRef" @hide="onDialogHide" persistent>
|
||||||
|
<q-card class="q-pa-sm">
|
||||||
|
<q-card-section class="row">
|
||||||
|
<div class="q-pr-md">
|
||||||
|
<q-avatar
|
||||||
|
:icon="icon"
|
||||||
|
size="lg"
|
||||||
|
font-size="25px"
|
||||||
|
color="blue-1"
|
||||||
|
:text-color="color"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col text-dark">
|
||||||
|
<span class="text-bold">{{ title }}</span>
|
||||||
|
<br />
|
||||||
|
<span>{{ message }}</span>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-actions
|
||||||
|
align="right"
|
||||||
|
class="bg-white text-teal"
|
||||||
|
v-if="onlycancel"
|
||||||
|
>
|
||||||
|
<q-btn label="ตกลง" flat color="grey-8" @click="onDialogCancel" />
|
||||||
|
<!-- <q-btn :label="textOk" :color="color" @click="onOKClick" /> -->
|
||||||
|
</q-card-actions>
|
||||||
|
<q-card-actions align="right" class="bg-white text-teal" v-else>
|
||||||
|
<q-btn label="ยกเลิก" flat color="grey-8" @click="onDialogCancel" />
|
||||||
|
<q-btn :label="textOk" :color="color" @click="onOKClick" />
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useDialogPluginComponent } from "quasar";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: "primary",
|
||||||
|
},
|
||||||
|
textOk: {
|
||||||
|
type: String,
|
||||||
|
default: "ตกลง",
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: "หัวข้อ?",
|
||||||
|
},
|
||||||
|
message: {
|
||||||
|
type: String,
|
||||||
|
default: "ข้อความ",
|
||||||
|
},
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: "question_mark",
|
||||||
|
},
|
||||||
|
onlycancel: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
defineEmits([
|
||||||
|
// REQUIRED; need to specify some events that your
|
||||||
|
// component will emit through useDialogPluginComponent()
|
||||||
|
...useDialogPluginComponent.emits,
|
||||||
|
]);
|
||||||
|
|
||||||
|
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
|
||||||
|
useDialogPluginComponent();
|
||||||
|
// dialogRef - Vue ref to be applied to QDialog
|
||||||
|
// onDialogHide - Function to be used as handler for @hide on QDialog
|
||||||
|
// onDialogOK - Function to call to settle dialog with "ok" outcome
|
||||||
|
// example: onDialogOK() - no payload
|
||||||
|
// example: onDialogOK({ /*...*/ }) - with payload
|
||||||
|
// onDialogCancel - Function to call to settle dialog with "cancel" outcome
|
||||||
|
|
||||||
|
// this is part of our example (so not required)
|
||||||
|
function onOKClick() {
|
||||||
|
// on OK, it is REQUIRED to
|
||||||
|
// call onDialogOK (with optional payload)
|
||||||
|
onDialogOK();
|
||||||
|
// or with payload: onDialogOK({ ... })
|
||||||
|
// ...and it will also hide the dialog automatically
|
||||||
|
}
|
||||||
|
</script>
|
||||||
27
src/components/DialogHeader.vue
Normal file
27
src/components/DialogHeader.vue
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
<template>
|
||||||
|
<q-toolbar>
|
||||||
|
<q-toolbar-title class="text-subtitle2 text-bold">{{ tittle }}</q-toolbar-title>
|
||||||
|
<q-btn
|
||||||
|
icon="close"
|
||||||
|
unelevated
|
||||||
|
round
|
||||||
|
dense
|
||||||
|
@click="close"
|
||||||
|
style="color: #ff8080; background-color: #ffdede"
|
||||||
|
/>
|
||||||
|
</q-toolbar>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, useAttrs } from "vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
tittle: String,
|
||||||
|
close: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const close = async () => {
|
||||||
|
props.close();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
16
src/components/DropDownNoResultMsg.vue
Normal file
16
src/components/DropDownNoResultMsg.vue
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
<!-- =============================== -->
|
||||||
|
<!-- Component Show No Result Found Message -->
|
||||||
|
<!-- When filtering Drodown(q-select) -->
|
||||||
|
<!-- ข้อความที่จะแสดงเวลาค้นหาข้อมูลในดรอบดาวน์ไม่เจอ -->
|
||||||
|
<!-- ใช้หลายที่ จะได้จัด css ที่เดียว -->
|
||||||
|
<!-- =============================== -->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<q-item>
|
||||||
|
<q-item-section class="text-black"> ไม่พบข้อมูลที่ค้นหา </q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
|
<style lang="scss"></style>
|
||||||
15
src/components/Selector.vue
Normal file
15
src/components/Selector.vue
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<template>
|
||||||
|
<q-select v-bind="attrs">
|
||||||
|
<template v-slot:no-option>
|
||||||
|
<q-item>
|
||||||
|
<q-item-section class="text-black">
|
||||||
|
ไม่พบข้อมูลที่ค้นหา
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</template>
|
||||||
|
</q-select>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, useAttrs, defineAsyncComponent } from "vue";
|
||||||
|
const attrs = ref<any>(useAttrs());
|
||||||
|
</script>
|
||||||
204
src/components/TableHistory.vue
Normal file
204
src/components/TableHistory.vue
Normal file
|
|
@ -0,0 +1,204 @@
|
||||||
|
<template>
|
||||||
|
<q-dialog :model-value="modal" persistent>
|
||||||
|
<q-card style="min-width: 70vw;">
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<div class="row items-center q-pa-sm">
|
||||||
|
<div class="row">
|
||||||
|
<div class="text-bold">{{ tittle }}</div>
|
||||||
|
</div>
|
||||||
|
<q-space />
|
||||||
|
<q-btn
|
||||||
|
icon="close"
|
||||||
|
unelevated
|
||||||
|
round
|
||||||
|
dense
|
||||||
|
style="color: #ff8080; background-color: #ffdede"
|
||||||
|
size="12px"
|
||||||
|
@click="close"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<q-separator />
|
||||||
|
<div class="q-pa-sm">
|
||||||
|
<!-- header บน table มี ค้นหา แสดงคอลัมน์ (status nornmalData true) -->
|
||||||
|
<div class="col-12 row q-pb-sm">
|
||||||
|
<!-- <q-select
|
||||||
|
hide-bottom-space
|
||||||
|
@update:model-value="updateHistory"
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
borderless
|
||||||
|
:model-value="history"
|
||||||
|
:label="`${'วันที่'}`"
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
option-label="publishedDate"
|
||||||
|
:options="optionsHistory"
|
||||||
|
option-value="id"
|
||||||
|
/> -->
|
||||||
|
<q-space />
|
||||||
|
<div class="items-center" style="display: flex">
|
||||||
|
<!-- ค้นหาข้อความใน table -->
|
||||||
|
<q-input
|
||||||
|
standout
|
||||||
|
dense
|
||||||
|
:model-value="inputfilter"
|
||||||
|
ref="filterRef"
|
||||||
|
@update:model-value="updateInput"
|
||||||
|
outlined
|
||||||
|
debounce="300"
|
||||||
|
placeholder="ค้นหา"
|
||||||
|
style="max-width: 200px"
|
||||||
|
class="q-ml-sm"
|
||||||
|
>
|
||||||
|
<template v-slot:append>
|
||||||
|
<q-icon v-if="inputfilter == ''" name="search" />
|
||||||
|
<q-icon
|
||||||
|
v-if="inputfilter !== ''"
|
||||||
|
name="clear"
|
||||||
|
class="cursor-pointer"
|
||||||
|
@click="resetFilter"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
<!-- แสดงคอลัมน์ใน table -->
|
||||||
|
<q-select
|
||||||
|
:model-value="inputvisible"
|
||||||
|
@update:model-value="updateVisible"
|
||||||
|
:display-value="$q.lang.table.columns"
|
||||||
|
multiple
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
:options="attrs.columns"
|
||||||
|
options-dense
|
||||||
|
option-value="name"
|
||||||
|
map-options
|
||||||
|
emit-value
|
||||||
|
style="min-width: 150px"
|
||||||
|
class="gt-xs q-ml-sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<q-table
|
||||||
|
ref="table"
|
||||||
|
flat
|
||||||
|
bordered
|
||||||
|
class="custom-header-table"
|
||||||
|
v-bind="attrs"
|
||||||
|
virtual-scroll
|
||||||
|
:virtual-scroll-sticky-size-start="48"
|
||||||
|
dense
|
||||||
|
:pagination-label="paginationLabel"
|
||||||
|
:pagination="initialPagination"
|
||||||
|
:rows-per-page-options="[0]"
|
||||||
|
>
|
||||||
|
<template v-slot:header="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-th auto-width v-if="boss == true" />
|
||||||
|
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<span class="text-weight-medium">{{ col.label }}</span>
|
||||||
|
</q-th>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
<!-- สำหรับเรียกใช้ template ตัวข้างนอก -->
|
||||||
|
<template #body="props">
|
||||||
|
<slot v-bind="props" name="columns"></slot>
|
||||||
|
</template>
|
||||||
|
</q-table>
|
||||||
|
</div>
|
||||||
|
<q-separator />
|
||||||
|
</q-form>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, useAttrs } from "vue";
|
||||||
|
import type { Pagination } from "@/modules/01_metadata/interface/index/Main";
|
||||||
|
|
||||||
|
const attrs = ref<any>(useAttrs());
|
||||||
|
const filterRef = ref<any>(null);
|
||||||
|
// const history = ref<string>("");
|
||||||
|
const initialPagination = ref<Pagination>({
|
||||||
|
// descending: false,
|
||||||
|
rowsPerPage: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
tittle: String,
|
||||||
|
inputfilter: String,
|
||||||
|
// history: String,
|
||||||
|
inputvisible: Array,
|
||||||
|
modal: Boolean,
|
||||||
|
boss: {
|
||||||
|
type: Boolean,
|
||||||
|
defualt: false,
|
||||||
|
},
|
||||||
|
// optionsHistory: Array,
|
||||||
|
// updateHistory: {
|
||||||
|
// type: Function,
|
||||||
|
// default: () => console.log("not function"),
|
||||||
|
// },
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits([
|
||||||
|
"update:inputfilter",
|
||||||
|
"update:inputvisible",
|
||||||
|
"update:modal",
|
||||||
|
// "update:history",
|
||||||
|
]);
|
||||||
|
|
||||||
|
const updateInput = (value: string | number | null) => {
|
||||||
|
emit("update:inputfilter", value);
|
||||||
|
};
|
||||||
|
const updateVisible = (value: []) => {
|
||||||
|
emit("update:inputvisible", value);
|
||||||
|
};
|
||||||
|
const close = () => {
|
||||||
|
emit("update:modal", false);
|
||||||
|
};
|
||||||
|
// const updateHistory = (value: string) => {
|
||||||
|
// emit("update:history", value);
|
||||||
|
// props.updateHistory();
|
||||||
|
// };
|
||||||
|
|
||||||
|
const paginationLabel = (start: string, end: string, total: string) => {
|
||||||
|
return start + "-" + end + " ใน " + total;
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetFilter = () => {
|
||||||
|
// reset ค่าที่ค้นหาเมื่อกดปุ่ม X ในกล่องค้นหา
|
||||||
|
emit("update:inputfilter", "");
|
||||||
|
filterRef.value.focus();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.icon-color {
|
||||||
|
color: #4154b3;
|
||||||
|
}
|
||||||
|
.custom-header-table {
|
||||||
|
max-height: 64vh;
|
||||||
|
.q-table tr:nth-child(odd) td {
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
.q-table tr:nth-child(even) td {
|
||||||
|
background: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-table thead tr {
|
||||||
|
background: #ecebeb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-table thead tr th {
|
||||||
|
position: sticky;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
/* this will be the loading indicator */
|
||||||
|
.q-table thead tr:last-child th {
|
||||||
|
/* height of all previous header rows */
|
||||||
|
top: 48px;
|
||||||
|
}
|
||||||
|
.q-table thead tr:first-child th {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
541
src/components/TableView.vue
Normal file
541
src/components/TableView.vue
Normal file
|
|
@ -0,0 +1,541 @@
|
||||||
|
<template>
|
||||||
|
<div class="q-px-md q-pb-md">
|
||||||
|
<!-- header บน table มี ค้นหา แสดงคอลัมน์ ปุ่มแก้ไข เพิ่ม เผยแพร่ข้อมูล ยกเลิก (status nornmalData false) -->
|
||||||
|
<div class="col-12 row q-py-sm" v-if="nornmalData == false">
|
||||||
|
<q-btn
|
||||||
|
v-if="!editvisible == true && publicNoBtn == false"
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
:disabled="editvisible == true"
|
||||||
|
:color="editvisible == true ? 'grey-7' : 'primary'"
|
||||||
|
@click="edit"
|
||||||
|
icon="mdi-pencil-outline"
|
||||||
|
>
|
||||||
|
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
<!-- ยกเลิก แสดงเมื่อ กดปุ่มแก้ไข -->
|
||||||
|
<q-btn
|
||||||
|
v-else
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
:disabled="editvisible == false"
|
||||||
|
:outline="editvisible == false"
|
||||||
|
:color="editvisible == false ? 'grey-7' : 'red'"
|
||||||
|
@click="cancel()"
|
||||||
|
icon="mdi-undo"
|
||||||
|
>
|
||||||
|
<q-tooltip>ยกเลิก</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
<!-- <q-separator vertical /> -->
|
||||||
|
<div class="q-px-sm">
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
:disabled="editvisible == false"
|
||||||
|
:color="editvisible == false ? 'grey-7' : 'add'"
|
||||||
|
@click="add"
|
||||||
|
icon="mdi-plus"
|
||||||
|
>
|
||||||
|
<q-tooltip>เพิ่มข้อมูล</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
|
||||||
|
<!-- บันทึกร่าง แสดงเมื่อ กดปุ่มแก้ไข ข้อมูลมีการเป็นแปลงหรือ ยังไม่เผยแพร่ข้อมูล -->
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
:disabled="!(editvisible == true && updateData == true)"
|
||||||
|
:color="
|
||||||
|
!(editvisible == true && updateData == true) ? 'grey-7' : 'public'
|
||||||
|
"
|
||||||
|
@click="checkSave"
|
||||||
|
v-if="saveNoDraft == false"
|
||||||
|
icon="mdi-content-save-outline"
|
||||||
|
>
|
||||||
|
<q-tooltip>บันทึกร่าง</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
<!-- ลบบันทึกร่าง แสดงเมื่อ บันทึกร่างแล้ว -->
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
:disabled="publicData == true"
|
||||||
|
:color="publicData == true ? 'grey-7' : 'deep-orange'"
|
||||||
|
@click="DeleteModal"
|
||||||
|
icon="mdi-file-remove-outline"
|
||||||
|
v-if="publicNoBtn == false"
|
||||||
|
>
|
||||||
|
<q-tooltip>ลบบันทึกร่าง</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- เผยแพร่ -->
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
:disabled="!(publicData == false || updateData == true)"
|
||||||
|
:color="
|
||||||
|
!(publicData == false || updateData == true) ? 'grey-7' : 'public'
|
||||||
|
"
|
||||||
|
@click="publishModal"
|
||||||
|
icon="mdi-cloud-upload-outline"
|
||||||
|
v-if="publicNoBtn == false"
|
||||||
|
>
|
||||||
|
<q-tooltip>เผยแพร่</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
<div class="items-center" style="display: flex">
|
||||||
|
<div
|
||||||
|
class="row items-center"
|
||||||
|
style="display: flex"
|
||||||
|
v-if="publicData == false && publicNoBtn == false"
|
||||||
|
>
|
||||||
|
<div class="text-public text-body2 text-weight-medium q-px-sm">
|
||||||
|
ข้อมูลยังไม่เผยแพร่
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<q-space />
|
||||||
|
<div class="items-center" style="display: flex">
|
||||||
|
<!-- ข้อความสถานะเผยแพร่ โดยใช้ parameter publicData เป็นตัวกำหนดข้อความ -->
|
||||||
|
<!-- <div class="row items-center" style="display: flex" v-if="publicData == true">
|
||||||
|
<q-icon cener size="20px" name="label_important" class="icon-color" />
|
||||||
|
<div class="text-size">ข้อมูลเผยแพร่แล้ว</div>
|
||||||
|
</div> -->
|
||||||
|
<div
|
||||||
|
class="row items-center"
|
||||||
|
style="display: flex"
|
||||||
|
v-if="publicData == false && publicNoBtn == false"
|
||||||
|
>
|
||||||
|
<!-- <q-icon cener size="20px" name="label_important" color="amber" />
|
||||||
|
<div class="text-grey-7 text-body2 text-weight-medium q-px-sm">
|
||||||
|
ข้อมูลยังไม่เผยแพร่
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
<!-- ค้นหาข้อความใน table -->
|
||||||
|
<q-input
|
||||||
|
standout
|
||||||
|
dense
|
||||||
|
:model-value="inputfilter"
|
||||||
|
ref="filterRef"
|
||||||
|
@update:model-value="updateInput"
|
||||||
|
outlined
|
||||||
|
debounce="300"
|
||||||
|
placeholder="ค้นหา"
|
||||||
|
style="max-width: 200px"
|
||||||
|
class="q-ml-sm"
|
||||||
|
>
|
||||||
|
<template v-slot:append>
|
||||||
|
<q-icon v-if="inputfilter == ''" name="search" />
|
||||||
|
<q-icon
|
||||||
|
v-if="inputfilter !== ''"
|
||||||
|
name="clear"
|
||||||
|
class="cursor-pointer"
|
||||||
|
@click="resetFilter"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
<!-- แสดงคอลัมน์ใน table -->
|
||||||
|
<q-select
|
||||||
|
:model-value="inputvisible"
|
||||||
|
@update:model-value="updateVisible"
|
||||||
|
:display-value="$q.lang.table.columns"
|
||||||
|
multiple
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
:options="attrs.columns"
|
||||||
|
options-dense
|
||||||
|
option-value="name"
|
||||||
|
map-options
|
||||||
|
emit-value
|
||||||
|
style="min-width: 150px"
|
||||||
|
class="gt-xs q-ml-sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- header บน table มี ค้นหา แสดงคอลัมน์ (status nornmalData true) -->
|
||||||
|
<div class="col-12 row q-py-sm items-center" v-if="nornmalData == true">
|
||||||
|
<span class="text-subtitle1">{{ titleText }}</span>
|
||||||
|
<!-- <q-select
|
||||||
|
:model-value="inputvisibleFilter"
|
||||||
|
:options="optionsFilter"
|
||||||
|
style="min-width: 150px"
|
||||||
|
class="gt-xs q-ml-sm"
|
||||||
|
/> -->
|
||||||
|
<q-select
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
:model-value="inputvisibleFilter"
|
||||||
|
:options="optionsFilter"
|
||||||
|
class="col-xs-12 col-sm-4 col-md-3"
|
||||||
|
option-value="id"
|
||||||
|
option-label="name"
|
||||||
|
map-options
|
||||||
|
emit-value
|
||||||
|
@update:model-value="updateVisibleFilter"
|
||||||
|
v-if="optionsFilter != undefined && optionsFilter.length > 0"
|
||||||
|
/>
|
||||||
|
<q-space />
|
||||||
|
<div class="items-center" style="display: flex">
|
||||||
|
<!-- ค้นหาข้อความใน table -->
|
||||||
|
<q-input
|
||||||
|
standout
|
||||||
|
dense
|
||||||
|
:model-value="inputfilter"
|
||||||
|
ref="filterRef"
|
||||||
|
@update:model-value="updateInput"
|
||||||
|
outlined
|
||||||
|
debounce="300"
|
||||||
|
placeholder="ค้นหา"
|
||||||
|
style="max-width: 200px"
|
||||||
|
class="q-ml-sm"
|
||||||
|
>
|
||||||
|
<template v-slot:append>
|
||||||
|
<q-icon v-if="inputfilter == ''" name="search" />
|
||||||
|
<q-icon
|
||||||
|
v-if="inputfilter !== ''"
|
||||||
|
name="clear"
|
||||||
|
class="cursor-pointer"
|
||||||
|
@click="resetFilter"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
<!-- แสดงคอลัมน์ใน table -->
|
||||||
|
<q-select
|
||||||
|
:model-value="inputvisible"
|
||||||
|
@update:model-value="updateVisible"
|
||||||
|
:display-value="$q.lang.table.columns"
|
||||||
|
multiple
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
:options="attrs.columns"
|
||||||
|
options-dense
|
||||||
|
option-value="name"
|
||||||
|
map-options
|
||||||
|
emit-value
|
||||||
|
style="min-width: 150px"
|
||||||
|
class="gt-xs q-ml-sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<q-table
|
||||||
|
ref="table"
|
||||||
|
flat
|
||||||
|
bordered
|
||||||
|
class="custom-header-table"
|
||||||
|
v-bind="attrs"
|
||||||
|
virtual-scroll
|
||||||
|
:virtual-scroll-sticky-size-start="48"
|
||||||
|
dense
|
||||||
|
:pagination-label="paginationLabel"
|
||||||
|
:pagination="initialPagination"
|
||||||
|
:rows-per-page-options="paging == true ? [25, 50, 100, 500] : []"
|
||||||
|
>
|
||||||
|
<!-- :pagination="initialPagination" -->
|
||||||
|
<!-- :rows-per-page-options="[0]" -->
|
||||||
|
<template v-slot:header="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-th auto-width v-if="boss == true" />
|
||||||
|
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<span class="text-weight-medium">{{ col.label }}</span>
|
||||||
|
</q-th>
|
||||||
|
<q-th
|
||||||
|
auto-width
|
||||||
|
v-if="
|
||||||
|
editvisible == true || nextPageVisible == true || history == true
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
<!-- สำหรับเรียกใช้ template ตัวข้างนอก -->
|
||||||
|
<template #body="props">
|
||||||
|
<slot v-bind="props" name="columns"></slot>
|
||||||
|
</template>
|
||||||
|
</q-table>
|
||||||
|
</div>
|
||||||
|
<!-- ข้อมูลการเผยแพร่ข้อมูล -->
|
||||||
|
<!-- <notifyPublishDraft v-model:showModal="modalPublish" :ok="publish" /> -->
|
||||||
|
<!-- <q-dialog v-model="modalPublish" persistent>
|
||||||
|
<q-card class="q-pa-sm">
|
||||||
|
<q-card-section class="row">
|
||||||
|
<div class="q-pr-md">
|
||||||
|
<q-avatar
|
||||||
|
icon="public"
|
||||||
|
size="lg"
|
||||||
|
font-size="25px"
|
||||||
|
color="blue-1"
|
||||||
|
text-color="public"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col text-dark">
|
||||||
|
<span class="text-bold">ต้องการเผยแพร่ข้อมูลนี้หรือไม่?</span>
|
||||||
|
<br />
|
||||||
|
<span>ข้อมูลที่กำลังถูกเผยแพร่นี้จะมีผลใช้งานทันที</span>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-actions align="right" class="bg-white text-teal">
|
||||||
|
<q-btn label="ยกเลิก" flat color="grey-8" v-close-popup />
|
||||||
|
<q-btn
|
||||||
|
label="เผยแพร่"
|
||||||
|
color="public"
|
||||||
|
@click="publish()"
|
||||||
|
v-close-popup
|
||||||
|
/>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog> -->
|
||||||
|
|
||||||
|
<!-- ข้อมูลการลบเผยแพร่ข้อมูล -->
|
||||||
|
<!-- <notifyDeleteDraft v-model:showModal="modalDelete" :ok="deleted" /> -->
|
||||||
|
<!-- <q-dialog v-model="modalDelete" persistent>
|
||||||
|
<q-card class="q-pa-sm">
|
||||||
|
<q-card-section class="row">
|
||||||
|
<div class="q-pr-md">
|
||||||
|
<q-avatar
|
||||||
|
icon="mdi-file-remove-outline"
|
||||||
|
size="lg"
|
||||||
|
font-size="25px"
|
||||||
|
color="red-1"
|
||||||
|
text-color="deep-orange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col text-dark">
|
||||||
|
<span class="text-bold">ต้องการลบข้อมูลบันทึกร่างนี้หรือไม่?</span>
|
||||||
|
<br />
|
||||||
|
<span>ข้อมูลบันทึกร่างที่กำลังถูกลบนี้จะมีผลใช้งานทันที</span>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-actions align="right" class="bg-white text-teal">
|
||||||
|
<q-btn label="ยกเลิก" flat color="grey-8" v-close-popup />
|
||||||
|
<q-btn label="ลบบันทึก" color="red" @click="deleted()" v-close-popup />
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog> -->
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, useAttrs } from "vue";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
|
||||||
|
const $q = useQuasar();
|
||||||
|
const mixin = useCounterMixin(); //เรียกฟังก์ชันกลาง
|
||||||
|
const { dialogMessage } = mixin;
|
||||||
|
|
||||||
|
const attrs = ref<any>(useAttrs());
|
||||||
|
const table = ref<any>(null);
|
||||||
|
const filterRef = ref<any>(null);
|
||||||
|
const modalPublish = ref<boolean>(false);
|
||||||
|
const modalDelete = ref<boolean>(false);
|
||||||
|
const props = defineProps({
|
||||||
|
inputfilter: String,
|
||||||
|
inputvisible: Array,
|
||||||
|
inputvisibleFilter: String,
|
||||||
|
editvisible: Boolean,
|
||||||
|
titleText: String,
|
||||||
|
optionsFilter: {
|
||||||
|
type: Array,
|
||||||
|
defualt: [],
|
||||||
|
},
|
||||||
|
boss: {
|
||||||
|
type: Boolean,
|
||||||
|
defualt: false,
|
||||||
|
},
|
||||||
|
saveNoDraft: {
|
||||||
|
type: Boolean,
|
||||||
|
defualt: false,
|
||||||
|
},
|
||||||
|
history: {
|
||||||
|
type: Boolean,
|
||||||
|
defualt: false,
|
||||||
|
},
|
||||||
|
paging: {
|
||||||
|
type: Boolean,
|
||||||
|
defualt: false,
|
||||||
|
},
|
||||||
|
nornmalData: {
|
||||||
|
type: Boolean,
|
||||||
|
defualt: false,
|
||||||
|
},
|
||||||
|
nextPageVisible: {
|
||||||
|
type: Boolean,
|
||||||
|
defualt: false,
|
||||||
|
},
|
||||||
|
publicData: {
|
||||||
|
type: Boolean,
|
||||||
|
defualt: true,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
updateData: {
|
||||||
|
type: Boolean,
|
||||||
|
defualt: true,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
publicNoBtn: {
|
||||||
|
type: Boolean,
|
||||||
|
defualt: false,
|
||||||
|
},
|
||||||
|
add: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
edit: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
save: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
deleted: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
cancel: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
publish: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
validate: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const initialPagination = ref<any>({
|
||||||
|
// descending: false,
|
||||||
|
rowsPerPage: props.paging == true ? 25 : 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits([
|
||||||
|
"update:inputfilter",
|
||||||
|
"update:inputvisible",
|
||||||
|
"update:editvisible",
|
||||||
|
"update:titleText",
|
||||||
|
"update:inputvisibleFilter",
|
||||||
|
]);
|
||||||
|
|
||||||
|
const updateEdit = (value: any) => {
|
||||||
|
emit("update:editvisible", value);
|
||||||
|
};
|
||||||
|
const updateInput = (value: any) => {
|
||||||
|
emit("update:inputfilter", value);
|
||||||
|
};
|
||||||
|
const updateVisible = (value: any) => {
|
||||||
|
emit("update:inputvisible", value);
|
||||||
|
};
|
||||||
|
const updateVisibleFilter = (value: any) => {
|
||||||
|
emit("update:inputvisibleFilter", value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const paginationLabel = (start: string, end: string, total: string) => {
|
||||||
|
if (props.paging == true)
|
||||||
|
return " " + start + " ใน " + end + " จากจำนวน " + total + " รายการ";
|
||||||
|
else return start + "-" + end + " ใน " + total;
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkSave = () => {
|
||||||
|
props.validate();
|
||||||
|
props.save();
|
||||||
|
// if (myForm.value !== null) {
|
||||||
|
// myForm.value.validate().then((success) => {
|
||||||
|
// if (success) {
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
const publishModal = () => {
|
||||||
|
props.validate();
|
||||||
|
const filter = attrs.value.rows.filter((r: any) => r.name == "");
|
||||||
|
|
||||||
|
if (filter.length == 0 || attrs.value.rows.length == 0) {
|
||||||
|
// modalPublish.value = true;
|
||||||
|
dialogMessage(
|
||||||
|
$q,
|
||||||
|
"ต้องการเผยแพร่ข้อมูลนี้หรือไม่?",
|
||||||
|
"ข้อมูลที่กำลังถูกเผยแพร่นี้จะมีผลใช้งานทันที",
|
||||||
|
"public",
|
||||||
|
"เผยแพร่",
|
||||||
|
"public",
|
||||||
|
props.publish,
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const DeleteModal = () => {
|
||||||
|
// modalDelete.value = true;
|
||||||
|
dialogMessage(
|
||||||
|
$q,
|
||||||
|
"ต้องการลบข้อมูลบันทึกร่างนี้หรือไม่?",
|
||||||
|
"ข้อมูลบันทึกร่างที่กำลังถูกลบนี้จะมีผลใช้งานทันที",
|
||||||
|
"mdi-file-remove-outline",
|
||||||
|
"ลบบันทึก",
|
||||||
|
"red",
|
||||||
|
props.deleted,
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const edit = async () => {
|
||||||
|
updateEdit(!props.editvisible);
|
||||||
|
props.edit();
|
||||||
|
};
|
||||||
|
|
||||||
|
const add = async () => {
|
||||||
|
// if (myForm.value !== null) {
|
||||||
|
// myForm.value.validate();
|
||||||
|
// }
|
||||||
|
props.validate();
|
||||||
|
props.add();
|
||||||
|
await table.value.lastPage();
|
||||||
|
await table.value.scrollTo(attrs.value.rows.length - 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleted = async () => {
|
||||||
|
// const deletedF = () => {
|
||||||
|
if (props.publicNoBtn === false) {
|
||||||
|
updateEdit(false);
|
||||||
|
}
|
||||||
|
props.deleted();
|
||||||
|
};
|
||||||
|
|
||||||
|
const resetFilter = () => {
|
||||||
|
// reset ค่าที่ค้นหาเมื่อกดปุ่ม X ในกล่องค้นหา
|
||||||
|
emit("update:inputfilter", "");
|
||||||
|
filterRef.value.focus();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.icon-color {
|
||||||
|
color: #4154b3;
|
||||||
|
}
|
||||||
|
.custom-header-table {
|
||||||
|
max-height: 64vh;
|
||||||
|
.q-table tr:nth-child(odd) td {
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
.q-table tr:nth-child(even) td {
|
||||||
|
background: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-table thead tr {
|
||||||
|
background: #ecebeb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-table thead tr th {
|
||||||
|
position: sticky;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
/* this will be the loading indicator */
|
||||||
|
.q-table thead tr:last-child th {
|
||||||
|
/* height of all previous header rows */
|
||||||
|
top: 48px;
|
||||||
|
}
|
||||||
|
.q-table thead tr:first-child th {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
412
src/components/TableView1.vue
Normal file
412
src/components/TableView1.vue
Normal file
|
|
@ -0,0 +1,412 @@
|
||||||
|
<template>
|
||||||
|
<div class="q-px-md q-pb-md">
|
||||||
|
<!-- header บน table มี ค้นหา แสดงคอลัมน์ ปุ่มแก้ไข เพิ่ม เผยแพร่ข้อมูล ยกเลิก-->
|
||||||
|
<div class="col-12 row q-py-sm q-col-gutter-sm">
|
||||||
|
<q-btn-group flat>
|
||||||
|
<q-btn
|
||||||
|
:push="!editvisible"
|
||||||
|
:outline="editvisible"
|
||||||
|
dense
|
||||||
|
:disabled="editvisible == true"
|
||||||
|
:color="editvisible == true ? 'grey-7' : 'primary'"
|
||||||
|
label="แก้ไข"
|
||||||
|
@click="edit"
|
||||||
|
icon="mdi-pencil-outline"
|
||||||
|
class="q-px-sm"
|
||||||
|
>
|
||||||
|
<!-- <q-tooltip>แก้ไขข้อมูล</q-tooltip> -->
|
||||||
|
</q-btn>
|
||||||
|
<!-- <q-separator vertical /> -->
|
||||||
|
<q-btn
|
||||||
|
:push="editvisible"
|
||||||
|
:outline="!editvisible"
|
||||||
|
dense
|
||||||
|
:disabled="editvisible == false"
|
||||||
|
:color="editvisible == false ? 'grey-7' : 'primary'"
|
||||||
|
label="เพิ่ม"
|
||||||
|
@click="add"
|
||||||
|
icon="mdi-plus"
|
||||||
|
class="q-px-sm"
|
||||||
|
>
|
||||||
|
<!-- <q-tooltip>เพิ่มข้อมูล</q-tooltip> -->
|
||||||
|
</q-btn>
|
||||||
|
</q-btn-group>
|
||||||
|
<q-btn-group flat>
|
||||||
|
<!-- เผยแพร่ -->
|
||||||
|
<q-btn
|
||||||
|
dense
|
||||||
|
:push="publicData == false || updateData == true"
|
||||||
|
:outline="!(publicData == false || updateData == true)"
|
||||||
|
:disabled="!(publicData == false || updateData == true)"
|
||||||
|
:color="
|
||||||
|
!(publicData == false || updateData == true) ? 'grey-7' : 'public'
|
||||||
|
"
|
||||||
|
label="เผยแพร่"
|
||||||
|
@click="publishModal"
|
||||||
|
icon="mdi-file-upload-outline"
|
||||||
|
class="q-px-sm"
|
||||||
|
>
|
||||||
|
<!-- <q-tooltip>เผยแพร่</q-tooltip> -->
|
||||||
|
</q-btn>
|
||||||
|
<!-- บันทึกร่าง แสดงเมื่อ กดปุ่มแก้ไข ข้อมูลมีการเป็นแปลงหรือ ยังไม่เผยแพร่ข้อมูล -->
|
||||||
|
<q-btn
|
||||||
|
dense
|
||||||
|
:push="
|
||||||
|
editvisible == true && (publicData == false || updateData == true)
|
||||||
|
"
|
||||||
|
:outline="
|
||||||
|
!(
|
||||||
|
editvisible == true &&
|
||||||
|
(publicData == false || updateData == true)
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:disabled="
|
||||||
|
!(
|
||||||
|
editvisible == true &&
|
||||||
|
(publicData == false || updateData == true)
|
||||||
|
)
|
||||||
|
"
|
||||||
|
:color="
|
||||||
|
!(
|
||||||
|
editvisible == true &&
|
||||||
|
(publicData == false || updateData == true)
|
||||||
|
)
|
||||||
|
? 'grey-7'
|
||||||
|
: 'public'
|
||||||
|
"
|
||||||
|
label="บันทึกร่าง"
|
||||||
|
@click="checkSave"
|
||||||
|
icon="mdi-file-check-outline"
|
||||||
|
class="q-px-sm"
|
||||||
|
>
|
||||||
|
<!-- <q-tooltip>บันทึกร่าง</q-tooltip> -->
|
||||||
|
</q-btn>
|
||||||
|
|
||||||
|
<!-- ลบบันทึกร่าง แสดงเมื่อ บันทึกร่างแล้ว -->
|
||||||
|
<q-btn
|
||||||
|
dense
|
||||||
|
:push="!publicData"
|
||||||
|
:disabled="publicData == true"
|
||||||
|
:outline="publicData == true"
|
||||||
|
label="ลบร่าง"
|
||||||
|
:color="publicData == true ? 'grey-7' : 'public'"
|
||||||
|
@click="deleted()"
|
||||||
|
icon="mdi-file-remove-outline"
|
||||||
|
class="q-px-sm"
|
||||||
|
>
|
||||||
|
<!-- <q-tooltip>ลบบันทึกร่าง</q-tooltip> -->
|
||||||
|
</q-btn>
|
||||||
|
</q-btn-group>
|
||||||
|
|
||||||
|
<q-btn-group flat>
|
||||||
|
<!-- ยกเลิก แสดงเมื่อ กดปุ่มแก้ไข -->
|
||||||
|
<q-btn
|
||||||
|
dense
|
||||||
|
:push="editvisible"
|
||||||
|
:disabled="editvisible == false"
|
||||||
|
:outline="editvisible == false"
|
||||||
|
label="ยกเลิก"
|
||||||
|
:color="editvisible == false ? 'grey-7' : 'red'"
|
||||||
|
@click="cancel()"
|
||||||
|
icon="mdi-close"
|
||||||
|
class="q-px-sm"
|
||||||
|
>
|
||||||
|
<!-- <q-tooltip>ยกเลิก</q-tooltip> -->
|
||||||
|
</q-btn>
|
||||||
|
</q-btn-group>
|
||||||
|
<q-space />
|
||||||
|
<div class="items-center" style="display: flex">
|
||||||
|
<!-- ข้อความสถานะเผยแพร่ โดยใช้ parameter publicData เป็นตัวกำหนดข้อความ -->
|
||||||
|
<!-- <div class="row items-center" style="display: flex" v-if="publicData == true">
|
||||||
|
<q-icon cener size="20px" name="label_important" class="icon-color" />
|
||||||
|
<div class="text-size">ข้อมูลเผยแพร่แล้ว</div>
|
||||||
|
</div> -->
|
||||||
|
<div
|
||||||
|
class="row items-center"
|
||||||
|
style="display: flex"
|
||||||
|
v-if="publicData == false"
|
||||||
|
>
|
||||||
|
<q-icon cener size="15px" name="label_important" color="amber" />
|
||||||
|
<div class="text-caption text-grey-7 text-weight-medium q-px-sm">
|
||||||
|
ข้อมูลยังไม่เผยแพร่
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- ค้นหาข้อความใน table -->
|
||||||
|
<q-input
|
||||||
|
standout
|
||||||
|
dense
|
||||||
|
:model-value="inputfilter"
|
||||||
|
@update:model-value="updateInput"
|
||||||
|
outlined
|
||||||
|
debounce="300"
|
||||||
|
placeholder="ค้นหา"
|
||||||
|
style="max-width: 200px"
|
||||||
|
class="q-ml-sm"
|
||||||
|
>
|
||||||
|
<template v-slot:append>
|
||||||
|
<q-icon name="search" />
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
<!-- แสดงคอลัมน์ใน table -->
|
||||||
|
<q-select
|
||||||
|
:model-value="inputvisible"
|
||||||
|
@update:model-value="updateVisible"
|
||||||
|
:display-value="$q.lang.table.columns"
|
||||||
|
multiple
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
:options="attrs.columns"
|
||||||
|
options-dense
|
||||||
|
option-value="name"
|
||||||
|
map-options
|
||||||
|
emit-value
|
||||||
|
style="min-width: 150px"
|
||||||
|
class="gt-xs q-ml-sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<q-table
|
||||||
|
ref="table"
|
||||||
|
flat
|
||||||
|
bordered
|
||||||
|
class="custom-header-table"
|
||||||
|
v-bind="attrs"
|
||||||
|
virtual-scroll
|
||||||
|
:rows-per-page-options="[0]"
|
||||||
|
:virtual-scroll-sticky-size-start="48"
|
||||||
|
dense
|
||||||
|
><!-- :pagination="initialPagination"
|
||||||
|
:pagination-label="paginationLabel" -->
|
||||||
|
<template v-slot:header="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<span class="text-weight-medium">{{ col.label }}</span>
|
||||||
|
</q-th>
|
||||||
|
<q-th
|
||||||
|
auto-width
|
||||||
|
v-if="editvisible == true || nextPageVisible == true"
|
||||||
|
/>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
<!-- สำหรับเรียกใช้ template ตัวข้างนอก -->
|
||||||
|
<template #body="props">
|
||||||
|
<slot v-bind="props" name="columns"></slot>
|
||||||
|
</template>
|
||||||
|
</q-table>
|
||||||
|
</div>
|
||||||
|
<!-- ข้อมูลการเผยแพร่ข้อมูล -->
|
||||||
|
<q-dialog v-model="modal" persistent>
|
||||||
|
<q-card class="q-pa-sm">
|
||||||
|
<q-card-section class="row">
|
||||||
|
<div class="q-pr-md">
|
||||||
|
<q-avatar
|
||||||
|
icon="public"
|
||||||
|
size="lg"
|
||||||
|
font-size="25px"
|
||||||
|
color="blue-1"
|
||||||
|
text-color="public"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col text-dark">
|
||||||
|
<span class="text-bold">ต้องการเผยแพร่ข้อมูลนี้หรือไม่?</span>
|
||||||
|
<br />
|
||||||
|
<span>ข้อมูลที่กำลังถูกเผยแพร่นี้จะมีผลใช้งานทันที</span>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-actions align="right" class="bg-white text-teal">
|
||||||
|
<q-btn label="ยกเลิก" flat color="grey-8" v-close-popup />
|
||||||
|
<q-btn
|
||||||
|
label="เผยแพร่"
|
||||||
|
color="public"
|
||||||
|
@click="publish()"
|
||||||
|
v-close-popup
|
||||||
|
/>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
<q-dialog
|
||||||
|
:model-value="modalError"
|
||||||
|
persistent
|
||||||
|
@update:model-value="updateClose"
|
||||||
|
>
|
||||||
|
<q-card class="q-pa-sm">
|
||||||
|
<q-card-section class="row items-center">
|
||||||
|
<div class="q-pr-md">
|
||||||
|
<q-avatar
|
||||||
|
icon="mdi-alert-circle-outline"
|
||||||
|
font-size="25px"
|
||||||
|
size="lg"
|
||||||
|
color="red-1"
|
||||||
|
text-color="red"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col text-dark">
|
||||||
|
<span class="text-bold">{{ modalErrorTittle }}</span>
|
||||||
|
<br />
|
||||||
|
<span>{{ modalErrorDetail }}</span>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-actions align="right" class="bg-white text-teal">
|
||||||
|
<q-btn
|
||||||
|
label="ตกลง"
|
||||||
|
color="primary"
|
||||||
|
@click="updateClose"
|
||||||
|
v-close-popup
|
||||||
|
/>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, useAttrs } from "vue";
|
||||||
|
|
||||||
|
const attrs = ref<any>(useAttrs());
|
||||||
|
const table = ref<any>(null);
|
||||||
|
|
||||||
|
const modal = ref<boolean>(false);
|
||||||
|
const initialPagination = ref<any>({
|
||||||
|
descending: false,
|
||||||
|
rowsPerPage: 10,
|
||||||
|
});
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
inputfilter: String,
|
||||||
|
inputvisible: Array,
|
||||||
|
editvisible: Boolean,
|
||||||
|
nextPageVisible: {
|
||||||
|
type: Boolean,
|
||||||
|
defualt: false,
|
||||||
|
},
|
||||||
|
modalError: Boolean,
|
||||||
|
modalErrorTittle: String,
|
||||||
|
modalErrorDetail: String,
|
||||||
|
publicData: {
|
||||||
|
type: Boolean,
|
||||||
|
defualt: true,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
updateData: {
|
||||||
|
type: Boolean,
|
||||||
|
defualt: true,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
add: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
edit: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
save: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
deleted: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
cancel: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
publish: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits([
|
||||||
|
"update:inputfilter",
|
||||||
|
"update:inputvisible",
|
||||||
|
"update:editvisible",
|
||||||
|
"update:modalError",
|
||||||
|
"update:modalErrorTittle",
|
||||||
|
"update:modalErrorDetail",
|
||||||
|
]);
|
||||||
|
|
||||||
|
const updateEdit = (value: any) => {
|
||||||
|
emit("update:editvisible", value);
|
||||||
|
};
|
||||||
|
const updateInput = (value: any) => {
|
||||||
|
emit("update:inputfilter", value);
|
||||||
|
};
|
||||||
|
const updateVisible = (value: any) => {
|
||||||
|
emit("update:inputvisible", value);
|
||||||
|
};
|
||||||
|
const updateClose = (value: any) => {
|
||||||
|
// props.modalError = false;
|
||||||
|
emit("update:modalError", false);
|
||||||
|
emit("update:modalErrorTittle", "");
|
||||||
|
emit("update:modalErrorDetail", "");
|
||||||
|
};
|
||||||
|
|
||||||
|
const paginationLabel = (start: string, end: string, total: string) => {
|
||||||
|
return start + "-" + end + " ใน " + total;
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkSave = () => {
|
||||||
|
props.save();
|
||||||
|
// if (myForm.value !== null) {
|
||||||
|
// myForm.value.validate().then((success) => {
|
||||||
|
// if (success) {
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
|
||||||
|
const publishModal = () => {
|
||||||
|
const filter = attrs.value.rows.filter((r: any) => r.name == "");
|
||||||
|
|
||||||
|
if (filter.length == 0 && attrs.value.rows.length !== 0) {
|
||||||
|
modal.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const edit = async () => {
|
||||||
|
updateEdit(!props.editvisible);
|
||||||
|
props.edit();
|
||||||
|
};
|
||||||
|
|
||||||
|
const add = async () => {
|
||||||
|
// if (myForm.value !== null) {
|
||||||
|
// myForm.value.validate();
|
||||||
|
// }
|
||||||
|
props.add();
|
||||||
|
await table.value.lastPage();
|
||||||
|
await table.value.scrollTo(attrs.value.rows.length - 1);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.icon-color {
|
||||||
|
color: #4154b3;
|
||||||
|
}
|
||||||
|
.custom-header-table {
|
||||||
|
max-height: 38vh;
|
||||||
|
.q-table tr:nth-child(odd) td {
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
.q-table tr:nth-child(even) td {
|
||||||
|
background: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-table thead tr {
|
||||||
|
background: #ecebeb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-table thead tr th {
|
||||||
|
position: sticky;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
/* this will be the loading indicator */
|
||||||
|
.q-table thead tr:last-child th {
|
||||||
|
/* height of all previous header rows */
|
||||||
|
top: 48px;
|
||||||
|
}
|
||||||
|
.q-table thead tr:first-child th {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
0
src/components/ViewPDF.vue
Normal file
0
src/components/ViewPDF.vue
Normal file
11
src/components/__tests__/HelloWorld.spec.ts
Normal file
11
src/components/__tests__/HelloWorld.spec.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { describe, it, expect } from "vitest";
|
||||||
|
|
||||||
|
import { mount } from "@vue/test-utils";
|
||||||
|
// import HelloWorld from '../HelloWorld.vue'
|
||||||
|
|
||||||
|
describe("HelloWorld", () => {
|
||||||
|
it("renders properly", () => {
|
||||||
|
// const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
|
||||||
|
// expect(wrapper.text()).toContain('Hello Vitest')
|
||||||
|
});
|
||||||
|
});
|
||||||
7
src/components/icons/IconCommunity.vue
Normal file
7
src/components/icons/IconCommunity.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
|
||||||
|
<path
|
||||||
|
d="M15 4a1 1 0 1 0 0 2V4zm0 11v-1a1 1 0 0 0-1 1h1zm0 4l-.707.707A1 1 0 0 0 16 19h-1zm-4-4l.707-.707A1 1 0 0 0 11 14v1zm-4.707-1.293a1 1 0 0 0-1.414 1.414l1.414-1.414zm-.707.707l-.707-.707.707.707zM9 11v-1a1 1 0 0 0-.707.293L9 11zm-4 0h1a1 1 0 0 0-1-1v1zm0 4H4a1 1 0 0 0 1.707.707L5 15zm10-9h2V4h-2v2zm2 0a1 1 0 0 1 1 1h2a3 3 0 0 0-3-3v2zm1 1v6h2V7h-2zm0 6a1 1 0 0 1-1 1v2a3 3 0 0 0 3-3h-2zm-1 1h-2v2h2v-2zm-3 1v4h2v-4h-2zm1.707 3.293l-4-4-1.414 1.414 4 4 1.414-1.414zM11 14H7v2h4v-2zm-4 0c-.276 0-.525-.111-.707-.293l-1.414 1.414C5.42 15.663 6.172 16 7 16v-2zm-.707 1.121l3.414-3.414-1.414-1.414-3.414 3.414 1.414 1.414zM9 12h4v-2H9v2zm4 0a3 3 0 0 0 3-3h-2a1 1 0 0 1-1 1v2zm3-3V3h-2v6h2zm0-6a3 3 0 0 0-3-3v2a1 1 0 0 1 1 1h2zm-3-3H3v2h10V0zM3 0a3 3 0 0 0-3 3h2a1 1 0 0 1 1-1V0zM0 3v6h2V3H0zm0 6a3 3 0 0 0 3 3v-2a1 1 0 0 1-1-1H0zm3 3h2v-2H3v2zm1-1v4h2v-4H4zm1.707 4.707l.586-.586-1.414-1.414-.586.586 1.414 1.414z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
7
src/components/icons/IconDocumentation.vue
Normal file
7
src/components/icons/IconDocumentation.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" fill="currentColor">
|
||||||
|
<path
|
||||||
|
d="M11 2.253a1 1 0 1 0-2 0h2zm-2 13a1 1 0 1 0 2 0H9zm.447-12.167a1 1 0 1 0 1.107-1.666L9.447 3.086zM1 2.253L.447 1.42A1 1 0 0 0 0 2.253h1zm0 13H0a1 1 0 0 0 1.553.833L1 15.253zm8.447.833a1 1 0 1 0 1.107-1.666l-1.107 1.666zm0-14.666a1 1 0 1 0 1.107 1.666L9.447 1.42zM19 2.253h1a1 1 0 0 0-.447-.833L19 2.253zm0 13l-.553.833A1 1 0 0 0 20 15.253h-1zm-9.553-.833a1 1 0 1 0 1.107 1.666L9.447 14.42zM9 2.253v13h2v-13H9zm1.553-.833C9.203.523 7.42 0 5.5 0v2c1.572 0 2.961.431 3.947 1.086l1.107-1.666zM5.5 0C3.58 0 1.797.523.447 1.42l1.107 1.666C2.539 2.431 3.928 2 5.5 2V0zM0 2.253v13h2v-13H0zm1.553 13.833C2.539 15.431 3.928 15 5.5 15v-2c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM5.5 15c1.572 0 2.961.431 3.947 1.086l1.107-1.666C9.203 13.523 7.42 13 5.5 13v2zm5.053-11.914C11.539 2.431 12.928 2 14.5 2V0c-1.92 0-3.703.523-5.053 1.42l1.107 1.666zM14.5 2c1.573 0 2.961.431 3.947 1.086l1.107-1.666C18.203.523 16.421 0 14.5 0v2zm3.5.253v13h2v-13h-2zm1.553 12.167C18.203 13.523 16.421 13 14.5 13v2c1.573 0 2.961.431 3.947 1.086l1.107-1.666zM14.5 13c-1.92 0-3.703.523-5.053 1.42l1.107 1.666C11.539 15.431 12.928 15 14.5 15v-2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
7
src/components/icons/IconEcosystem.vue
Normal file
7
src/components/icons/IconEcosystem.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" fill="currentColor">
|
||||||
|
<path
|
||||||
|
d="M11.447 8.894a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm0 1.789a1 1 0 1 0 .894-1.789l-.894 1.789zM7.447 7.106a1 1 0 1 0-.894 1.789l.894-1.789zM10 9a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0H8zm9.447-5.606a1 1 0 1 0-.894-1.789l.894 1.789zm-2.894-.789a1 1 0 1 0 .894 1.789l-.894-1.789zm2 .789a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zM18 5a1 1 0 1 0-2 0h2zm-2 2.5a1 1 0 1 0 2 0h-2zm-5.447-4.606a1 1 0 1 0 .894-1.789l-.894 1.789zM9 1l.447-.894a1 1 0 0 0-.894 0L9 1zm-2.447.106a1 1 0 1 0 .894 1.789l-.894-1.789zm-6 3a1 1 0 1 0 .894 1.789L.553 4.106zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zm-2-.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 2.789a1 1 0 1 0 .894-1.789l-.894 1.789zM2 5a1 1 0 1 0-2 0h2zM0 7.5a1 1 0 1 0 2 0H0zm8.553 12.394a1 1 0 1 0 .894-1.789l-.894 1.789zm-1.106-2.789a1 1 0 1 0-.894 1.789l.894-1.789zm1.106 1a1 1 0 1 0 .894 1.789l-.894-1.789zm2.894.789a1 1 0 1 0-.894-1.789l.894 1.789zM8 19a1 1 0 1 0 2 0H8zm2-2.5a1 1 0 1 0-2 0h2zm-7.447.394a1 1 0 1 0 .894-1.789l-.894 1.789zM1 15H0a1 1 0 0 0 .553.894L1 15zm1-2.5a1 1 0 1 0-2 0h2zm12.553 2.606a1 1 0 1 0 .894 1.789l-.894-1.789zM17 15l.447.894A1 1 0 0 0 18 15h-1zm1-2.5a1 1 0 1 0-2 0h2zm-7.447-5.394l-2 1 .894 1.789 2-1-.894-1.789zm-1.106 1l-2-1-.894 1.789 2 1 .894-1.789zM8 9v2.5h2V9H8zm8.553-4.894l-2 1 .894 1.789 2-1-.894-1.789zm.894 0l-2-1-.894 1.789 2 1 .894-1.789zM16 5v2.5h2V5h-2zm-4.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zm-2.894-1l-2 1 .894 1.789 2-1L8.553.106zM1.447 5.894l2-1-.894-1.789-2 1 .894 1.789zm-.894 0l2 1 .894-1.789-2-1-.894 1.789zM0 5v2.5h2V5H0zm9.447 13.106l-2-1-.894 1.789 2 1 .894-1.789zm0 1.789l2-1-.894-1.789-2 1 .894 1.789zM10 19v-2.5H8V19h2zm-6.553-3.894l-2-1-.894 1.789 2 1 .894-1.789zM2 15v-2.5H0V15h2zm13.447 1.894l2-1-.894-1.789-2 1 .894 1.789zM18 15v-2.5h-2V15h2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
7
src/components/icons/IconSupport.vue
Normal file
7
src/components/icons/IconSupport.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<template>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor">
|
||||||
|
<path
|
||||||
|
d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.666.105 5.5 5.5 0 0 0-.114 7.665L10 18.78l8.39-8.4a5.5 5.5 0 0 0-.114-7.665 5.5 5.5 0 0 0-7.666-.105l-.61.61z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
19
src/components/icons/IconTooling.vue
Normal file
19
src/components/icons/IconTooling.vue
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!-- This icon is from <https://github.com/Templarian/MaterialDesign>, distributed under Apache 2.0 (https://www.apache.org/licenses/LICENSE-2.0) license-->
|
||||||
|
<template>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
aria-hidden="true"
|
||||||
|
role="img"
|
||||||
|
class="iconify iconify--mdi"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
preserveAspectRatio="xMidYMid meet"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20 18v-4h-3v1h-2v-1H9v1H7v-1H4v4h16M6.33 8l-1.74 4H7v-1h2v1h6v-1h2v1h2.41l-1.74-4H6.33M9 5v1h6V5H9m12.84 7.61c.1.22.16.48.16.8V18c0 .53-.21 1-.6 1.41c-.4.4-.85.59-1.4.59H4c-.55 0-1-.19-1.4-.59C2.21 19 2 18.53 2 18v-4.59c0-.32.06-.58.16-.8L4.5 7.22C4.84 6.41 5.45 6 6.33 6H7V5c0-.55.18-1 .57-1.41C7.96 3.2 8.44 3 9 3h6c.56 0 1.04.2 1.43.59c.39.41.57.86.57 1.41v1h.67c.88 0 1.49.41 1.83 1.22l2.34 5.39z"
|
||||||
|
fill="currentColor"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
41
src/global/user_response_msg.ts
Normal file
41
src/global/user_response_msg.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* GLOABL Response Message for User
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
|
||||||
|
// const $q = useQuasar(); // show dialog Error:runtime-core.esm-bundler.js:40 [Vue warn]: inject() can only be used inside setup() or functional components.
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, modalConfirm, modalError, modalDelete } = mixin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param catchE throw catch error message (e)
|
||||||
|
* @param q $q quasar dialog
|
||||||
|
* @returns no values return only pop-up dialog message for user
|
||||||
|
*/
|
||||||
|
const manageApiErrorMsg = (catchE: any, q: any) => {
|
||||||
|
// console.log(catchE);
|
||||||
|
// console.log(catchE.response);
|
||||||
|
// console.log(catchE.response.status);
|
||||||
|
// if (!catchE || !catchE.response || !catchE.response.data) {
|
||||||
|
// console.error("Invalid error object:", catchE);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
if (catchE.response.status == 401 || catchE.response.data.status == 401) {
|
||||||
|
modalError(q, "พบข้อผิดพลาด", "กรุณาล็อกอินใหม่อีกครั้ง"); //invalid_token
|
||||||
|
} else if (
|
||||||
|
catchE.response.data.status == 400 ||
|
||||||
|
catchE.response.data.status == 403 ||
|
||||||
|
catchE.response.data.status == 404
|
||||||
|
) {
|
||||||
|
//ใส่เป็น error กลางๆ ถ้ามีเคสให้เห็นมากขึ้น ถึงจะแยกข้อความได้
|
||||||
|
modalError(q, "พบข้อผิดพลาด", "ไม่พบข้อมูล");
|
||||||
|
} else {
|
||||||
|
modalError(q, "พบข้อผิดพลาด", catchE.response.data.message);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default manageApiErrorMsg;
|
||||||
22
src/hooks/filters.ts
Normal file
22
src/hooks/filters.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* GLOABL Filters
|
||||||
|
* - ไฟล์นี้จะไว้เก็บฟังก์ชันง่าย ๆ พวก Helper Functions ทั้งหลาย
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
const filters = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน compactNumber ใช้แปลงตัวเลขยาว ๆ ให้กลายเป็นเลขสั้น ๆ แบบที่พวก Social Media ชอบใช้กัน เช่น 1,000 แปลงเป็น 1K หรือ 1,000,000 แปลงเป็น 1M
|
||||||
|
* วิธีใช้ : {{ $filters.compactNumber(value) }}
|
||||||
|
*
|
||||||
|
* @param val รับค่าพารามิเตอร์เป็นตัวแปรชนิดตัวเลข
|
||||||
|
* @returns คืนค่าเป็นตัวเลขที่แปลงค่าแล้ว
|
||||||
|
*/
|
||||||
|
compactNumber (val: number) {
|
||||||
|
const formatter = Intl.NumberFormat('en', { notation: 'compact'})
|
||||||
|
return formatter.format(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default filters;
|
||||||
314
src/hooks/share.ts
Normal file
314
src/hooks/share.ts
Normal file
|
|
@ -0,0 +1,314 @@
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันกลาง
|
||||||
|
*/
|
||||||
|
|
||||||
|
function date2Thai(srcDate: Date, isFullMonth = false, isTime = false) {
|
||||||
|
if (srcDate == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const date = new Date(srcDate);
|
||||||
|
const isValidDate = Boolean(+date);
|
||||||
|
if (!isValidDate) return srcDate.toString();
|
||||||
|
if (isValidDate && date.getFullYear() < 1000) return srcDate.toString();
|
||||||
|
const fullMonthThai = [
|
||||||
|
"มกราคม",
|
||||||
|
"กุมภาพันธ์",
|
||||||
|
"มีนาคม",
|
||||||
|
"เมษายน",
|
||||||
|
"พฤษภาคม",
|
||||||
|
"มิถุนายน",
|
||||||
|
"กรกฎาคม",
|
||||||
|
"สิงหาคม",
|
||||||
|
"กันยายน",
|
||||||
|
"ตุลาคม",
|
||||||
|
"พฤศจิกายน",
|
||||||
|
"ธันวาคม",
|
||||||
|
];
|
||||||
|
const abbrMonthThai = [
|
||||||
|
"ม.ค.",
|
||||||
|
"ก.พ.",
|
||||||
|
"มี.ค.",
|
||||||
|
"เม.ย.",
|
||||||
|
"พ.ค.",
|
||||||
|
"มิ.ย.",
|
||||||
|
"ก.ค.",
|
||||||
|
"ส.ค.",
|
||||||
|
"ก.ย.",
|
||||||
|
"ต.ค.",
|
||||||
|
"พ.ย.",
|
||||||
|
"ธ.ค.",
|
||||||
|
];
|
||||||
|
let dstYear = 0;
|
||||||
|
if (date.getFullYear() > 2500) {
|
||||||
|
dstYear = date.getFullYear();
|
||||||
|
} else {
|
||||||
|
dstYear = date.getFullYear() + 543;
|
||||||
|
}
|
||||||
|
let dstMonth = "";
|
||||||
|
if (isFullMonth) {
|
||||||
|
dstMonth = fullMonthThai[date.getMonth()];
|
||||||
|
} else {
|
||||||
|
dstMonth = abbrMonthThai[date.getMonth()];
|
||||||
|
}
|
||||||
|
let dstTime = "";
|
||||||
|
if (isTime) {
|
||||||
|
const H =
|
||||||
|
date.getHours().toString().length === 1
|
||||||
|
? "0" + date.getHours()
|
||||||
|
: date.getHours();
|
||||||
|
const M =
|
||||||
|
date.getMinutes().toString().length === 1
|
||||||
|
? "0" + date.getMinutes()
|
||||||
|
: date.getMinutes();
|
||||||
|
// const S = date.getSeconds().toString().length === 1 ? "0" + date.getSeconds() : date.getSeconds()
|
||||||
|
// dstTime = " " + H + ":" + M + ":" + S + " น."
|
||||||
|
dstTime = " " + H + ":" + M + " น.";
|
||||||
|
}
|
||||||
|
return date.getDate() + " " + dstMonth + " " + dstYear + dstTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dateMonth2Thai(srcDate: Date, isFullMonth = false, isTime = false) {
|
||||||
|
if (!srcDate) return srcDate;
|
||||||
|
const date = new Date(srcDate);
|
||||||
|
const isValidDate = Boolean(+date);
|
||||||
|
if (!isValidDate) return srcDate;
|
||||||
|
if (isValidDate && date.getFullYear() < 1000) return srcDate;
|
||||||
|
const fullMonthThai = [
|
||||||
|
"มกราคม",
|
||||||
|
"กุมภาพันธ์",
|
||||||
|
"มีนาคม",
|
||||||
|
"เมษายน",
|
||||||
|
"พฤษภาคม",
|
||||||
|
"มิถุนายน",
|
||||||
|
"กรกฎาคม",
|
||||||
|
"สิงหาคม",
|
||||||
|
"กันยายน",
|
||||||
|
"ตุลาคม",
|
||||||
|
"พฤศจิกายน",
|
||||||
|
"ธันวาคม",
|
||||||
|
];
|
||||||
|
const abbrMonthThai = [
|
||||||
|
"ม.ค.",
|
||||||
|
"ก.พ.",
|
||||||
|
"มี.ค.",
|
||||||
|
"เม.ย.",
|
||||||
|
"พ.ค.",
|
||||||
|
"มิ.ย.",
|
||||||
|
"ก.ค.",
|
||||||
|
"ส.ค.",
|
||||||
|
"ก.ย.",
|
||||||
|
"ต.ค.",
|
||||||
|
"พ.ย.",
|
||||||
|
"ธ.ค.",
|
||||||
|
];
|
||||||
|
let dstYear = 0;
|
||||||
|
if (date.getFullYear() > 2500) {
|
||||||
|
dstYear = date.getFullYear();
|
||||||
|
} else {
|
||||||
|
dstYear = date.getFullYear() + 543;
|
||||||
|
}
|
||||||
|
let dstMonth = "";
|
||||||
|
if (isFullMonth) {
|
||||||
|
dstMonth = fullMonthThai[date.getMonth()];
|
||||||
|
} else {
|
||||||
|
dstMonth = abbrMonthThai[date.getMonth()];
|
||||||
|
}
|
||||||
|
let dstTime = "";
|
||||||
|
if (isTime) {
|
||||||
|
const H =
|
||||||
|
date.getHours().toString().length === 1
|
||||||
|
? "0" + date.getHours()
|
||||||
|
: date.getHours();
|
||||||
|
const M =
|
||||||
|
date.getMinutes().toString().length === 1
|
||||||
|
? "0" + date.getMinutes()
|
||||||
|
: date.getMinutes();
|
||||||
|
// const S = date.getSeconds().toString().length === 1 ? "0" + date.getSeconds() : date.getSeconds()
|
||||||
|
// dstTime = " " + H + ":" + M + ":" + S + " น."
|
||||||
|
dstTime = " " + H + ":" + M + " น.";
|
||||||
|
}
|
||||||
|
return date.getDate() + " " + dstMonth;
|
||||||
|
}
|
||||||
|
|
||||||
|
function monthYear2Thai(month: number, year: number, isFullMonth = false) {
|
||||||
|
const date = new Date(`${year}-${month + 1}-1`);
|
||||||
|
const fullMonthThai = [
|
||||||
|
"มกราคม",
|
||||||
|
"กุมภาพันธ์",
|
||||||
|
"มีนาคม",
|
||||||
|
"เมษายน",
|
||||||
|
"พฤษภาคม",
|
||||||
|
"มิถุนายน",
|
||||||
|
"กรกฎาคม",
|
||||||
|
"สิงหาคม",
|
||||||
|
"กันยายน",
|
||||||
|
"ตุลาคม",
|
||||||
|
"พฤศจิกายน",
|
||||||
|
"ธันวาคม",
|
||||||
|
];
|
||||||
|
const abbrMonthThai = [
|
||||||
|
"ม.ค.",
|
||||||
|
"ก.พ.",
|
||||||
|
"มี.ค.",
|
||||||
|
"เม.ย.",
|
||||||
|
"พ.ค.",
|
||||||
|
"มิ.ย.",
|
||||||
|
"ก.ค.",
|
||||||
|
"ส.ค.",
|
||||||
|
"ก.ย.",
|
||||||
|
"ต.ค.",
|
||||||
|
"พ.ย.",
|
||||||
|
"ธ.ค.",
|
||||||
|
];
|
||||||
|
let dstYear = 0;
|
||||||
|
if (date.getFullYear() > 2500) {
|
||||||
|
dstYear = date.getFullYear();
|
||||||
|
} else {
|
||||||
|
dstYear = date.getFullYear() + 543;
|
||||||
|
}
|
||||||
|
let dstMonth = "";
|
||||||
|
if (isFullMonth) {
|
||||||
|
dstMonth = fullMonthThai[date.getMonth()];
|
||||||
|
} else {
|
||||||
|
dstMonth = abbrMonthThai[date.getMonth()];
|
||||||
|
}
|
||||||
|
return dstMonth + " " + dstYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dateToISO(date: Date) {
|
||||||
|
return (
|
||||||
|
date.getFullYear() +
|
||||||
|
"-" +
|
||||||
|
appendLeadingZeroes(date.getMonth() + 1) +
|
||||||
|
"-" +
|
||||||
|
appendLeadingZeroes(date.getDate())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendLeadingZeroes(n: Number) {
|
||||||
|
if (n <= 9) return "0" + n;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
const success = (q: any, val: string) => {
|
||||||
|
// useQuasar ไม่สามารถใช้นอกไฟล์ .vue
|
||||||
|
if (val !== "") {
|
||||||
|
return q.notify({
|
||||||
|
message: val,
|
||||||
|
color: "primary",
|
||||||
|
icon: "mdi-information",
|
||||||
|
position: "bottom-right",
|
||||||
|
multiLine: true,
|
||||||
|
timeout: 1000,
|
||||||
|
badgeColor: "positive",
|
||||||
|
classes: "my-notif-class",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function notify(q: any, val: string) {
|
||||||
|
if (val !== "") {
|
||||||
|
q.notify({
|
||||||
|
color: "teal-10",
|
||||||
|
message: val,
|
||||||
|
icon: "mdi-information",
|
||||||
|
position: "bottom-right",
|
||||||
|
multiLine: true,
|
||||||
|
timeout: 7000,
|
||||||
|
actions: [{ label: "ปิด", color: "white", handler: () => {} }],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function notifyError(q: any, val: string) {
|
||||||
|
if (val !== "") {
|
||||||
|
q.notify({
|
||||||
|
color: "negative",
|
||||||
|
message: val,
|
||||||
|
icon: "mdi-alert-circle",
|
||||||
|
position: "top",
|
||||||
|
multiLine: true,
|
||||||
|
timeout: 12000,
|
||||||
|
actions: [{ label: "ปิด", color: "white", handler: () => {} }],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const dateText = (val: Date) => {
|
||||||
|
if (val != null) {
|
||||||
|
return date2Thai(val);
|
||||||
|
} else {
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const weekThai = (val: Number) => {
|
||||||
|
switch (val) {
|
||||||
|
case 0:
|
||||||
|
return "วันอาทิตย์";
|
||||||
|
case 1:
|
||||||
|
return "วันจันทร์";
|
||||||
|
case 2:
|
||||||
|
return "วันอังคาร";
|
||||||
|
case 3:
|
||||||
|
return "วันพุธ";
|
||||||
|
case 4:
|
||||||
|
return "วันพฤหัสบดี";
|
||||||
|
case 5:
|
||||||
|
return "วันศุกร์";
|
||||||
|
case 6:
|
||||||
|
return "วันเสาร์";
|
||||||
|
default:
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const genColor15 = (val: number) => {
|
||||||
|
val = val % 15;
|
||||||
|
switch (val) {
|
||||||
|
case 1:
|
||||||
|
return "pink";
|
||||||
|
case 2:
|
||||||
|
return "purple";
|
||||||
|
case 3:
|
||||||
|
return "deep-purple";
|
||||||
|
case 4:
|
||||||
|
return "indigo";
|
||||||
|
case 5:
|
||||||
|
return "blue";
|
||||||
|
case 6:
|
||||||
|
return "light-blue";
|
||||||
|
case 7:
|
||||||
|
return "cyan";
|
||||||
|
case 8:
|
||||||
|
return "teal";
|
||||||
|
case 9:
|
||||||
|
return "green";
|
||||||
|
case 10:
|
||||||
|
return "light-green";
|
||||||
|
case 11:
|
||||||
|
return "amber";
|
||||||
|
case 12:
|
||||||
|
return "orange";
|
||||||
|
case 13:
|
||||||
|
return "deep-orange";
|
||||||
|
case 14:
|
||||||
|
return "brown";
|
||||||
|
case 0:
|
||||||
|
return "blue-grey";
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
date2Thai,
|
||||||
|
dateToISO,
|
||||||
|
notify,
|
||||||
|
notifyError,
|
||||||
|
dateText,
|
||||||
|
monthYear2Thai,
|
||||||
|
dateMonth2Thai,
|
||||||
|
success,
|
||||||
|
weekThai,
|
||||||
|
genColor15,
|
||||||
|
};
|
||||||
281
src/interface/request/main/main.ts
Normal file
281
src/interface/request/main/main.ts
Normal file
|
|
@ -0,0 +1,281 @@
|
||||||
|
import { readonly } from "vue";
|
||||||
|
interface ScrollType {
|
||||||
|
position: number;
|
||||||
|
direction: string;
|
||||||
|
directionChanged: boolean;
|
||||||
|
inflectionPoint: number;
|
||||||
|
delta: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface tabType {
|
||||||
|
key: number;
|
||||||
|
label: string;
|
||||||
|
tag: string;
|
||||||
|
}
|
||||||
|
interface childrenType {
|
||||||
|
key: number;
|
||||||
|
label: string;
|
||||||
|
path?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface menuType {
|
||||||
|
key: number;
|
||||||
|
icon: string;
|
||||||
|
activeIcon: string;
|
||||||
|
label: string;
|
||||||
|
path: string;
|
||||||
|
children?: childrenType[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface notiType {
|
||||||
|
id: number;
|
||||||
|
sender: string;
|
||||||
|
body: string;
|
||||||
|
timereceive: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface optionType {
|
||||||
|
icon: string;
|
||||||
|
label: string;
|
||||||
|
value: string;
|
||||||
|
color: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const menuList = readonly<any[]>([
|
||||||
|
{
|
||||||
|
key: 1,
|
||||||
|
icon: "mdi-home-variant-outline",
|
||||||
|
activeIcon: "mdi-home-variant",
|
||||||
|
label: "หน้าแรก",
|
||||||
|
path: "dashboard",
|
||||||
|
role: "dashboard",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 2,
|
||||||
|
icon: "o_person",
|
||||||
|
activeIcon: "person",
|
||||||
|
label: "ข้อมูลหลัก",
|
||||||
|
path: "metadata",
|
||||||
|
role: "metadata",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 3,
|
||||||
|
icon: "o_groups",
|
||||||
|
activeIcon: "groups",
|
||||||
|
label: "โครงสร้างอัตรากำลัง",
|
||||||
|
path: "organizational",
|
||||||
|
role: "organization",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
key: 3.1,
|
||||||
|
label: "จัดการตำแหน่ง",
|
||||||
|
path: "organizationalMapping",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 3.2,
|
||||||
|
label: "แผนภูมิโครงสร้าง",
|
||||||
|
path: "organizationalStructChart",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 3.3,
|
||||||
|
label: "แผนภูมิองค์กร",
|
||||||
|
path: "organizationalOrgChart",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 3.4,
|
||||||
|
label: "ผังโครงสร้าง",
|
||||||
|
path: "organizationalTree",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 3.5,
|
||||||
|
label: "จัดการบัญชี 2",
|
||||||
|
path: "manageReport2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 3.6,
|
||||||
|
label: "รายงานบัญชี",
|
||||||
|
path: "organizationalReport",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 4,
|
||||||
|
icon: "o_contact_page",
|
||||||
|
activeIcon: "contact_page",
|
||||||
|
label: "ทะเบียนประวัติ",
|
||||||
|
path: "registry",
|
||||||
|
role: "registry",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 5,
|
||||||
|
icon: "o_search",
|
||||||
|
activeIcon: "search",
|
||||||
|
label: "สรรหา",
|
||||||
|
path: "recruiting",
|
||||||
|
role: "recruit",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: "ตั้งค่าเว็บสรรหา",
|
||||||
|
path: "editorweb",
|
||||||
|
key: 5.1,
|
||||||
|
role: "recruit",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "สอบแข่งขัน",
|
||||||
|
path: "",
|
||||||
|
key: 5.2,
|
||||||
|
role: "recruit",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: "จัดการข้อมูลผู้สมัครสอบ" /* แข่งขัน */,
|
||||||
|
path: "competePeriod",
|
||||||
|
role: "recruit",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "ข้อมูลสถิติการสมัครสอบ" /* แข่งขัน */,
|
||||||
|
path: "competePeriodStat",
|
||||||
|
role: "recruit",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "คัดเลือก",
|
||||||
|
path: "",
|
||||||
|
key: 5.3,
|
||||||
|
role: "recruit",
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
label: "จัดการรอบคัดเลือก",
|
||||||
|
path: "qualifyPeriod",
|
||||||
|
role: "recruit",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "จัดการรอบคัดเลือกคนพิการ",
|
||||||
|
path: "disablePeriod",
|
||||||
|
role: "recruit",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "จัดการรายชื่อคัดเลือก",
|
||||||
|
path: "manage",
|
||||||
|
role: "recruit",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "สถิติสมัครคัดเลือก",
|
||||||
|
path: "qualifyPeriodStat",
|
||||||
|
role: "recruit",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "สถิติสมัครคัดเลือกคนพิการ",
|
||||||
|
path: "qualifyPeriodStatDisable",
|
||||||
|
role: "recruit",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 6,
|
||||||
|
icon: "mdi-home-variant-outline",
|
||||||
|
activeIcon: "mdi-home-variant",
|
||||||
|
label: "บรรจุ แต่งตั้ง ย้าย โอน",
|
||||||
|
path: "placement",
|
||||||
|
role: "placement",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 7,
|
||||||
|
icon: "mdi-home-variant-outline",
|
||||||
|
activeIcon: "mdi-home-variant",
|
||||||
|
label: "พ้นจากราชการ",
|
||||||
|
path: "retirement",
|
||||||
|
role: "retirement",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 8,
|
||||||
|
icon: "mdi-home-variant-outline",
|
||||||
|
activeIcon: "mdi-home-variant",
|
||||||
|
label: "เครื่องราชอิสริยาภรณ์",
|
||||||
|
path: "insignia",
|
||||||
|
role: "insignia",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const tabList = readonly<tabType[]>([
|
||||||
|
{
|
||||||
|
key: 1,
|
||||||
|
label: "ข้อมูลทั่วไป",
|
||||||
|
tag: "information",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 15,
|
||||||
|
label: "ใบอนุญาตประกอบอาชีพ",
|
||||||
|
tag: "certicate",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 2,
|
||||||
|
label: "ประวัติการศึกษา",
|
||||||
|
tag: "education",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 3,
|
||||||
|
label: "การฝึกอบรม/ดูงาน",
|
||||||
|
tag: "training",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 4,
|
||||||
|
label: "เครื่องราชอิสริยาภรณ์",
|
||||||
|
tag: "insignia",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 5,
|
||||||
|
label: "ประกาศเกียรติคุณ",
|
||||||
|
tag: "coined",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 6,
|
||||||
|
label: "ผลการประเมินปฏิบัติราชการ",
|
||||||
|
tag: "assessment",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 7,
|
||||||
|
label: "ตำแหน่ง/เงินเดือน",
|
||||||
|
tag: "position",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 8,
|
||||||
|
label: "วินัย",
|
||||||
|
tag: "rule",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 9,
|
||||||
|
label: "การลา",
|
||||||
|
tag: "leave",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 10,
|
||||||
|
label: "ความสามารถพิเศษ",
|
||||||
|
tag: "talent",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 11,
|
||||||
|
label: "ปฎิบัติราชการพิเศษ",
|
||||||
|
tag: "work",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 12,
|
||||||
|
label: "บันทึกวันที่ไม่ได้รับเงินเดือนฯ",
|
||||||
|
tag: "record",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 13,
|
||||||
|
label: "อื่นๆ",
|
||||||
|
tag: "other",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 14,
|
||||||
|
label: "เอกสารหลักฐาน",
|
||||||
|
tag: "document",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
export { menuList, tabList };
|
||||||
|
export type { ScrollType, tabType, menuType, notiType, optionType };
|
||||||
46
src/interface/request/manage/prefix.ts
Normal file
46
src/interface/request/manage/prefix.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
//response api เกี่ยวกับ status code กับ error
|
||||||
|
interface RequestHistoryObject {
|
||||||
|
message: String;
|
||||||
|
result: ResultHistoryObject;
|
||||||
|
status: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
//rusult แนบ id version mongo
|
||||||
|
interface ResultHistoryObject {
|
||||||
|
id: String;
|
||||||
|
items: RequestPrefixHistoryObject;
|
||||||
|
version: String;
|
||||||
|
}
|
||||||
|
|
||||||
|
//ข้อมูล คำนำหน้า
|
||||||
|
interface RequestPrefixHistoryObject {
|
||||||
|
createdAt?: Date;
|
||||||
|
createdFullName: String;
|
||||||
|
createdUserId: String;
|
||||||
|
id: String;
|
||||||
|
isActive: Boolean;
|
||||||
|
lastUpdateFullName: String;
|
||||||
|
lastUpdateUserId: String;
|
||||||
|
lastUpdatedAt?: Date;
|
||||||
|
name: String;
|
||||||
|
}
|
||||||
|
|
||||||
|
//columns
|
||||||
|
interface PrefixColumns {
|
||||||
|
[index: number]: {
|
||||||
|
name: String;
|
||||||
|
align: String;
|
||||||
|
label: String;
|
||||||
|
sortable: Boolean;
|
||||||
|
field: String;
|
||||||
|
headerStyle: String;
|
||||||
|
style: String;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export type {
|
||||||
|
RequestHistoryObject,
|
||||||
|
ResultHistoryObject,
|
||||||
|
RequestPrefixHistoryObject,
|
||||||
|
PrefixColumns,
|
||||||
|
};
|
||||||
14
src/interface/response/manage/prefix.ts
Normal file
14
src/interface/response/manage/prefix.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
//ข้อมูล คำนำหน้า
|
||||||
|
interface ResponsePrefixHistoryObject {
|
||||||
|
createdAt?: Date;
|
||||||
|
createdFullName: String;
|
||||||
|
createdUserId: String;
|
||||||
|
id: String;
|
||||||
|
isActive: Boolean;
|
||||||
|
lastUpdateFullName: String;
|
||||||
|
lastUpdateUserId: String;
|
||||||
|
lastUpdatedAt?: Date;
|
||||||
|
name: String;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type { ResponsePrefixHistoryObject };
|
||||||
71
src/main.ts
Normal file
71
src/main.ts
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
import { createApp, defineAsyncComponent } from "vue";
|
||||||
|
import App from "./App.vue";
|
||||||
|
import router from "./router";
|
||||||
|
import { Dialog, Notify, Quasar } from "quasar";
|
||||||
|
import quasarUserOptions from "./quasar-user-options";
|
||||||
|
|
||||||
|
import "quasar/src/css/index.sass";
|
||||||
|
import th from "quasar/lang/th";
|
||||||
|
|
||||||
|
import "@vuepic/vue-datepicker/dist/main.css";
|
||||||
|
import http from "./plugins/http";
|
||||||
|
import { createPinia } from "pinia";
|
||||||
|
// organization
|
||||||
|
// position
|
||||||
|
// positionEmployee
|
||||||
|
//calendar
|
||||||
|
// insignia
|
||||||
|
|
||||||
|
// import './assets/main.css'
|
||||||
|
|
||||||
|
// Import GlobalFilters
|
||||||
|
import filters from "./hooks/filters";
|
||||||
|
|
||||||
|
const app = createApp(App);
|
||||||
|
const pinia = createPinia();
|
||||||
|
|
||||||
|
// เพิ่ม Global Filters ลงใน App
|
||||||
|
app.config.globalProperties.$filters = filters;
|
||||||
|
|
||||||
|
app.use(router);
|
||||||
|
app.use(pinia);
|
||||||
|
|
||||||
|
app.use(
|
||||||
|
Quasar,
|
||||||
|
{
|
||||||
|
plugins: {
|
||||||
|
Notify,
|
||||||
|
Dialog,
|
||||||
|
}, // import Quasar plugins and add here
|
||||||
|
config: {
|
||||||
|
notify: {
|
||||||
|
/* look at QuasarConfOptions from the API card */
|
||||||
|
},
|
||||||
|
},
|
||||||
|
lang: th,
|
||||||
|
}
|
||||||
|
// quasarUserOptions // build ไม่ผ่านหลัง install code org&structure chart เลยต้องคอมเม้นไว้ก่อน เทสแล้วยังรันได้หลังคอมเม้น
|
||||||
|
);
|
||||||
|
|
||||||
|
//** Global Components */
|
||||||
|
app.component(
|
||||||
|
"data-table",
|
||||||
|
defineAsyncComponent(() => import("./components/TableView.vue"))
|
||||||
|
);
|
||||||
|
app.component(
|
||||||
|
"datepicker",
|
||||||
|
defineAsyncComponent(() => import("@vuepic/vue-datepicker"))
|
||||||
|
);
|
||||||
|
app.component(
|
||||||
|
"full-loader",
|
||||||
|
defineAsyncComponent(() => import("./plugins/FullLoader.vue"))
|
||||||
|
);
|
||||||
|
|
||||||
|
app.component(
|
||||||
|
"selector",
|
||||||
|
defineAsyncComponent(() => import("./components/Selector.vue"))
|
||||||
|
);
|
||||||
|
|
||||||
|
app.config.globalProperties.$http = http;
|
||||||
|
|
||||||
|
app.mount("#app");
|
||||||
859
src/modules/01_metadata/components/Calendar.vue
Normal file
859
src/modules/01_metadata/components/Calendar.vue
Normal file
|
|
@ -0,0 +1,859 @@
|
||||||
|
<!-- tab ปฏิทิน หน้าปฏิทินวันหยุด -->
|
||||||
|
<template>
|
||||||
|
<div class="q-mt-md">
|
||||||
|
<div class="row q-gutter-sm q-pb-sm main-content">
|
||||||
|
<div class="demo-app-main">
|
||||||
|
<!-- แสดงปฏิทิน -->
|
||||||
|
<FullCalendar
|
||||||
|
ref="fullCalendar"
|
||||||
|
class="demo-app-calendar"
|
||||||
|
:options="calendarOptions"
|
||||||
|
>
|
||||||
|
<template v-slot:eventContent="arg">
|
||||||
|
<b>{{ arg.timeText }}</b>
|
||||||
|
<i>{{ arg.event.title }}</i>
|
||||||
|
<q-tooltip style="font-size: 15px">{{ arg.event.title }}</q-tooltip>
|
||||||
|
</template>
|
||||||
|
</FullCalendar>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row q-col-gutter-md">
|
||||||
|
<div class="items-center row">
|
||||||
|
<q-icon color="blue" name="mdi-circle" class="q-mr-sm" />
|
||||||
|
วันทำงาน 5 วัน
|
||||||
|
</div>
|
||||||
|
<div class="items-center row">
|
||||||
|
<q-icon color="orange" name="mdi-circle" class="q-mr-sm" />
|
||||||
|
วันทำงาน 6 วัน
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- modal เพิ่มวันหยุด -->
|
||||||
|
<q-dialog v-model="modalAdd" persistent>
|
||||||
|
<q-card style="min-width: 550px">
|
||||||
|
<q-form ref="formDate" @submit.prevent.stop="onSubmit">
|
||||||
|
<q-card-section class="row items-center q-pa-sm">
|
||||||
|
<div class="text-bold" v-if="showEdit">แก้ไขวันหยุด</div>
|
||||||
|
<div class="text-bold" v-else>เพิ่มวันหยุด</div>
|
||||||
|
<q-space />
|
||||||
|
<q-btn
|
||||||
|
icon="close"
|
||||||
|
unelevated
|
||||||
|
round
|
||||||
|
dense
|
||||||
|
v-close-popup
|
||||||
|
style="color: #ff8080; background-color: #ffdede"
|
||||||
|
/>
|
||||||
|
</q-card-section>
|
||||||
|
<q-separator />
|
||||||
|
<q-card-section class="q-p-md row q-gutter-y-md">
|
||||||
|
<div class="row col-12">
|
||||||
|
<div class="col-12" v-if="!showEdit">
|
||||||
|
{{ dateThaiRange(dateRange) }}
|
||||||
|
</div>
|
||||||
|
<datepicker
|
||||||
|
v-else
|
||||||
|
:readonly="!edit"
|
||||||
|
v-model="dateRange"
|
||||||
|
:locale="'th'"
|
||||||
|
autoApply
|
||||||
|
range
|
||||||
|
:enableTimePicker="false"
|
||||||
|
week-start="0"
|
||||||
|
>
|
||||||
|
<template #year="{ year }">
|
||||||
|
{{ year + 543 }}
|
||||||
|
</template>
|
||||||
|
<template #year-overlay-value="{ value }">
|
||||||
|
{{ parseInt(value + 543) }}
|
||||||
|
</template>
|
||||||
|
<template #trigger>
|
||||||
|
<q-input
|
||||||
|
:class="getClass(edit)"
|
||||||
|
hide-bottom-space
|
||||||
|
:outlined="edit"
|
||||||
|
dense
|
||||||
|
label="วันที่"
|
||||||
|
lazy-rules
|
||||||
|
:borderless="!edit"
|
||||||
|
:model-value="dateThaiRange(dateRange)"
|
||||||
|
>
|
||||||
|
<template v-slot:prepend>
|
||||||
|
<q-icon
|
||||||
|
name="event"
|
||||||
|
class="cursor-pointer"
|
||||||
|
style="color: var(--q-primary)"
|
||||||
|
>
|
||||||
|
</q-icon>
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
</template>
|
||||||
|
</datepicker>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<q-input
|
||||||
|
:class="getClass(edit)"
|
||||||
|
hide-bottom-space
|
||||||
|
:outlined="edit"
|
||||||
|
label="คำอธิบาย"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
:readonly="!edit"
|
||||||
|
:borderless="!edit"
|
||||||
|
v-model="name"
|
||||||
|
autogrow
|
||||||
|
:rules="[(val) => (val && val.length > 0) || '']"
|
||||||
|
/>
|
||||||
|
<q-option-group
|
||||||
|
v-if="showEdit == false"
|
||||||
|
v-model="category"
|
||||||
|
:options="categoryOptions"
|
||||||
|
color="primary"
|
||||||
|
inline
|
||||||
|
/>
|
||||||
|
</q-card-section>
|
||||||
|
<q-separator />
|
||||||
|
<q-card-actions align="right" class="text-primary">
|
||||||
|
<q-btn
|
||||||
|
v-if="showEdit && edit"
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
outline
|
||||||
|
color="red"
|
||||||
|
@click="cancelClick()"
|
||||||
|
icon="mdi-undo"
|
||||||
|
>
|
||||||
|
<q-tooltip>ยกเลิก</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
<q-btn
|
||||||
|
v-if="edit"
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
color="public"
|
||||||
|
icon="mdi-content-save-outline"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
<q-tooltip>บันทึก</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
<q-btn
|
||||||
|
v-if="!edit"
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
color="primary"
|
||||||
|
@click="editClick"
|
||||||
|
icon="mdi-pencil-outline"
|
||||||
|
>
|
||||||
|
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
<q-btn
|
||||||
|
v-if="showEdit && edit"
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
outline
|
||||||
|
color="red"
|
||||||
|
@click="deleteClick()"
|
||||||
|
icon="mdi-delete"
|
||||||
|
>
|
||||||
|
<q-tooltip>ลบ</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-form>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
|
||||||
|
<!-- modal ลบวันหยุด -->
|
||||||
|
<q-dialog v-model="modalDelete" persistent>
|
||||||
|
<q-card style="min-width: 550px">
|
||||||
|
<q-card-section class="row items-center q-pb-xs">
|
||||||
|
<div class="text-bold">ต้องการลบข้อมูลนี้หรือไม่?</div>
|
||||||
|
<q-space />
|
||||||
|
<q-btn
|
||||||
|
icon="close"
|
||||||
|
unelevated
|
||||||
|
round
|
||||||
|
dense
|
||||||
|
v-close-popup
|
||||||
|
style="color: #ff8080; background-color: #ffdede"
|
||||||
|
/>
|
||||||
|
</q-card-section>
|
||||||
|
<q-separator />
|
||||||
|
<q-card-section class="row items-center">
|
||||||
|
<div class="q-pr-md">
|
||||||
|
<q-avatar
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
font-size="25px"
|
||||||
|
size="lg"
|
||||||
|
color="red-1"
|
||||||
|
text-color="red"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col text-dark">
|
||||||
|
<span>ข้อมูลที่กำลังถูกลบนี้จะมีผลใช้งานทันที</span>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
<q-separator />
|
||||||
|
<q-card-actions align="right" class="bg-white text-teal">
|
||||||
|
<q-btn label="ยกเลิก" flat color="grey-8" @click="cancelClick" />
|
||||||
|
<q-btn label="ตกลง" color="primary" @click="deleteData" />
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import FullCalendar from "@fullcalendar/vue3";
|
||||||
|
import dayGridPlugin from "@fullcalendar/daygrid";
|
||||||
|
import timeGridPlugin from "@fullcalendar/timegrid";
|
||||||
|
import interactionPlugin from "@fullcalendar/interaction";
|
||||||
|
import allLocales from "@fullcalendar/core/locales-all";
|
||||||
|
import listPlugin from "@fullcalendar/list";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import type {
|
||||||
|
RequestItemsObject,
|
||||||
|
DataDateRowObject,
|
||||||
|
DataDateAddObject,
|
||||||
|
} from "@/modules/01_metadata/interface/request/Calendar";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
dateYear: {
|
||||||
|
//filter ปี วันหยุด
|
||||||
|
type: Number,
|
||||||
|
default: () => new Date().getFullYear(),
|
||||||
|
},
|
||||||
|
dateMonth: {
|
||||||
|
//filter เดือน วันหยุด
|
||||||
|
type: Number,
|
||||||
|
default: () => new Date().getMonth(),
|
||||||
|
},
|
||||||
|
refreshData: {
|
||||||
|
//หน้า main มีการอัพเดทค่าให้ refresh data
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
fetchDataSummaryCalendar: {
|
||||||
|
//ฟังก์ชันอัพเดทสรุปวันหยุด
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const store = useDataStore();
|
||||||
|
const { loaderPage } = store;
|
||||||
|
const mixin = useCounterMixin(); //เรียกฟังก์ชันกลาง
|
||||||
|
const { success, dateToISO, date2Thai, messageError } = mixin;
|
||||||
|
const $q = useQuasar(); //ใช้ noti quasar
|
||||||
|
const modalAdd = ref<boolean>(false); //modal เพิ่มวันหยุด
|
||||||
|
const modalDelete = ref<boolean>(false); //modal ลบวันหยุด
|
||||||
|
const edit = ref<boolean>(false); //modal เลือกวันหยุดกับวันลบวันหยุด
|
||||||
|
const showEdit = ref<boolean>(false); //กด event แก้ไขหรือเพิ่ม
|
||||||
|
const name = ref<string>(""); //ชื่อวันหยุด
|
||||||
|
const type = ref<string>(""); //ประเภทวันหยุด
|
||||||
|
const isSpecial = ref<boolean>(true); //เช็ควันหยุด
|
||||||
|
const id = ref<string>(""); //id ที่แก้ไขวันหยุด
|
||||||
|
const fullCalendar = ref<any>(); //ref calendar
|
||||||
|
const dateRange = ref<[Date, Date]>([new Date(), new Date()]); //วันที่ ที่เพิ่มเป็นวันหยุด
|
||||||
|
const formDate = ref<any>(); //ref เพิ่ม แก้ไข วันหยุดสำหรับ validate
|
||||||
|
|
||||||
|
const category = ref<string>("all");
|
||||||
|
const categoryOptions = ref<any>([
|
||||||
|
{
|
||||||
|
label: "ทั้งหมด",
|
||||||
|
value: "all",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "ทำงาน 5 วัน",
|
||||||
|
value: "normal",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "ทำงาน 6 วัน",
|
||||||
|
value: "6days",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const dataHistory = ref<RequestItemsObject[]>([]);
|
||||||
|
const dataNormalRaw = ref<RequestItemsObject[]>([]);
|
||||||
|
const dataSixDaysRaw = ref<RequestItemsObject[]>([]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เรียกฟังก์ชันทั้งหมดตอนเรียกใช้ไฟล์นี้
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
const calen = fullCalendar.value.getApi();
|
||||||
|
const date = new Date(props.dateYear, props.dateMonth);
|
||||||
|
calen.gotoDate(date);
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ค่า props(วันเดือนปีที่เลือก) ตอนอัพเดท ค่าฏิทินให้อัพเดทใหม่
|
||||||
|
*/
|
||||||
|
watch(props, async (count, prevCount) => {
|
||||||
|
const calen = fullCalendar.value.getApi();
|
||||||
|
const date = new Date(props.dateYear, props.dateMonth);
|
||||||
|
calen.gotoDate(date);
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เลือกค่าปฏิทินในช่องว่าง
|
||||||
|
* @param selectInfo ค่าที่เลือกในฏิทิน
|
||||||
|
*/
|
||||||
|
const handleDateSelect = async (selectInfo: any) => {
|
||||||
|
edit.value = true;
|
||||||
|
category.value = "all";
|
||||||
|
selectInfo.start;
|
||||||
|
const checkNormalDate = dataNormalRaw.value.filter(
|
||||||
|
(r: RequestItemsObject) =>
|
||||||
|
dateToISO(new Date(r.holidayDate)) == dateToISO(selectInfo.start)
|
||||||
|
);
|
||||||
|
const checkSixDaysDate = dataSixDaysRaw.value.filter(
|
||||||
|
(r: RequestItemsObject) =>
|
||||||
|
dateToISO(new Date(r.holidayDate)) == dateToISO(selectInfo.start)
|
||||||
|
);
|
||||||
|
if (checkNormalDate.length == 0 || checkSixDaysDate.length == 0) {
|
||||||
|
name.value = "";
|
||||||
|
isSpecial.value = true;
|
||||||
|
dateRange.value = [
|
||||||
|
selectInfo.startStr,
|
||||||
|
new Date(
|
||||||
|
new Date(selectInfo.endStr).setDate(
|
||||||
|
new Date(selectInfo.endStr).getDate() - 1
|
||||||
|
)
|
||||||
|
),
|
||||||
|
];
|
||||||
|
showEdit.value = false;
|
||||||
|
modalAdd.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เลือกค่า event ในปฏิทิน
|
||||||
|
* @param selectInfo ค่าที่เลือกในฏิทิน
|
||||||
|
*/
|
||||||
|
const handleEventClick = async (selectInfo: any) => {
|
||||||
|
modalAdd.value = true;
|
||||||
|
edit.value = false;
|
||||||
|
showEdit.value = true;
|
||||||
|
name.value = selectInfo.event.title;
|
||||||
|
type.value = selectInfo.event.id;
|
||||||
|
isSpecial.value = true;
|
||||||
|
id.value = selectInfo.event.groupId;
|
||||||
|
dataHistory.value = selectInfo.event.extendedProps.dataRangeRow;
|
||||||
|
dateRange.value = [
|
||||||
|
selectInfo.event.startStr,
|
||||||
|
selectInfo.event.endStr == ""
|
||||||
|
? selectInfo.event.startStr
|
||||||
|
: dateToISO(
|
||||||
|
new Date(
|
||||||
|
new Date(selectInfo.event.endStr).setDate(
|
||||||
|
new Date(selectInfo.event.endStr).getDate() - 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* กดปุ่มแก้ไขให้แสดง modal แก้ไข
|
||||||
|
*/
|
||||||
|
const editClick = async () => {
|
||||||
|
showEdit.value = true;
|
||||||
|
edit.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* กดปุ่มลบให้แสดง modal ลบ
|
||||||
|
*/
|
||||||
|
const deleteClick = async () => {
|
||||||
|
modalDelete.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ปุ่มยกเลิกให้ย้อนกลับไป modal เลือกแก้ไขหรือลบ
|
||||||
|
*/
|
||||||
|
const cancelClick = async () => {
|
||||||
|
modalDelete.value = false;
|
||||||
|
modalAdd.value = true;
|
||||||
|
edit.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* option calendar
|
||||||
|
*/
|
||||||
|
const calendarOptions = ref<any>({
|
||||||
|
plugins: [
|
||||||
|
dayGridPlugin,
|
||||||
|
timeGridPlugin,
|
||||||
|
interactionPlugin, // needed for dateClick
|
||||||
|
listPlugin,
|
||||||
|
],
|
||||||
|
headerToolbar: null,
|
||||||
|
selectable: true,
|
||||||
|
select: handleDateSelect,
|
||||||
|
eventClick: handleEventClick,
|
||||||
|
locale: "th",
|
||||||
|
locales: allLocales,
|
||||||
|
height: "100%",
|
||||||
|
eventColor: "#e4f3ff",
|
||||||
|
eventTextColor: "#50a5fc",
|
||||||
|
eventBorderColor: "#50a5fc",
|
||||||
|
events: <any>[],
|
||||||
|
firstDay: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ปุ่มบันทึกข้อมูลวันหยุด
|
||||||
|
*/
|
||||||
|
const onSubmit = async () => {
|
||||||
|
if (showEdit.value === true) {
|
||||||
|
await editData();
|
||||||
|
} else {
|
||||||
|
await addDate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fetch วันหยุดในปฏิทิน
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
calendarOptions.value.events = [];
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(
|
||||||
|
config.API.listHolidayHistoryYearMonth(
|
||||||
|
props.dateYear,
|
||||||
|
props.dateMonth + 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
const dataNormal = res.data.result.normal;
|
||||||
|
const dataSixDays = res.data.result.sixDays;
|
||||||
|
const dateStart = ref<Date | null>();
|
||||||
|
const firstEvent = ref<boolean>(true);
|
||||||
|
const dateRow = ref<DataDateRowObject[]>([]);
|
||||||
|
dataNormalRaw.value = res.data.result.normal;
|
||||||
|
dataSixDaysRaw.value = res.data.result.sixDays;
|
||||||
|
dataNormal.map((e: RequestItemsObject, index: number) => {
|
||||||
|
dateRow.value.push({
|
||||||
|
holidayDate: new Date(e.holidayDate),
|
||||||
|
name: e.name,
|
||||||
|
isSpecial: true,
|
||||||
|
id: e.id,
|
||||||
|
});
|
||||||
|
if (
|
||||||
|
index == dataNormal.length - 1 ||
|
||||||
|
dataNormal[index + 1].name != e.name ||
|
||||||
|
(dataNormal[index + 1].name == e.name &&
|
||||||
|
dateToISO(new Date(dataNormal[index + 1].holidayDate)) !=
|
||||||
|
dateToISO(
|
||||||
|
new Date(
|
||||||
|
new Date(e.holidayDate).setDate(
|
||||||
|
new Date(e.holidayDate).getDate() + 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
))
|
||||||
|
) {
|
||||||
|
firstEvent.value = true;
|
||||||
|
calendarOptions.value.events.push({
|
||||||
|
id: "normal",
|
||||||
|
groupId: e.id,
|
||||||
|
title:
|
||||||
|
dateToISO(new Date(e.holidayDate)) ==
|
||||||
|
dateToISO(new Date(e.originalDate))
|
||||||
|
? e.name
|
||||||
|
: `ชดเชย ${e.name}`,
|
||||||
|
start: dateStart.value ? dateStart.value : new Date(e.holidayDate),
|
||||||
|
end: new Date(
|
||||||
|
new Date(e.holidayDate).setDate(
|
||||||
|
new Date(e.holidayDate).getDate() + 1
|
||||||
|
)
|
||||||
|
),
|
||||||
|
isSpecial: true,
|
||||||
|
allDay: true,
|
||||||
|
dataRangeRow: dateRow.value,
|
||||||
|
backgroundColor: "#CCE5FF",
|
||||||
|
textColor: "#0080FF",
|
||||||
|
});
|
||||||
|
dateStart.value = null;
|
||||||
|
dateRow.value = [];
|
||||||
|
} else if (firstEvent.value == true) {
|
||||||
|
firstEvent.value = false;
|
||||||
|
dateStart.value = new Date(e.holidayDate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dataSixDays.map((e: RequestItemsObject, index: number) => {
|
||||||
|
dateRow.value.push({
|
||||||
|
holidayDate: new Date(e.holidayDate),
|
||||||
|
name: e.name,
|
||||||
|
isSpecial: true,
|
||||||
|
id: e.id,
|
||||||
|
});
|
||||||
|
if (
|
||||||
|
index == dataSixDays.length - 1 ||
|
||||||
|
dataSixDays[index + 1].name != e.name ||
|
||||||
|
(dataSixDays[index + 1].name == e.name &&
|
||||||
|
dateToISO(new Date(dataSixDays[index + 1].holidayDate)) !=
|
||||||
|
dateToISO(
|
||||||
|
new Date(
|
||||||
|
new Date(e.holidayDate).setDate(
|
||||||
|
new Date(e.holidayDate).getDate() + 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
))
|
||||||
|
) {
|
||||||
|
firstEvent.value = true;
|
||||||
|
calendarOptions.value.events.push({
|
||||||
|
id: "sixdays",
|
||||||
|
groupId: e.id,
|
||||||
|
title:
|
||||||
|
dateToISO(new Date(e.holidayDate)) ==
|
||||||
|
dateToISO(new Date(e.originalDate))
|
||||||
|
? e.name
|
||||||
|
: `ชดเชย ${e.name}`,
|
||||||
|
start: dateStart.value ? dateStart.value : new Date(e.holidayDate),
|
||||||
|
end: new Date(
|
||||||
|
new Date(e.holidayDate).setDate(
|
||||||
|
new Date(e.holidayDate).getDate() + 1
|
||||||
|
)
|
||||||
|
),
|
||||||
|
isSpecial: true,
|
||||||
|
allDay: true,
|
||||||
|
dataRangeRow: dateRow.value,
|
||||||
|
backgroundColor: "#FFE5CC",
|
||||||
|
textColor: "#FF8000",
|
||||||
|
});
|
||||||
|
dateStart.value = null;
|
||||||
|
dateRow.value = [];
|
||||||
|
} else if (firstEvent.value == true) {
|
||||||
|
firstEvent.value = false;
|
||||||
|
dateStart.value = new Date(e.holidayDate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await props.fetchDataSummaryCalendar();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* บันทึกแก้ไขวันหยุด
|
||||||
|
*/
|
||||||
|
const editData = async () => {
|
||||||
|
await formDate.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
const dataEdit = ref<DataDateAddObject[]>([]);
|
||||||
|
let i = 0;
|
||||||
|
const dateStart = ref<Date>(dateRange.value[0]);
|
||||||
|
do {
|
||||||
|
i = i + 1;
|
||||||
|
dataEdit.value.push({
|
||||||
|
year: new Date(dateStart.value).getFullYear(),
|
||||||
|
holidayDate: dateToISO(new Date(dateStart.value)),
|
||||||
|
name: name.value,
|
||||||
|
isSpecial: true,
|
||||||
|
});
|
||||||
|
dateStart.value = new Date(
|
||||||
|
new Date(dateStart.value).setDate(
|
||||||
|
new Date(dateStart.value).getDate() + 1
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} while (new Date(dateStart.value) <= new Date(dateRange.value[1]));
|
||||||
|
|
||||||
|
const _dataHistory = ref<RequestItemsObject[]>([]);
|
||||||
|
dataHistory.value.map((e: RequestItemsObject, index: number) => {
|
||||||
|
_dataHistory.value.push({
|
||||||
|
...e,
|
||||||
|
holidayDate: dateToISO(new Date(e.holidayDate)),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listHolidayHistoryEdit(type.value), {
|
||||||
|
history: _dataHistory.value,
|
||||||
|
updated: dataEdit.value,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
modalAdd.value = false;
|
||||||
|
success($q, "แก้ไขข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* บันทึกเพิ่มวันหยุด
|
||||||
|
*/
|
||||||
|
const addDate = async () => {
|
||||||
|
await formDate.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
const dataAdd = ref<DataDateAddObject[]>([]);
|
||||||
|
let i = 0;
|
||||||
|
const dateStart = ref<Date>(dateRange.value[0]);
|
||||||
|
do {
|
||||||
|
i = i + 1;
|
||||||
|
dataAdd.value.push({
|
||||||
|
year: new Date(dateStart.value).getFullYear(),
|
||||||
|
holidayDate: dateToISO(new Date(dateStart.value)),
|
||||||
|
name: name.value,
|
||||||
|
isSpecial: true,
|
||||||
|
});
|
||||||
|
dateStart.value = new Date(
|
||||||
|
new Date(dateStart.value).setDate(
|
||||||
|
new Date(dateStart.value).getDate() + 1
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} while (new Date(dateStart.value) <= new Date(dateRange.value[1]));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listHolidayHistoryAdd(category.value), dataAdd.value)
|
||||||
|
.then((res) => {
|
||||||
|
modalAdd.value = false;
|
||||||
|
success($q, "เพิ่มข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ลบข้อมูลวันหยุด
|
||||||
|
*/
|
||||||
|
const deleteData = async () => {
|
||||||
|
modalDelete.value = false;
|
||||||
|
const dataDelete = ref<DataDateAddObject[]>([]);
|
||||||
|
let i = 0;
|
||||||
|
const dateStart = ref<Date>(dateRange.value[0]);
|
||||||
|
do {
|
||||||
|
i = i + 1;
|
||||||
|
dataDelete.value.push({
|
||||||
|
year: new Date(dateStart.value).getFullYear(),
|
||||||
|
holidayDate: dateToISO(new Date(dateStart.value)),
|
||||||
|
name: name.value,
|
||||||
|
isSpecial: true,
|
||||||
|
});
|
||||||
|
dateStart.value = new Date(
|
||||||
|
new Date(dateStart.value).setDate(new Date(dateStart.value).getDate() + 1)
|
||||||
|
);
|
||||||
|
} while (new Date(dateStart.value) <= new Date(dateRange.value[1]));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listHolidayHistoryDelete(type.value), dataDelete.value)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
modalAdd.value = false;
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แปลงช่วงวันที่ถ้า2ค่าเป็นวันเดียวกันจะโชววันเดียวแต่ถ้าไม่เท่ากันจะแสดงเป็นช่วง
|
||||||
|
* @param val ช่วงวันที่
|
||||||
|
*/
|
||||||
|
const dateThaiRange = (val: [Date, Date]) => {
|
||||||
|
if (val === null) {
|
||||||
|
} else if (date2Thai(val[0]) === date2Thai(val[1])) {
|
||||||
|
return `${date2Thai(val[0])}`;
|
||||||
|
} else {
|
||||||
|
return `${date2Thai(val[0])} - ${date2Thai(val[1])} `;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getClass = (val: boolean) => {
|
||||||
|
return {
|
||||||
|
"full-width inputgreen cursor-pointer": val,
|
||||||
|
"full-width cursor-pointer": !val,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scope lang="scss">
|
||||||
|
.main-content {
|
||||||
|
height: 70vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-main {
|
||||||
|
color: #18a259;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padding-content {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.demo-app-main {
|
||||||
|
flex-grow: 1;
|
||||||
|
/* padding: 3em; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc {
|
||||||
|
/* the calendar root */
|
||||||
|
max-width: 1100px;
|
||||||
|
margin: 0 auto;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-day-today {
|
||||||
|
background-color: rgb(255, 255, 255) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// .fc-day-sun {
|
||||||
|
// background-color: rgba(207, 205, 205, 0.177) !important;
|
||||||
|
// width: 80px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .fc-day-sat {
|
||||||
|
// background-color: rgba(207, 205, 205, 0.177) !important;
|
||||||
|
// width: 80px;
|
||||||
|
// }
|
||||||
|
|
||||||
|
.fc-day-today .fc-daygrid-day-number {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
/* border: 2px solid #17a259; */
|
||||||
|
border-radius: 50%;
|
||||||
|
height: 25px;
|
||||||
|
width: 25px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: white !important;
|
||||||
|
background: #17a259;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-day-today .fc-daygrid-day-frame {
|
||||||
|
padding: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .fc-button-group > .fc-button {
|
||||||
|
color: black;
|
||||||
|
background-color: #fafafa;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .fc-button-group > .fc-button:active {
|
||||||
|
color: white;
|
||||||
|
background-color: #22a15e;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .fc-button-group > .fc-button.fc-button-active {
|
||||||
|
color: white;
|
||||||
|
background-color: #22a15e;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-header-toolbar {
|
||||||
|
background-color: white;
|
||||||
|
padding: 0px 10px 0px 10px;
|
||||||
|
border-radius: 10px 10px 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .fc-scrollgrid-liquid > thead {
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dp-custom-cell {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dp__today {
|
||||||
|
border: 1px solid var(--q-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dp__range_end,
|
||||||
|
.dp__range_start,
|
||||||
|
.dp__active_date {
|
||||||
|
background: var(--q-primary);
|
||||||
|
color: var(--dp-primary-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.datepicker .q-field__label {
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datepicker .q-field__messages {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datepicker .q-field__native {
|
||||||
|
padding-left: 5px;
|
||||||
|
color: var(--q-primary) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datepicker .q-field__prepend {
|
||||||
|
padding-left: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datepicker .q-field__append {
|
||||||
|
padding-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datepicker .q-field__after {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc .fc-popover {
|
||||||
|
z-index: 6000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-direction-ltr .fc-daygrid-event.fc-event-end,
|
||||||
|
.fc-direction-rtl .fc-daygrid-event.fc-event-start {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subName {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subInput {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event {
|
||||||
|
overflow: hidden;
|
||||||
|
border-color: transparent !important;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-event-main {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fc-direction-ltr .fc-daygrid-event.fc-event-end,
|
||||||
|
.fc-direction-rtl .fc-daygrid-event.fc-event-start {
|
||||||
|
padding-left: 0px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
580
src/modules/01_metadata/components/CalendarList.vue
Normal file
580
src/modules/01_metadata/components/CalendarList.vue
Normal file
|
|
@ -0,0 +1,580 @@
|
||||||
|
<!-- tab รายการ หน้าปฏิทินวันหยุด -->
|
||||||
|
<template>
|
||||||
|
<q-card class="q-mt-md" flat bordered>
|
||||||
|
<!-- list รายการันหยุด -->
|
||||||
|
<q-tabs
|
||||||
|
dense
|
||||||
|
v-model="currentTab"
|
||||||
|
indicator-color="primary"
|
||||||
|
active-color="primary bg-teal-1"
|
||||||
|
class="text-body2 text-grey-7"
|
||||||
|
>
|
||||||
|
<q-tab
|
||||||
|
v-for="tab in tabs"
|
||||||
|
:key="tab.value"
|
||||||
|
v-on:click="changeTab(tab.value)"
|
||||||
|
:label="tab.label"
|
||||||
|
:name="tab.value"
|
||||||
|
class="q-py-xs col-6 row"
|
||||||
|
/>
|
||||||
|
</q-tabs>
|
||||||
|
<q-table
|
||||||
|
ref="table"
|
||||||
|
flat
|
||||||
|
bordered
|
||||||
|
class="custom-header-table"
|
||||||
|
virtual-scroll
|
||||||
|
:rows="calendarData"
|
||||||
|
:columns="columns"
|
||||||
|
dense
|
||||||
|
:rows-per-page-options="[0]"
|
||||||
|
hide-header
|
||||||
|
>
|
||||||
|
<template v-slot:body="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'week'" class="">
|
||||||
|
{{ dayThaiRange(props.row.dateRange) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'holidayDate'" class="">
|
||||||
|
{{ dateThaiRange(props.row.dateRange) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="my-table-details">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
color="grey"
|
||||||
|
@click.stop
|
||||||
|
size="10px"
|
||||||
|
icon="more_vert"
|
||||||
|
>
|
||||||
|
<q-menu>
|
||||||
|
<q-list>
|
||||||
|
<q-item
|
||||||
|
clickable
|
||||||
|
v-close-popup
|
||||||
|
@click="editCalendar(props.row)"
|
||||||
|
>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>แก้ไขวันหยุด</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item
|
||||||
|
clickable
|
||||||
|
v-close-popup
|
||||||
|
@click="deleteClick(props.row)"
|
||||||
|
>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>ลบวันหยุด</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</q-menu>
|
||||||
|
</q-btn>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</q-table>
|
||||||
|
</q-card>
|
||||||
|
|
||||||
|
<!-- modal เพิ่มวันหยุด -->
|
||||||
|
<q-dialog v-model="modalAdd" persistent>
|
||||||
|
<q-card style="min-width: 550px">
|
||||||
|
<q-form ref="formDate" @submit.prevent.stop="editData">
|
||||||
|
<q-card-section class="row items-center q-pb-xs">
|
||||||
|
<div class="text-bold">แก้ไขวันหยุด</div>
|
||||||
|
<q-space />
|
||||||
|
<q-btn
|
||||||
|
icon="close"
|
||||||
|
unelevated
|
||||||
|
round
|
||||||
|
dense
|
||||||
|
v-close-popup
|
||||||
|
style="color: #ff8080; background-color: #ffdede"
|
||||||
|
/>
|
||||||
|
</q-card-section>
|
||||||
|
<q-separator />
|
||||||
|
<q-card-section class="q-p-sm">
|
||||||
|
<div class="row col-12 q-col-gutter-sm">
|
||||||
|
<div class="col-2 subName">
|
||||||
|
<label>เลือกวันที่</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-10">
|
||||||
|
<datepicker
|
||||||
|
v-model="dateAdd"
|
||||||
|
:locale="'th'"
|
||||||
|
autoApply
|
||||||
|
range
|
||||||
|
:enableTimePicker="false"
|
||||||
|
week-start="0"
|
||||||
|
>
|
||||||
|
<template #year="{ year }">
|
||||||
|
{{ year + 543 }}
|
||||||
|
</template>
|
||||||
|
<template #year-overlay-value="{ value }">
|
||||||
|
{{ parseInt(value + 543) }}
|
||||||
|
</template>
|
||||||
|
<template #trigger>
|
||||||
|
<q-input
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
class="full-width datepicker"
|
||||||
|
:model-value="dateThaiRange(dateAdd)"
|
||||||
|
>
|
||||||
|
<template v-slot:prepend>
|
||||||
|
<q-icon
|
||||||
|
name="event"
|
||||||
|
class="cursor-pointer"
|
||||||
|
style="color: var(--q-primary)"
|
||||||
|
>
|
||||||
|
</q-icon>
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
</template>
|
||||||
|
</datepicker>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row col-12 q-col-gutter-sm">
|
||||||
|
<div class="col-2 subName">
|
||||||
|
<label>คำอธิบาย</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-10">
|
||||||
|
<q-input
|
||||||
|
dense
|
||||||
|
borderless
|
||||||
|
class="full-width datepicker q-pb-none"
|
||||||
|
v-model="name"
|
||||||
|
type="textarea"
|
||||||
|
:rules="[(val) => (val && val.length > 0) || '']"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
<q-separator />
|
||||||
|
<q-card-actions align="right" class="text-primary">
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
round
|
||||||
|
color="public"
|
||||||
|
icon="mdi-content-save-outline"
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
<q-tooltip>บันทึก</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-form>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
|
||||||
|
<!-- modal ลบวันหยุด -->
|
||||||
|
<q-dialog v-model="modalDelete" persistent>
|
||||||
|
<q-card style="min-width: 550px">
|
||||||
|
<q-card-section class="row items-center q-pb-xs">
|
||||||
|
<div class="text-bold">ต้องการลบข้อมูลนี้หรือไม่?</div>
|
||||||
|
<q-space />
|
||||||
|
<q-btn
|
||||||
|
icon="close"
|
||||||
|
unelevated
|
||||||
|
round
|
||||||
|
dense
|
||||||
|
v-close-popup
|
||||||
|
style="color: #ff8080; background-color: #ffdede"
|
||||||
|
/>
|
||||||
|
</q-card-section>
|
||||||
|
<q-separator />
|
||||||
|
<q-card-section class="row items-center">
|
||||||
|
<div class="q-pr-md">
|
||||||
|
<q-avatar
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
font-size="25px"
|
||||||
|
size="lg"
|
||||||
|
color="red-1"
|
||||||
|
text-color="red"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col text-dark">
|
||||||
|
<span>ข้อมูลที่กำลังถูกลบนี้จะมีผลใช้งานทันที</span>
|
||||||
|
</div>
|
||||||
|
</q-card-section>
|
||||||
|
<q-separator />
|
||||||
|
<q-card-actions align="right" class="bg-white text-teal">
|
||||||
|
<q-btn label="ตกลง" color="primary" @click="deleteConfirm" />
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import type {
|
||||||
|
RequestItemsObject,
|
||||||
|
DataDateRowObject,
|
||||||
|
DataDateAddObject,
|
||||||
|
DataDateListsObject,
|
||||||
|
TabsObject,
|
||||||
|
} from "@/modules/01_metadata/interface/request/Calendar";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
dateYear: {
|
||||||
|
//filter ปี วันหยุด
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
refreshData: {
|
||||||
|
//หน้า main มีการอัพเดทค่าให้ refresh data
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
fetchDataSummaryCalendar: {
|
||||||
|
//ฟังก์ชันอัพเดทสรุปวันหยุด
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const store = useDataStore();
|
||||||
|
const { loaderPage } = store;
|
||||||
|
const mixin = useCounterMixin(); //เรียกฟังก์ชันกลาง
|
||||||
|
const { success, dateToISO, dateMonth2Thai, weekThai, messageError } = mixin;
|
||||||
|
const $q = useQuasar(); //ใช้ noti quasar
|
||||||
|
const calendarData = ref<DataDateListsObject[]>([]); //data วันหยุด
|
||||||
|
const modalAdd = ref<boolean>(false); //modal เพิ่มวันหยุด
|
||||||
|
const modalDelete = ref<boolean>(false); //modal ลบวันหยุด
|
||||||
|
const name = ref<string>(""); //ชื่อวันหยุด
|
||||||
|
const isSpecial = ref<boolean>(true); //เช็ควันหยุด
|
||||||
|
const dateAdd = ref<[Date, Date]>([new Date(), new Date()]); //วันที่ ที่เพิ่มเป็นวันหยุด
|
||||||
|
const rowData = ref<DataDateListsObject>(); //data ที่ถูกเลือกใน row นั้น
|
||||||
|
const formDate = ref<any>(); //ref เพิ่ม แก้ไข วันหยุดสำหรับ validate
|
||||||
|
|
||||||
|
const currentTab = ref<string>("normal"); //เลือก tab ประเภทวันหยุด
|
||||||
|
const tabs = ref<TabsObject[]>([
|
||||||
|
{ label: "ทำงานจันทร์-ศุกร์ (5 วัน)", value: "normal" },
|
||||||
|
{ label: "ทำงานจันทร์-เสาร์ (6 วัน)", value: "6day" },
|
||||||
|
]); //tab ประเภทวันหยุดทั้งหมด
|
||||||
|
|
||||||
|
//columns รายการวันหยุด
|
||||||
|
const columns = ref<any>([
|
||||||
|
{
|
||||||
|
name: "week",
|
||||||
|
align: "left",
|
||||||
|
label: "-",
|
||||||
|
sortable: true,
|
||||||
|
field: "week",
|
||||||
|
style: "font-size: 15px",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "holidayDate",
|
||||||
|
align: "left",
|
||||||
|
label: "-",
|
||||||
|
sortable: true,
|
||||||
|
field: "holidayDate",
|
||||||
|
style: "font-size: 15px",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "detail",
|
||||||
|
align: "left",
|
||||||
|
label: "-",
|
||||||
|
sortable: true,
|
||||||
|
field: "detail",
|
||||||
|
style: "font-size: 15px",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เรียกฟังก์ชันทั้งหมดตอนเรียกใช้ไฟล์นี้
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ค่า props(วันปีที่เลือก และเพิ่มหรือแก้ไข) ตอนอัพเดท ค่าฏิทินให้อัพเดทใหม่
|
||||||
|
*/
|
||||||
|
watch(props, async (count, prevCount) => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* กดปุ่มแก้ไขวันหยุด
|
||||||
|
* @param val data วันหยุดทั้ง row
|
||||||
|
*/
|
||||||
|
const editCalendar = async (val: DataDateListsObject) => {
|
||||||
|
rowData.value = val;
|
||||||
|
dateAdd.value = [val.dateRange[0], val.dateRange[1]];
|
||||||
|
name.value = val.detail;
|
||||||
|
isSpecial.value = true;
|
||||||
|
modalAdd.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* กดปุ่มลบวันหยุด
|
||||||
|
* @param val data วันหยุดทั้ง row
|
||||||
|
*/
|
||||||
|
const deleteClick = async (val: DataDateListsObject) => {
|
||||||
|
rowData.value = val;
|
||||||
|
modalDelete.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fetch วันหยุดในรายการ
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
calendarData.value = [];
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listHolidayHistoryYear(props.dateYear))
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result.normal;
|
||||||
|
if (currentTab.value == "6day") {
|
||||||
|
data = res.data.result.sixDays;
|
||||||
|
}
|
||||||
|
const dateStart = ref<Date | null>();
|
||||||
|
const firstEvent = ref<boolean>(true);
|
||||||
|
const dateRow = ref<DataDateRowObject[]>([]);
|
||||||
|
data.map((e: RequestItemsObject, index: number) => {
|
||||||
|
dateRow.value.push({
|
||||||
|
holidayDate: new Date(e.holidayDate),
|
||||||
|
name: e.name,
|
||||||
|
isSpecial: true,
|
||||||
|
id: e.id,
|
||||||
|
});
|
||||||
|
if (
|
||||||
|
index == data.length - 1 ||
|
||||||
|
data[index + 1].name != e.name ||
|
||||||
|
(data[index + 1].name == e.name &&
|
||||||
|
dateToISO(new Date(data[index + 1].holidayDate)) !=
|
||||||
|
dateToISO(
|
||||||
|
new Date(
|
||||||
|
new Date(e.holidayDate).setDate(
|
||||||
|
new Date(e.holidayDate).getDate() + 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
))
|
||||||
|
) {
|
||||||
|
firstEvent.value = true;
|
||||||
|
calendarData.value.push({
|
||||||
|
id: e.id,
|
||||||
|
dateRange: [
|
||||||
|
dateStart.value ? dateStart.value : new Date(e.holidayDate),
|
||||||
|
new Date(e.holidayDate),
|
||||||
|
],
|
||||||
|
dataRangeRow: dateRow.value,
|
||||||
|
detail:
|
||||||
|
dateToISO(new Date(e.holidayDate)) ==
|
||||||
|
dateToISO(new Date(e.originalDate))
|
||||||
|
? e.name
|
||||||
|
: `ชดเชย ${e.name}`,
|
||||||
|
isSpecial: true,
|
||||||
|
});
|
||||||
|
dateStart.value = null;
|
||||||
|
dateRow.value = [];
|
||||||
|
} else if (firstEvent.value == true) {
|
||||||
|
firstEvent.value = false;
|
||||||
|
dateStart.value = new Date(e.holidayDate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await props.fetchDataSummaryCalendar();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ลบข้อมูลวันหยุด
|
||||||
|
*/
|
||||||
|
const deleteConfirm = async () => {
|
||||||
|
modalDelete.value = false;
|
||||||
|
const dataDelete = ref<DataDateAddObject[]>([]);
|
||||||
|
if (rowData.value != null) {
|
||||||
|
await rowData.value.dataRangeRow.map((e: DataDateRowObject) => {
|
||||||
|
dataDelete.value.push({
|
||||||
|
year: new Date(e.holidayDate).getFullYear(),
|
||||||
|
holidayDate: dateToISO(e.holidayDate),
|
||||||
|
name: e.name,
|
||||||
|
isSpecial: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(
|
||||||
|
config.API.listHolidayHistoryDelete(currentTab.value),
|
||||||
|
dataDelete.value
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* บันทึกแก้ไขวันหยุด
|
||||||
|
*/
|
||||||
|
const editData = async () => {
|
||||||
|
await formDate.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
const dataEdit = ref<DataDateAddObject[]>([]);
|
||||||
|
let i = 0;
|
||||||
|
const dateStart = ref<Date>(dateAdd.value[0]);
|
||||||
|
do {
|
||||||
|
i = i + 1;
|
||||||
|
dataEdit.value.push({
|
||||||
|
year: new Date(dateStart.value).getFullYear(),
|
||||||
|
holidayDate: dateToISO(new Date(dateStart.value)),
|
||||||
|
name: name.value,
|
||||||
|
isSpecial: true,
|
||||||
|
});
|
||||||
|
dateStart.value = new Date(
|
||||||
|
new Date(dateStart.value).setDate(
|
||||||
|
new Date(dateStart.value).getDate() + 1
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} while (new Date(dateStart.value) <= new Date(dateAdd.value[1]));
|
||||||
|
const _dataHistory = ref<DataDateAddObject[]>([]);
|
||||||
|
if (rowData.value != null) {
|
||||||
|
rowData.value.dataRangeRow.map(
|
||||||
|
(e: DataDateRowObject, index: number) => {
|
||||||
|
_dataHistory.value.push({
|
||||||
|
year: new Date(e.holidayDate).getFullYear(),
|
||||||
|
holidayDate: dateToISO(e.holidayDate),
|
||||||
|
name: e.name,
|
||||||
|
isSpecial: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listHolidayHistoryEdit(currentTab.value), {
|
||||||
|
history: _dataHistory.value,
|
||||||
|
updated: dataEdit.value,
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
modalAdd.value = false;
|
||||||
|
success($q, "แก้ไขข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เปลี่ยน tab ดูวันหยุดตามประเภท
|
||||||
|
* @param tab tab ประเภทวันหยุดที่เลือก
|
||||||
|
*/
|
||||||
|
const changeTab = async (tab: string) => {
|
||||||
|
currentTab.value = tab;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แปลงช่วงวันที่ถ้า2ค่าเป็นวันเดียวกันจะโชววันเดียวแต่ถ้าไม่เท่ากันจะแสดงเป็นช่วง
|
||||||
|
* @param val ช่วงวันที่
|
||||||
|
*/
|
||||||
|
const dateThaiRange = (val: [Date, Date]) => {
|
||||||
|
if (val === null) {
|
||||||
|
return "";
|
||||||
|
} else if (dateMonth2Thai(val[0], true) === dateMonth2Thai(val[1], true)) {
|
||||||
|
return `${dateMonth2Thai(val[0], true)}`;
|
||||||
|
} else {
|
||||||
|
return `${dateMonth2Thai(val[0], true)} - ${dateMonth2Thai(val[1], true)}`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แปลงช่วงวันที่ถ้า2ค่าเป็นวันเดียวกันจะโชววันเดียวแต่ถ้าไม่เท่ากันจะแสดงเป็นช่วง(เช่นวันจันทร์ -วันศุกร์)
|
||||||
|
* @param val ช่วงวันที่
|
||||||
|
*/
|
||||||
|
const dayThaiRange = (val: [Date, Date]) => {
|
||||||
|
if (val === null) {
|
||||||
|
} else if (dateToISO(val[0]) == dateToISO(val[1])) {
|
||||||
|
return `${weekThai(new Date(val[0]).getDay())}`;
|
||||||
|
} else {
|
||||||
|
return `${weekThai(new Date(val[0]).getDay())} - ${weekThai(
|
||||||
|
new Date(val[1]).getDay()
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.custom-header-table {
|
||||||
|
max-height: 64vh;
|
||||||
|
|
||||||
|
.q-table tr:nth-child(odd) td {
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-table tr:nth-child(even) td {
|
||||||
|
background: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-table thead tr {
|
||||||
|
background: #ecebeb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-table thead tr th {
|
||||||
|
position: sticky;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this will be the loading indicator */
|
||||||
|
.q-table thead tr:last-child th {
|
||||||
|
/* height of all previous header rows */
|
||||||
|
top: 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-table thead tr:first-child th {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-table-details {
|
||||||
|
white-space: -moz-pre-wrap !important;
|
||||||
|
/* Mozilla, since 1999 */
|
||||||
|
white-space: -webkit-pre-wrap;
|
||||||
|
/* Chrome & Safari */
|
||||||
|
white-space: -pre-wrap;
|
||||||
|
/* Opera 4-6 */
|
||||||
|
white-space: -o-pre-wrap;
|
||||||
|
/* Opera 7 */
|
||||||
|
white-space: pre-wrap;
|
||||||
|
/* CSS3 */
|
||||||
|
word-wrap: break-word;
|
||||||
|
/* Internet Explorer 5.5+ */
|
||||||
|
word-break: break-all;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table_ellipsis {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: wrap;
|
||||||
|
max-width: 250px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
198
src/modules/01_metadata/components/TableHistory.vue
Normal file
198
src/modules/01_metadata/components/TableHistory.vue
Normal file
|
|
@ -0,0 +1,198 @@
|
||||||
|
<template>
|
||||||
|
<q-dialog :model-value="modal" persistent>
|
||||||
|
<q-card style="min-width: 700px">
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<div class="row items-center q-pa-sm">
|
||||||
|
<div class="row">
|
||||||
|
<div class="text-bold">{{ tittle }}</div>
|
||||||
|
</div>
|
||||||
|
<q-space />
|
||||||
|
<q-btn
|
||||||
|
icon="close"
|
||||||
|
unelevated
|
||||||
|
round
|
||||||
|
dense
|
||||||
|
style="color: #ff8080; background-color: #ffdede"
|
||||||
|
size="12px"
|
||||||
|
@click="close"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<q-separator />
|
||||||
|
<div class="q-pa-sm">
|
||||||
|
<!-- header บน table มี ค้นหา แสดงคอลัมน์ (status nornmalData true) -->
|
||||||
|
<div class="col-12 row q-pb-sm">
|
||||||
|
<q-select
|
||||||
|
hide-bottom-space
|
||||||
|
@update:model-value="updateHistory"
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
borderless
|
||||||
|
:model-value="history"
|
||||||
|
:label="`${'ชื่อเครื่องราชฯ'}`"
|
||||||
|
emit-value
|
||||||
|
map-options
|
||||||
|
option-label="publishedDate"
|
||||||
|
:options="optionsHistory"
|
||||||
|
option-value="id"
|
||||||
|
/>
|
||||||
|
<q-space />
|
||||||
|
<div class="items-center" style="display: flex">
|
||||||
|
<!-- ค้นหาข้อความใน table -->
|
||||||
|
<q-input
|
||||||
|
standout
|
||||||
|
dense
|
||||||
|
:model-value="inputfilter"
|
||||||
|
ref="filterRef"
|
||||||
|
@update:model-value="updateInput"
|
||||||
|
outlined
|
||||||
|
debounce="300"
|
||||||
|
placeholder="ค้นหา"
|
||||||
|
style="max-width: 200px"
|
||||||
|
class="q-ml-sm"
|
||||||
|
>
|
||||||
|
<template v-slot:append>
|
||||||
|
<q-icon v-if="inputfilter == ''" name="search" />
|
||||||
|
<q-icon
|
||||||
|
v-if="inputfilter !== ''"
|
||||||
|
name="clear"
|
||||||
|
class="cursor-pointer"
|
||||||
|
@click="resetFilter"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
<!-- แสดงคอลัมน์ใน table -->
|
||||||
|
<q-select
|
||||||
|
:model-value="inputvisible"
|
||||||
|
@update:model-value="updateVisible"
|
||||||
|
:display-value="$q.lang.table.columns"
|
||||||
|
multiple
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
:options="attrs.columns"
|
||||||
|
options-dense
|
||||||
|
option-value="name"
|
||||||
|
map-options
|
||||||
|
emit-value
|
||||||
|
style="min-width: 150px"
|
||||||
|
class="gt-xs q-ml-sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<q-table
|
||||||
|
ref="table"
|
||||||
|
flat
|
||||||
|
bordered
|
||||||
|
class="custom-header-table"
|
||||||
|
v-bind="attrs"
|
||||||
|
virtual-scroll
|
||||||
|
:virtual-scroll-sticky-size-start="48"
|
||||||
|
dense
|
||||||
|
:pagination-label="paginationLabel"
|
||||||
|
:pagination="initialPagination"
|
||||||
|
:rows-per-page-options="[0]"
|
||||||
|
>
|
||||||
|
<template v-slot:header="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<span class="text-weight-medium">{{ col.label }}</span>
|
||||||
|
</q-th>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
<!-- สำหรับเรียกใช้ template ตัวข้างนอก -->
|
||||||
|
<template #body="props">
|
||||||
|
<slot v-bind="props" name="columns"></slot>
|
||||||
|
</template>
|
||||||
|
</q-table>
|
||||||
|
</div>
|
||||||
|
<q-separator />
|
||||||
|
</q-form>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { ref, useAttrs } from "vue";
|
||||||
|
import type { Pagination } from "@/modules/01_metadata/interface/index/Main";
|
||||||
|
|
||||||
|
const attrs = ref<any>(useAttrs());
|
||||||
|
const filterRef = ref<any>(null);
|
||||||
|
const initialPagination = ref<Pagination>({
|
||||||
|
rowsPerPage: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
tittle: String,
|
||||||
|
inputfilter: String,
|
||||||
|
history: String,
|
||||||
|
inputvisible: Array,
|
||||||
|
modal: Boolean,
|
||||||
|
optionsHistory: Array,
|
||||||
|
updateHistory: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits([
|
||||||
|
"update:inputfilter",
|
||||||
|
"update:inputvisible",
|
||||||
|
"update:modal",
|
||||||
|
"update:history",
|
||||||
|
]);
|
||||||
|
|
||||||
|
const updateInput = (value: string | number | null) => {
|
||||||
|
emit("update:inputfilter", value);
|
||||||
|
};
|
||||||
|
const updateVisible = (value: []) => {
|
||||||
|
emit("update:inputvisible", value);
|
||||||
|
};
|
||||||
|
const close = () => {
|
||||||
|
emit("update:modal", false);
|
||||||
|
};
|
||||||
|
const updateHistory = (value: string) => {
|
||||||
|
emit("update:history", value);
|
||||||
|
props.updateHistory();
|
||||||
|
};
|
||||||
|
|
||||||
|
const paginationLabel = (start: string, end: string, total: string) => {
|
||||||
|
return start + "-" + end + " ใน " + total;
|
||||||
|
};
|
||||||
|
|
||||||
|
// reset ค่าที่ค้นหาเมื่อกดปุ่ม X ในกล่องค้นหา
|
||||||
|
const resetFilter = () => {
|
||||||
|
emit("update:inputfilter", "");
|
||||||
|
filterRef.value.focus();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.icon-color {
|
||||||
|
color: #4154b3;
|
||||||
|
}
|
||||||
|
.custom-header-table {
|
||||||
|
max-height: 64vh;
|
||||||
|
.q-table tr:nth-child(odd) td {
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
.q-table tr:nth-child(even) td {
|
||||||
|
background: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-table thead tr {
|
||||||
|
background: #ecebeb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.q-table thead tr th {
|
||||||
|
position: sticky;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
/* this will be the loading indicator */
|
||||||
|
.q-table thead tr:last-child th {
|
||||||
|
/* height of all previous header rows */
|
||||||
|
top: 48px;
|
||||||
|
}
|
||||||
|
.q-table thead tr:first-child th {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
966
src/modules/01_metadata/components/insignia/Insignia.vue
Normal file
966
src/modules/01_metadata/components/insignia/Insignia.vue
Normal file
|
|
@ -0,0 +1,966 @@
|
||||||
|
<!-- tab ชื่อเครื่องราช หน้าจัดการข้อมูลหลัก/ข้อมูลเครื่องราชอิสริยาภรณ์ -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'insigniaType'" class="">
|
||||||
|
{{ col.value == null ? "" : col.value.name }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td
|
||||||
|
key="level"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.level !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ props.row.level }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="shortName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.shortName !== undefined"
|
||||||
|
>
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.shortName"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataShortName(val) ||
|
||||||
|
'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="insigniaType"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.shortName !== undefined"
|
||||||
|
>
|
||||||
|
<q-select
|
||||||
|
:options="insigniaTypeOption"
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.insigniaType"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
hide-bottom-space
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
:rules="[(val) => val || 'กรุณาเลือกลำดับชั้นเครื่องราชฯ']"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
size="34px"
|
||||||
|
color="positive"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="note" :props="props" v-if="props.row.note !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.note"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<div class="row">
|
||||||
|
<q-btn
|
||||||
|
:disable="props.row.level <= 1"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
size="12px"
|
||||||
|
icon="mdi-menu-up"
|
||||||
|
style="
|
||||||
|
padding-top: 0em;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
padding-bottom: 0em;
|
||||||
|
padding-left: 0.5em;
|
||||||
|
min-height: 0em;
|
||||||
|
"
|
||||||
|
@click="directionItem(props.row, 'up')"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
:disable="props.row.level >= rows.length"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
size="12px"
|
||||||
|
icon="mdi-menu-down"
|
||||||
|
style="
|
||||||
|
padding-top: 0em;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
padding-bottom: 0em;
|
||||||
|
padding-left: 0.5em;
|
||||||
|
min-height: 0em;
|
||||||
|
"
|
||||||
|
@click="directionItem(props.row, 'down')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'insigniaType'" class="">
|
||||||
|
{{ col.value == null ? "" : col.value.name }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/insignia/Insignia";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/insignia/Insignia";
|
||||||
|
import type { DataOption } from "@/modules/01_metadata/interface/index/Main";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขชื่อเครื่องราชฯ"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
const insigniaTypeOption = ref<DataOption[]>([]); //ราชการลำดับเครื่องราชฯ
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "level",
|
||||||
|
align: "left",
|
||||||
|
label: "ลำดับ",
|
||||||
|
sortable: true,
|
||||||
|
field: "level",
|
||||||
|
headerStyle: "font-size: 14px; width:0px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ชื่อเครื่องราชฯ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "shortName",
|
||||||
|
align: "left",
|
||||||
|
label: "ชื่อย่อ",
|
||||||
|
sortable: true,
|
||||||
|
field: "shortName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "insigniaType",
|
||||||
|
align: "left",
|
||||||
|
label: "ลำดับชั้นเครื่องราชฯ",
|
||||||
|
sortable: true,
|
||||||
|
field: "insigniaType",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "note",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเหตุ",
|
||||||
|
sortable: true,
|
||||||
|
field: "note",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.insignia.class.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"level",
|
||||||
|
"name",
|
||||||
|
"shortName",
|
||||||
|
"insigniaType",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
"note",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.insignia.class.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "level",
|
||||||
|
align: "left",
|
||||||
|
label: "ลำดับ",
|
||||||
|
sortable: true,
|
||||||
|
field: "level",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ชื่อเครื่องราชฯ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "shortName",
|
||||||
|
align: "left",
|
||||||
|
label: "ชื่อย่อ",
|
||||||
|
sortable: true,
|
||||||
|
field: "shortName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "insigniaType",
|
||||||
|
align: "left",
|
||||||
|
label: "ลำดับชั้นเครื่องราชฯ",
|
||||||
|
sortable: true,
|
||||||
|
field: "insigniaType",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "note",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเหตุ",
|
||||||
|
sortable: true,
|
||||||
|
field: "note",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"level",
|
||||||
|
"name",
|
||||||
|
"shortName",
|
||||||
|
"insigniaType",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
"note",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(6, "class", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listInsigniaHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
shortName: e.shortName,
|
||||||
|
level: e.level,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
insigniaType: e.insigniaType,
|
||||||
|
note: e.note,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
rows.value.sort(
|
||||||
|
(
|
||||||
|
firstItem: RequestItemsHistoryObject,
|
||||||
|
secondItem: RequestItemsHistoryObject
|
||||||
|
) => firstItem.level - secondItem.level
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchinsigniaType();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* รายการลำดับเครื่องราชฯ
|
||||||
|
*/
|
||||||
|
const fetchinsigniaType = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.insigniaType)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
let option: DataOption[] = [];
|
||||||
|
data.map((r: RequestItemsHistoryObject) => {
|
||||||
|
option.push({ id: r.id.toString(), name: r.name.toString() });
|
||||||
|
});
|
||||||
|
insigniaTypeOption.value = option;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listInsigniaPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
level: i.level,
|
||||||
|
name: i.name,
|
||||||
|
shortName: i.shortName,
|
||||||
|
insigniaType: i.insigniaType,
|
||||||
|
note: i.note,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listInsigniaHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listInsigniaPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" &&
|
||||||
|
(f.name == "" || f.shortName == "") //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
shortName: "",
|
||||||
|
level: rows.value[rows.value.length - 1].level + 1,
|
||||||
|
note: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
shortName: e.shortName,
|
||||||
|
level: e.level,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
insigniaType: e.insigniaType,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listInsigniaHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อย่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อย่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataShortName = (val: string) => {
|
||||||
|
const filterShortNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.shortName == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterShortNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ย้ายลำดับ data
|
||||||
|
* @param row ค่าใน row
|
||||||
|
* @param type ย้ายตำแหน่งแบบไหน up=ขึ้น down=ลง
|
||||||
|
*/
|
||||||
|
const directionItem = (row: RequestItemsHistoryObject, type: string) => {
|
||||||
|
clickEditRow();
|
||||||
|
if (type === "up") {
|
||||||
|
rows.value[
|
||||||
|
rows.value.findIndex((object: RequestItemsHistoryObject) => {
|
||||||
|
return object === row;
|
||||||
|
})
|
||||||
|
].level -= 1;
|
||||||
|
rows.value[
|
||||||
|
rows.value.findIndex((object: RequestItemsHistoryObject) => {
|
||||||
|
return object === row;
|
||||||
|
}) - 1
|
||||||
|
].level += 1;
|
||||||
|
} else {
|
||||||
|
rows.value[
|
||||||
|
rows.value.findIndex((object: RequestItemsHistoryObject) => {
|
||||||
|
return object === row;
|
||||||
|
})
|
||||||
|
].level += 1;
|
||||||
|
rows.value[
|
||||||
|
rows.value.findIndex((object: RequestItemsHistoryObject) => {
|
||||||
|
return object === row;
|
||||||
|
}) + 1
|
||||||
|
].level -= 1;
|
||||||
|
}
|
||||||
|
rows.value.sort(
|
||||||
|
(
|
||||||
|
firstItem: RequestItemsHistoryObject,
|
||||||
|
secondItem: RequestItemsHistoryObject
|
||||||
|
) => firstItem.level - secondItem.level
|
||||||
|
);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
659
src/modules/01_metadata/components/insignia/InsigniaType.vue
Normal file
659
src/modules/01_metadata/components/insignia/InsigniaType.vue
Normal file
|
|
@ -0,0 +1,659 @@
|
||||||
|
<!-- tab ลำดับชั้นเครื่องราชฯ หน้าจัดการข้อมูลหลัก/ข้อมูลเครื่องราชอิสริยาภรณ์ -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
size="34px"
|
||||||
|
color="positive"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/insignia/InsigniaType";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/insignia/InsigniaType";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขลำดับชั้นเครื่องราชฯ"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ลำดับชั้นเครื่องราชฯ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.insignia.type.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.insignia.type.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ลำดับชั้นเครื่องราชฯ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(6, "type", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listInsigniaTypeHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listInsigniaTypePublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listInsigniaTypeHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listInsigniaTypePublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listInsigniaTypeHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
660
src/modules/01_metadata/components/organization/Agency.vue
Normal file
660
src/modules/01_metadata/components/organization/Agency.vue
Normal file
|
|
@ -0,0 +1,660 @@
|
||||||
|
<!-- tab หน่วยงานต้นสังกัด หน้าจัดการข้อมูลหลัก/ข้อมูลโครงสร้างหน่วยงาน -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
color="green"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/organization/Agency";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/organization/Agency";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขหน่วยงานต้นสังกัด"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "หน่วยงานต้นสังกัด",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.organization.agency.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.organization.agency.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "หน่วยงานต้นสังกัด",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(2, "agency", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationAgencyHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationAgencyPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listOrganizationAgencyHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationAgencyPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* @param publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listOrganizationAgencyHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
659
src/modules/01_metadata/components/organization/Fax.vue
Normal file
659
src/modules/01_metadata/components/organization/Fax.vue
Normal file
|
|
@ -0,0 +1,659 @@
|
||||||
|
<!-- tab หมายเลขโทรสาร หน้าจัดการข้อมูลหลัก/ข้อมูลโครงสร้างหน่วยงาน -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
color="green"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/organization/Fax";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/organization/Fax";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขหมายเลขโทรสาร"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเลขโทรสาร",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.organization.fax.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.organization.fax.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเลขโทรสาร",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(2, "fax", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationFaxHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationFaxPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listOrganizationFaxHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationFaxPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listOrganizationFaxHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,661 @@
|
||||||
|
<!-- tab ส่วนราชการต้นสังกัด หน้าจัดการข้อมูลหลัก/ข้อมูลโครงสร้างหน่วยงาน -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
color="green"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/organization/GovernmentAgency";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/organization/GovernmentAgency";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขส่วนราชการต้นสังกัด"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ส่วนราชการต้นสังกัด",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.organization.governmentAgency.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.organization.governmentAgency.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ส่วนราชการต้นสังกัด",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(2, "governmentAgency", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationGovernmentAgencyHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationGovernmentAgencyPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listOrganizationGovernmentAgencyHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationGovernmentAgencyPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(
|
||||||
|
config.API.listOrganizationGovernmentAgencyHistoryId(idVersion.value),
|
||||||
|
{
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
659
src/modules/01_metadata/components/organization/Level.vue
Normal file
659
src/modules/01_metadata/components/organization/Level.vue
Normal file
|
|
@ -0,0 +1,659 @@
|
||||||
|
<!-- tab ระดับของหน่วยงาน/ส่วนราชการ หน้าจัดการข้อมูลหลัก/ข้อมูลโครงสร้างหน่วยงาน -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
color="green"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/organization/Level";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/organization/Level";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขระดับของหน่วยงาน/ส่วนราชการ"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ระดับของหน่วยงาน/ส่วนราชการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.organization.level.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.organization.level.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ระดับของหน่วยงาน/ส่วนราชการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(2, "level", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationLevelHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationLevelPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listOrganizationLevelHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationLevelPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listOrganizationLevelHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
698
src/modules/01_metadata/components/organization/Organization.vue
Normal file
698
src/modules/01_metadata/components/organization/Organization.vue
Normal file
|
|
@ -0,0 +1,698 @@
|
||||||
|
<!-- tab ชื่อหน่วยงาน หน้าจัดการข้อมูลหลัก/ข้อมูลโครงสร้างหน่วยงาน -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
color="green"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="note" :props="props" v-if="props.row.note !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.note"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/organization/Organization";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/organization/Organization";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขชื่อหน่วยงาน"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ชื่อหน่วยงาน/หน่วยงานต้นสังกัด/ส่วนราชการต้นสังกัด",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "note",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเหตุ",
|
||||||
|
sortable: true,
|
||||||
|
field: "note",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.organization.organization.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
"note",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.organization.organization.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ชื่อหน่วยงาน/หน่วยงานต้นสังกัด/ส่วนราชการต้นสังกัด",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "note",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเหตุ",
|
||||||
|
sortable: true,
|
||||||
|
field: "note",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
"note",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(2, "organization", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationOrganizationHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
note: e.note,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationOrganizationPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
note: i.note,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listOrganizationOrganizationHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationOrganizationPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
note: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listOrganizationOrganizationHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
815
src/modules/01_metadata/components/organization/ShortName.vue
Normal file
815
src/modules/01_metadata/components/organization/ShortName.vue
Normal file
|
|
@ -0,0 +1,815 @@
|
||||||
|
<!-- tab ชื่อย่อหน่วยงาน หน้าจัดการข้อมูลหลัก/ข้อมูลโครงสร้างหน่วยงาน -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td
|
||||||
|
key="agencyCode"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.agencyCode !== undefined"
|
||||||
|
>
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.agencyCode"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(props.row) || 'ข้อมูลนี้มีอยู่แล้วในระบบ',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="governmentCode"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.governmentCode !== undefined"
|
||||||
|
>
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.governmentCode"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(props.row) || 'ข้อมูลนี้มีอยู่แล้วในระบบ',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-form ref="myForm3">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(props.row) ||
|
||||||
|
'ข้อมูลนี้มีอยู่แล้วในระบบ',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-form>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
color="green"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="note" :props="props" v-if="props.row.note !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.note"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/organization/ShortName";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/organization/ShortName";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขชื่อหน่วยงาน"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "agencyCode",
|
||||||
|
align: "left",
|
||||||
|
label: "รหัสหน่วยงาน",
|
||||||
|
sortable: true,
|
||||||
|
field: "agencyCode",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "governmentCode",
|
||||||
|
align: "left",
|
||||||
|
label: "รหัสส่วนราชการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "governmentCode",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ตัวย่อหน่วยงาน",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "note",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเหตุ",
|
||||||
|
sortable: true,
|
||||||
|
field: "note",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.organization.shortName.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"agencyCode",
|
||||||
|
"governmentCode",
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
"note",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.organization.shortName.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "agencyCode",
|
||||||
|
align: "left",
|
||||||
|
label: "รหัสหน่วยงาน",
|
||||||
|
sortable: true,
|
||||||
|
field: "agencyCode",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "governmentCode",
|
||||||
|
align: "left",
|
||||||
|
label: "รหัสส่วนราชการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "governmentCode",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ตัวย่อหน่วยงาน",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "note",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเหตุ",
|
||||||
|
sortable: true,
|
||||||
|
field: "note",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"agencyCode",
|
||||||
|
"governmentCode",
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
"note",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(2, "shortName", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationShortNameHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
agencyCode: e.agencyCode,
|
||||||
|
governmentCode: e.governmentCode,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
note: e.note,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationShortNamePublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
agencyCode: i.agencyCode,
|
||||||
|
governmentCode: i.governmentCode,
|
||||||
|
name: i.name,
|
||||||
|
note: i.note,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listOrganizationShortNameHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationShortNamePublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" &&
|
||||||
|
(f.agencyCode == "" || f.name == "") //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
agencyCode: "",
|
||||||
|
governmentCode: "",
|
||||||
|
name: "",
|
||||||
|
note: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
agencyCode: e.agencyCode,
|
||||||
|
governmentCode: e.governmentCode,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listOrganizationShortNameHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็ครหัสซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input รหัสส่วนราชการ
|
||||||
|
*/
|
||||||
|
const checkDupDataGovernmentCode = (gCode: string, aCode: string) => {
|
||||||
|
if (gCode == null || gCode == "") return true;
|
||||||
|
const filterCodeNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.governmentCode == gCode && f.agencyCode == aCode
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterCodeNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อย่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อย่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (row: any) => {
|
||||||
|
const filterShortNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.name == row.name &&
|
||||||
|
f.governmentCode == row.governmentCode &&
|
||||||
|
f.agencyCode == row.agencyCode
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterShortNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
659
src/modules/01_metadata/components/organization/Status.vue
Normal file
659
src/modules/01_metadata/components/organization/Status.vue
Normal file
|
|
@ -0,0 +1,659 @@
|
||||||
|
<!-- tab สถานะของหน่วยงาน/ส่วนราชการ หน้าจัดการข้อมูลหลัก/ข้อมูลโครงสร้างหน่วยงาน -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
color="green"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/organization/Status";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/organization/Status";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขสถานะของหน่วยงาน/ส่วนราชการ"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะของหน่วยงาน/ส่วนราชการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.organization.status.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.organization.status.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะของหน่วยงาน/ส่วนราชการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(2, "status", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationStatusHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationStatusPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listOrganizationStatusHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationStatusPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listOrganizationStatusHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
659
src/modules/01_metadata/components/organization/TelExternal.vue
Normal file
659
src/modules/01_metadata/components/organization/TelExternal.vue
Normal file
|
|
@ -0,0 +1,659 @@
|
||||||
|
<!-- tab หมายเลขโทรศัพท์ภายนอก หน้าจัดการข้อมูลหลัก/ข้อมูลโครงสร้างหน่วยงาน -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
color="green"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/organization/TelExternal";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/organization/TelExternal";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขหมายเลขโทรศัพท์ภายนอก"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเลขโทรศัพท์ภายนอก",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.organization.telExternal.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.organization.telExternal.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเลขโทรศัพท์ภายนอก",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(2, "telExternal", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationTelExternalHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationTelExternalPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listOrganizationTelExternalHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationTelExternalPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listOrganizationTelExternalHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
659
src/modules/01_metadata/components/organization/TelInternal.vue
Normal file
659
src/modules/01_metadata/components/organization/TelInternal.vue
Normal file
|
|
@ -0,0 +1,659 @@
|
||||||
|
<!-- tab หมายเลขโทรศัพท์ภายใน หน้าจัดการข้อมูลหลัก/ข้อมูลโครงสร้างหน่วยงาน -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
color="green"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/organization/TelInternal";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/organization/TelInternal";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขหมายเลขโทรศัพท์ภายใน"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเลขโทรศัพท์ภายใน",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.organization.telInternal.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.organization.telInternal.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเลขโทรศัพท์ภายใน",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(2, "telInternal", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationTelInternalHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationTelInternalPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listOrganizationTelInternalHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationTelInternalPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listOrganizationTelInternalHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
659
src/modules/01_metadata/components/organization/Type.vue
Normal file
659
src/modules/01_metadata/components/organization/Type.vue
Normal file
|
|
@ -0,0 +1,659 @@
|
||||||
|
<!-- tab ประเภทของหน่วยงาน/ส่วนราชการ หน้าจัดการข้อมูลหลัก/ข้อมูลโครงสร้างหน่วยงาน -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
color="green"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/organization/Type";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/organization/Type";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขประเภทของหน่วยงาน/ส่วนราชการ"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ประเภทของหน่วยงาน/ส่วนราชการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.organization.type.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.organization.type.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ประเภทของหน่วยงาน/ส่วนราชการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(2, "type", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationTypeHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationTypePublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listOrganizationTypeHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listOrganizationTypePublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listOrganizationTypeHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
663
src/modules/01_metadata/components/person/Blood.vue
Normal file
663
src/modules/01_metadata/components/person/Blood.vue
Normal file
|
|
@ -0,0 +1,663 @@
|
||||||
|
<!-- tab กลุ่มเลือด หน้าจัดการข้อมูลหลัก/ข้อมูลเกี่ยวกับบุคคล -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true" class="items-center">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
counter
|
||||||
|
maxlength="2"
|
||||||
|
>
|
||||||
|
<template v-slot:hint> ตัวอักษร </template></q-input
|
||||||
|
>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
size="34px"
|
||||||
|
color="positive"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/person/Blood";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/person/Blood";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขกลุ่มเลือด"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "กลุ่มเลือด",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px;",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.person.blood.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.person.blood.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "กลุ่มเลือด",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(1, "blood", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listBloodGroupHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listBloodGroupPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listBloodGroupHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listBloodGroupPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listBloodGroupHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
715
src/modules/01_metadata/components/person/District.vue
Normal file
715
src/modules/01_metadata/components/person/District.vue
Normal file
|
|
@ -0,0 +1,715 @@
|
||||||
|
<!-- tab เขต/อำเภอ หน้าจัดการข้อมูลหลัก/ข้อมูลเกี่ยวกับบุคคล -->
|
||||||
|
<template>
|
||||||
|
<div class="row items-center q-mb-sm q-mr-md q-ml-sm">
|
||||||
|
<q-btn icon="chevron_left" color="grey" flat dense @click="goToManage()">
|
||||||
|
<q-tooltip>กลับ</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
|
||||||
|
<div class="text-body1 text-weight-bold">การจัดการข้อมูลเขต</div>
|
||||||
|
<q-space />
|
||||||
|
<div @click="goToManage()" class="cursor-pointer">
|
||||||
|
การจัดการข้อมูลจังหวัด
|
||||||
|
<span class="text-primary text-weight-bold"> {{ provinceName }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<q-card flat bordered class="q-pa-md row col-12">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<div class="q-mt-md">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:nextPageVisible="true"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td
|
||||||
|
v-for="col in props.cols"
|
||||||
|
:key="col.name"
|
||||||
|
:props="props"
|
||||||
|
@click="clickRow(props.row.id)"
|
||||||
|
>
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
size="30px"
|
||||||
|
color="grey-8"
|
||||||
|
name="chevron_right"
|
||||||
|
@click="clickRow(props.row.id)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td
|
||||||
|
key="name"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.name !== undefined"
|
||||||
|
>
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) =>
|
||||||
|
(val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) ||
|
||||||
|
'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
color="green"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="
|
||||||
|
props.row.id === '00000000-0000-0000-0000-000000000000'
|
||||||
|
"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="
|
||||||
|
props.row.id !== '00000000-0000-0000-0000-000000000000'
|
||||||
|
"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-card>
|
||||||
|
</q-form>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/person/District";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/person/District";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useRoute, useRouter } from "vue-router";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { manageData, changeManageColumns, changeManageCurrentTab } = store;
|
||||||
|
const { loaderPage } = dataStore; //ขึ้นหน้า load ขณะเรียก api
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขเขต/อำเภอ"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
const router = useRouter();
|
||||||
|
const route = useRoute();
|
||||||
|
const provinceName = ref<string>("กรุงเทพมหานคร"); // ชื่อจังหวัดที่ต้องการดูเขต
|
||||||
|
const provinceId = ref<string | string[]>(route.params.province); // Id จังหวัดที่ต้องการดูเขต
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "เขต/อำเภอ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.person.district.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.person.district.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "เขต/อำเภอ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(1, "district", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listDistrictHistoryId(provinceId.value))
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
provinceName.value = data.provinceName.result;
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listDistrictPublishedHistory(provinceId.value))
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listDistrictHistoryId(provinceId.value))
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listProvincePublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listDistrictHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
provinceId: provinceId.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันกดเลือก row ไหนจะเปลี่ยนหน้าไปหาเขตทั้งหมดในจังหวัดที่กดเลือก
|
||||||
|
*/
|
||||||
|
const clickRow = (val: string) => {
|
||||||
|
router.push(`/metadata/province/${provinceId.value}/${val}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันย้อนกลับไปหน้าจัดการข้อมูลหลัก
|
||||||
|
*/
|
||||||
|
const goToManage = async () => {
|
||||||
|
await changeManageCurrentTab(1, "person_province");
|
||||||
|
router.push("/metadata");
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
660
src/modules/01_metadata/components/person/Education.vue
Normal file
660
src/modules/01_metadata/components/person/Education.vue
Normal file
|
|
@ -0,0 +1,660 @@
|
||||||
|
<!-- tab ระดับการศึกษา หน้าจัดการข้อมูลหลัก/ข้อมูลเกี่ยวกับบุคคล -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true" class="items-center">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
size="34px"
|
||||||
|
color="positive"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/person/Education";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/person/Education";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขระดับการศึกษา"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ระดับการศึกษา",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.person.education.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.person.education.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ระดับการศึกษา",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(1, "education", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listEducationLevelHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listEducationLevelPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listEducationLevelHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listEducationLevelPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listEducationLevelHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
660
src/modules/01_metadata/components/person/Gender.vue
Normal file
660
src/modules/01_metadata/components/person/Gender.vue
Normal file
|
|
@ -0,0 +1,660 @@
|
||||||
|
<!-- tab เพศ หน้าจัดการข้อมูลหลัก/ข้อมูลเกี่ยวกับบุคคล -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true" class="items-center">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
style="width: 150px"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
size="34px"
|
||||||
|
color="positive"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/person/Gender";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/person/Gender";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขเพศ"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "เพศ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.person.gender.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.person.gender.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "เพศ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(1, "gender", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listGenderHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listGenderPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listGenderHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listGenderPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listGenderHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
660
src/modules/01_metadata/components/person/Prefix.vue
Normal file
660
src/modules/01_metadata/components/person/Prefix.vue
Normal file
|
|
@ -0,0 +1,660 @@
|
||||||
|
<!-- tab คำนำหน้า หน้าจัดการข้อมูลหลัก/ข้อมูลเกี่ยวกับบุคคล -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true" class="items-center">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
size="34px"
|
||||||
|
color="positive"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/person/Prefix";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/person/Prefix";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขคำนำหน้า"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "คำนำหน้า",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.person.prefix.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.person.prefix.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "คำนำหน้า",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(1, "prefix", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPrefixHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPrefixPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listPrefixHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPrefixPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listPrefixHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
679
src/modules/01_metadata/components/person/Province.vue
Normal file
679
src/modules/01_metadata/components/person/Province.vue
Normal file
|
|
@ -0,0 +1,679 @@
|
||||||
|
<!-- tab จังหวัด หน้าจัดการข้อมูลหลัก/ข้อมูลเกี่ยวกับบุคคล -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
:nextPageVisible="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td
|
||||||
|
v-for="col in props.cols"
|
||||||
|
:key="col.name"
|
||||||
|
:props="props"
|
||||||
|
@click="clickRow(props.row.id)"
|
||||||
|
>
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
size="30px"
|
||||||
|
color="grey-8"
|
||||||
|
name="chevron_right"
|
||||||
|
@click="clickRow(props.row.id)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true" class="items-center">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
size="34px"
|
||||||
|
color="positive"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/person/Province";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/person/Province";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore; //ขึ้นหน้า load ขณะเรียก api
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขจังหวัด"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
const router = useRouter();
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "จังหวัด",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.person.province.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.person.province.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "จังหวัด",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(1, "province", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listProvinceHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listProvincePublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listProvinceHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listProvincePublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listProvinceHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันกดเลือก row ไหนจะเปลี่ยนหน้าไปหาเขตทั้งหมดในจังหวัดที่กดเลือก
|
||||||
|
*/
|
||||||
|
const clickRow = (val: string) => {
|
||||||
|
router.push(`/metadata/province/${val}`);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
660
src/modules/01_metadata/components/person/Relationship.vue
Normal file
660
src/modules/01_metadata/components/person/Relationship.vue
Normal file
|
|
@ -0,0 +1,660 @@
|
||||||
|
<!-- tab สถานภาพ หน้าจัดการข้อมูลหลัก/ข้อมูลเกี่ยวกับบุคคล -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true" class="items-center">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
size="34px"
|
||||||
|
color="positive"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/person/Relationship";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/person/Relationship";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขสถานภาพ"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานภาพ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.person.relationship.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.person.relationship.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานภาพ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(1, "relationship", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listRelationshipHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listRelationshipPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listRelationshipHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listRelationshipPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listRelationshipHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
660
src/modules/01_metadata/components/person/Religion.vue
Normal file
660
src/modules/01_metadata/components/person/Religion.vue
Normal file
|
|
@ -0,0 +1,660 @@
|
||||||
|
<!-- tab ศาสนา หน้าจัดการข้อมูลหลัก/ข้อมูลเกี่ยวกับบุคคล -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true" class="items-center">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
size="34px"
|
||||||
|
color="positive"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/person/Religion";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/person/Religion";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขศาสนา"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ศาสนา",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.person.religion.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.person.religion.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ศาสนา",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(1, "religion", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listReligionHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listReligionPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listReligionHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listReligionPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listReligionHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
769
src/modules/01_metadata/components/person/SubDistrict.vue
Normal file
769
src/modules/01_metadata/components/person/SubDistrict.vue
Normal file
|
|
@ -0,0 +1,769 @@
|
||||||
|
<!-- tab แขวง/ตำบล หน้าจัดการข้อมูลหลัก/ข้อมูลเกี่ยวกับบุคคล -->
|
||||||
|
<template>
|
||||||
|
<div class="row items-center q-mb-sm q-mr-md q-ml-sm">
|
||||||
|
<q-btn icon="chevron_left" color="grey" flat dense @click="goToProvince()">
|
||||||
|
<q-tooltip>กลับ</q-tooltip>
|
||||||
|
</q-btn>
|
||||||
|
|
||||||
|
<div class="text-body1 text-weight-bold">การจัดการข้อมูลแขวง/ตำบล</div>
|
||||||
|
<q-space />
|
||||||
|
<div @click="goToManage()" class="cursor-pointer">
|
||||||
|
การจัดการข้อมูลจังหวัด /
|
||||||
|
</div>
|
||||||
|
<div @click="goToProvince()" class="cursor-pointer">
|
||||||
|
จัดการข้อมูลเขต/อำเภอ
|
||||||
|
<span class="text-primary text-weight-bold"> {{ districtName }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<q-card flat bordered class="q-pa-md row col-12">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<div class="q-mt-md">
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td
|
||||||
|
key="name"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.name !== undefined"
|
||||||
|
>
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) =>
|
||||||
|
(val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) ||
|
||||||
|
'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="zipCode"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.zipCode !== undefined"
|
||||||
|
>
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.zipCode"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) =>
|
||||||
|
(val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
color="green"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="
|
||||||
|
props.row.id === '00000000-0000-0000-0000-000000000000'
|
||||||
|
"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="
|
||||||
|
props.row.id !== '00000000-0000-0000-0000-000000000000'
|
||||||
|
"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-card>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/person/SubDistrict";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/person/SubDistrict";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useRoute, useRouter } from "vue-router";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { manageData, changeManageColumns, changeManageCurrentTab } = store;
|
||||||
|
const { loaderPage } = dataStore; //ขึ้นหน้า load ขณะเรียก api
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขแขวง/ตำบล"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
const router = useRouter();
|
||||||
|
const route = useRoute();
|
||||||
|
const districtName = ref<string>("เขตพระนคร"); // ชื่อเขตที่ต้องการดูแขวง
|
||||||
|
const provinceId = ref<string | string[]>(route.params.province); // Id จังหวัดที่ต้องการดูเขต
|
||||||
|
const districtId = ref<string | string[]>(route.params.district); // Id เขตที่ต้องการดูแขวง
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "แขวง/ตำบล",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "zipCode",
|
||||||
|
align: "left",
|
||||||
|
label: "รหัสไปรษณีย์",
|
||||||
|
sortable: true,
|
||||||
|
field: "zipCode",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.person.subDistrict.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"zipCode",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.person.subDistrict.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "แขวง/ตำบล",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "zipCode",
|
||||||
|
align: "left",
|
||||||
|
label: "รหัสไปรษณีย์",
|
||||||
|
sortable: true,
|
||||||
|
field: "zipCode",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"zipCode",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(1, "subDistrict", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(
|
||||||
|
config.API.listSubDistrictHistoryProvinceId(
|
||||||
|
provinceId.value,
|
||||||
|
districtId.value
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
districtName.value = data.districtName.result;
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
zipCode: e.zipCode,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listSubDistrictPublishedHistory(districtId.value))
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
zipCode: i.zipCode,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listSubDistrictHistoryId(districtId.value))
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listProvincePublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" &&
|
||||||
|
(f.name == "" || f.zipCode == "") //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
zipCode: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
zipCode: e.zipCode,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listSubDistrictHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
districtId: districtId.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็ครหัสไปรษณีย์ซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input รหัสไปรษณีย์
|
||||||
|
*/
|
||||||
|
const checkDupDataZipCode = (val: string) => {
|
||||||
|
const filterZipCodeNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.zipCode == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterZipCodeNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันย้อนกลับไปหน้าจัดการข้อมูลหลัก
|
||||||
|
*/
|
||||||
|
const goToManage = () => {
|
||||||
|
changeManageCurrentTab(1, "person_province");
|
||||||
|
router.push("/metadata");
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันย้อนกลับไปหน้าจัดการเขต
|
||||||
|
*/
|
||||||
|
const goToProvince = () => {
|
||||||
|
router.push(`/metadata/province/${provinceId.value}`);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
660
src/modules/01_metadata/components/position/Executive.vue
Normal file
660
src/modules/01_metadata/components/position/Executive.vue
Normal file
|
|
@ -0,0 +1,660 @@
|
||||||
|
<!-- tab ชื่อตำแหน่งทางการบริหาร หน้าจัดการข้อมูลหลัก/ข้อมูลตำแหน่งของข้าราชการกรุงเทพมหานคร -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
size="34px"
|
||||||
|
color="positive"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/position/Executive";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/position/Executive";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขชื่อตำแหน่งทางการบริหาร"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ชื่อตำแหน่งทางการบริหาร",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.position.executive.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.position.executive.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ชื่อตำแหน่งทางการบริหาร",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(3, "executive", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionExecutiveHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionExecutivePublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listPositionExecutiveHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionExecutivePublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listPositionExecutiveHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
699
src/modules/01_metadata/components/position/ExecutiveSide.vue
Normal file
699
src/modules/01_metadata/components/position/ExecutiveSide.vue
Normal file
|
|
@ -0,0 +1,699 @@
|
||||||
|
<!-- tab ด้านทางการบริหาร หน้าจัดการข้อมูลหลัก/ข้อมูลตำแหน่งของข้าราชการกรุงเทพมหานคร -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
size="34px"
|
||||||
|
color="positive"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="note" :props="props" v-if="props.row.note !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.note"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/position/ExecutiveSide";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/position/ExecutiveSide";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขด้านทางการบริหาร"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ด้านทางการบริหาร",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "note",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเหตุ",
|
||||||
|
sortable: true,
|
||||||
|
field: "note",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.position.executiveSide.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
"note",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.position.executiveSide.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ด้านทางการบริหาร",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "note",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเหตุ",
|
||||||
|
sortable: true,
|
||||||
|
field: "note",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
"note",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(3, "executiveSide", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionExecutiveSideHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
note: e.note,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionExecutiveSidePublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
note: i.note,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listPositionExecutiveSideHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionExecutiveSidePublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
note: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listPositionExecutiveSideHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
837
src/modules/01_metadata/components/position/Level.vue
Normal file
837
src/modules/01_metadata/components/position/Level.vue
Normal file
|
|
@ -0,0 +1,837 @@
|
||||||
|
<!-- tab ระดับ หน้าจัดการข้อมูลหลัก/ข้อมูลตำแหน่งของข้าราชการกรุงเทพมหานคร -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td
|
||||||
|
key="level"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.level !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ props.row.level }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="shortName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.shortName !== undefined"
|
||||||
|
>
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.shortName"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataShortName(val) ||
|
||||||
|
'ชื่อย่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
size="34px"
|
||||||
|
color="positive"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<div class="row">
|
||||||
|
<q-btn
|
||||||
|
:disable="props.row.level <= 1"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
size="12px"
|
||||||
|
icon="mdi-menu-up"
|
||||||
|
style="
|
||||||
|
padding-top: 0em;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
padding-bottom: 0em;
|
||||||
|
padding-left: 0.5em;
|
||||||
|
min-height: 0em;
|
||||||
|
"
|
||||||
|
@click="directionItem(props.row, 'up')"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
:disable="props.row.level >= rows.length"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
size="12px"
|
||||||
|
icon="mdi-menu-down"
|
||||||
|
style="
|
||||||
|
padding-top: 0em;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
padding-bottom: 0em;
|
||||||
|
padding-left: 0.5em;
|
||||||
|
min-height: 0em;
|
||||||
|
"
|
||||||
|
@click="directionItem(props.row, 'down')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/position/Level";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/position/Level";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขระดับ"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "level",
|
||||||
|
align: "left",
|
||||||
|
label: "ลำดับ",
|
||||||
|
sortable: true,
|
||||||
|
field: "level",
|
||||||
|
headerStyle: "font-size: 14px; width:0px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ระดับ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "shortName",
|
||||||
|
align: "left",
|
||||||
|
label: "ชื่อย่อ",
|
||||||
|
sortable: true,
|
||||||
|
field: "shortName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.position.level.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"level",
|
||||||
|
"name",
|
||||||
|
"shortName",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.position.level.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "level",
|
||||||
|
align: "left",
|
||||||
|
label: "ลำดับ",
|
||||||
|
sortable: true,
|
||||||
|
field: "level",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ระดับ",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "shortName",
|
||||||
|
align: "left",
|
||||||
|
label: "ชื่อย่อ",
|
||||||
|
sortable: true,
|
||||||
|
field: "shortName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"level",
|
||||||
|
"name",
|
||||||
|
"shortName",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(3, "level", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionLevelHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
level: e.level,
|
||||||
|
name: e.name,
|
||||||
|
shortName: e.shortName,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
rows.value.sort(
|
||||||
|
(
|
||||||
|
firstItem: RequestItemsHistoryObject,
|
||||||
|
secondItem: RequestItemsHistoryObject
|
||||||
|
) => firstItem.level - secondItem.level
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionLevelPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
level: i.level,
|
||||||
|
name: i.name,
|
||||||
|
shortName: i.shortName,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listPositionLevelHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionLevelPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
level: rows.value[rows.value.length - 1].level + 1,
|
||||||
|
name: "",
|
||||||
|
shortName: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
level: e.level,
|
||||||
|
name: e.name,
|
||||||
|
shortName: e.shortName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listPositionLevelHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อย่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataShortName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.shortName == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ย้ายลำดับ data
|
||||||
|
* @param row ค่าใน row
|
||||||
|
* @param type ย้ายตำแหน่งแบบไหน up=ขึ้น down=ลง
|
||||||
|
*/
|
||||||
|
const directionItem = async (row: RequestItemsHistoryObject, type: string) => {
|
||||||
|
await clickEditRow();
|
||||||
|
if (type === "up") {
|
||||||
|
rows.value[
|
||||||
|
rows.value.findIndex((object: RequestItemsHistoryObject) => {
|
||||||
|
return object === row;
|
||||||
|
})
|
||||||
|
].level -= 1;
|
||||||
|
rows.value[
|
||||||
|
rows.value.findIndex((object: RequestItemsHistoryObject) => {
|
||||||
|
return object === row;
|
||||||
|
}) - 1
|
||||||
|
].level += 1;
|
||||||
|
} else {
|
||||||
|
rows.value[
|
||||||
|
rows.value.findIndex((object: RequestItemsHistoryObject) => {
|
||||||
|
return object === row;
|
||||||
|
})
|
||||||
|
].level += 1;
|
||||||
|
rows.value[
|
||||||
|
rows.value.findIndex((object: RequestItemsHistoryObject) => {
|
||||||
|
return object === row;
|
||||||
|
}) + 1
|
||||||
|
].level -= 1;
|
||||||
|
}
|
||||||
|
rows.value.sort(
|
||||||
|
(
|
||||||
|
firstItem: RequestItemsHistoryObject,
|
||||||
|
secondItem: RequestItemsHistoryObject
|
||||||
|
) => firstItem.level - secondItem.level
|
||||||
|
);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
660
src/modules/01_metadata/components/position/Line.vue
Normal file
660
src/modules/01_metadata/components/position/Line.vue
Normal file
|
|
@ -0,0 +1,660 @@
|
||||||
|
<!-- tab สายงาน หน้าจัดการข้อมูลหลัก/ข้อมูลตำแหน่งของข้าราชการกรุงเทพมหานคร -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
size="34px"
|
||||||
|
color="positive"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/position/Line";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/position/Line";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขสายงาน"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "สายงาน",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.position.line.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.position.line.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "สายงาน",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(3, "line", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionLineHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionLinePublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listPositionLineHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionLinePublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listPositionLineHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
699
src/modules/01_metadata/components/position/Path.vue
Normal file
699
src/modules/01_metadata/components/position/Path.vue
Normal file
|
|
@ -0,0 +1,699 @@
|
||||||
|
<!-- tab ชื่อตำแหน่ง หน้าจัดการข้อมูลหลัก/ข้อมูลตำแหน่งของข้าราชการกรุงเทพมหานคร -->
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<q-form ref="myForm">
|
||||||
|
<data-table
|
||||||
|
:rows="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:filter="filter"
|
||||||
|
:visible-columns="visibleColumns"
|
||||||
|
v-model:inputfilter="filter"
|
||||||
|
v-model:inputvisible="visibleColumns"
|
||||||
|
v-model:editvisible="edit"
|
||||||
|
:add="clickAdd"
|
||||||
|
:edit="clickEdit"
|
||||||
|
:save="clickSave"
|
||||||
|
:deleted="clickDelete"
|
||||||
|
:cancel="clickCancel"
|
||||||
|
:publish="clickPublish"
|
||||||
|
:validate="validateData"
|
||||||
|
:publicData="version === 'published'"
|
||||||
|
:updateData="updateData"
|
||||||
|
:history="true"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props" v-if="edit == false">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon
|
||||||
|
v-else
|
||||||
|
name="mdi-check"
|
||||||
|
color="positive"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'createdAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
<q-tr :props="props" v-if="edit == true">
|
||||||
|
<q-td key="name" :props="props" v-if="props.row.name !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.name"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
:rules="[
|
||||||
|
(val) => (val && val.length > 0) || 'กรุณากรอกข้อมูลให้ครบ',
|
||||||
|
(val) =>
|
||||||
|
checkDupDataName(val) || 'ชื่อซ้ำกันกับข้อมูลที่มีอยู่แล้ว',
|
||||||
|
]"
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="createdAt"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.createdAt !== undefined"
|
||||||
|
>
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.createdAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="lastUpdatedAt" :props="props">
|
||||||
|
<div class="">
|
||||||
|
{{ textDate(props.row.lastUpdatedAt) }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="lastUpdateFullName"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.lastUpdateFullName !== undefined"
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
{{ props.row.lastUpdateFullName }}
|
||||||
|
</q-td>
|
||||||
|
<q-td
|
||||||
|
key="isActive"
|
||||||
|
:props="props"
|
||||||
|
v-if="props.row.isActive !== undefined"
|
||||||
|
>
|
||||||
|
<q-toggle
|
||||||
|
v-model="props.row.isActive"
|
||||||
|
dense
|
||||||
|
size="34px"
|
||||||
|
color="positive"
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
<q-td key="note" :props="props" v-if="props.row.note !== undefined">
|
||||||
|
<q-input
|
||||||
|
class=""
|
||||||
|
outlined
|
||||||
|
@update:model-value="clickEditRow"
|
||||||
|
v-model="props.row.note"
|
||||||
|
dense
|
||||||
|
lazy-rules
|
||||||
|
autofocus
|
||||||
|
hide-bottom-space
|
||||||
|
></q-input>
|
||||||
|
</q-td>
|
||||||
|
|
||||||
|
<q-td auto-width>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id === '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="red"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-trash-can-outline"
|
||||||
|
@click="clickDeleteRow(props.row)"
|
||||||
|
/>
|
||||||
|
<q-btn
|
||||||
|
v-if="props.row.id !== '00000000-0000-0000-0000-000000000000'"
|
||||||
|
color="info"
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
round
|
||||||
|
size="14px"
|
||||||
|
icon="mdi-history"
|
||||||
|
@click="clickHistory(props.row)"
|
||||||
|
/>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</data-table>
|
||||||
|
</q-form>
|
||||||
|
</div>
|
||||||
|
<HistoryTable
|
||||||
|
:rows="rowsHistory"
|
||||||
|
:columns="columnsHistory"
|
||||||
|
:filter="filterHistory"
|
||||||
|
:visible-columns="visibleColumnsHistory"
|
||||||
|
v-model:modal="modalHistory"
|
||||||
|
v-model:inputfilter="filterHistory"
|
||||||
|
v-model:inputvisible="visibleColumnsHistory"
|
||||||
|
v-model:tittle="tittleHistory"
|
||||||
|
>
|
||||||
|
<template #columns="props">
|
||||||
|
<q-tr :props="props">
|
||||||
|
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||||
|
<div v-if="col.name == 'isActive'" class="">
|
||||||
|
<q-icon
|
||||||
|
v-if="col.value == false"
|
||||||
|
name="mdi-close"
|
||||||
|
color="red"
|
||||||
|
class="text-h5"
|
||||||
|
/>
|
||||||
|
<q-icon v-else name="mdi-check" color="positive" class="text-h5" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="col.name == 'lastUpdatedAt'" class="">
|
||||||
|
{{ textDate(col.value) }}
|
||||||
|
</div>
|
||||||
|
<div v-else class="">
|
||||||
|
{{ col.value }}
|
||||||
|
</div>
|
||||||
|
</q-td>
|
||||||
|
</q-tr>
|
||||||
|
</template>
|
||||||
|
</HistoryTable>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { QTableProps } from "quasar";
|
||||||
|
import { useQuasar } from "quasar";
|
||||||
|
import { onMounted, ref, watch } from "vue";
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
import keycloak from "@/plugins/keycloak";
|
||||||
|
import { useCounterMixin } from "@/stores/mixin";
|
||||||
|
import { useManageDataStore } from "@/modules/01_metadata/store";
|
||||||
|
import type {
|
||||||
|
RequestItemsHistoryObject,
|
||||||
|
RequestItemsPublishHistoryObject,
|
||||||
|
Columns,
|
||||||
|
} from "@/modules/01_metadata/interface/request/position/Path";
|
||||||
|
import type { ResponseHistoryObject } from "@/modules/01_metadata/interface/response/position/Path";
|
||||||
|
import HistoryTable from "@/components/TableHistory.vue";
|
||||||
|
import { useDataStore } from "@/stores/data";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
fetchDataComponent: {
|
||||||
|
type: Function,
|
||||||
|
default: () => console.log("not function"),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const dataStore = useDataStore();
|
||||||
|
const { loaderPage } = dataStore;
|
||||||
|
const mixin = useCounterMixin();
|
||||||
|
const { success, dateText, messageError } = mixin;
|
||||||
|
const store = useManageDataStore();
|
||||||
|
const { manageData, changeManageColumns } = store;
|
||||||
|
const rows = ref<RequestItemsHistoryObject[]>([]); //list data table
|
||||||
|
const rowsHistory = ref<RequestItemsHistoryObject[]>([]); //select data history
|
||||||
|
const rawHistory = ref<RequestItemsHistoryObject[]>([]); //raw data history
|
||||||
|
const tittleHistory = ref<string>("ประวัติแก้ไขชื่อตำแหน่ง"); //
|
||||||
|
const myForm = ref<any>(null); //ref สำหรับเช็คข้อมูลว่ามีช่องว่างไหม
|
||||||
|
const filter = ref<string>(""); //search data table
|
||||||
|
const filterHistory = ref<string>(""); //search data table history
|
||||||
|
const modalHistory = ref<boolean>(false); //modal ประวัติการแก้ไขข้อมูล
|
||||||
|
const edit = ref<boolean>(false); //ตรวจสอบการกดปุ่มแก้ไขข้อมูล
|
||||||
|
const idVersion = ref<string>(""); //id data ใน mongodb
|
||||||
|
const version = ref<string>("published"); //รายการข้อมูลล่าสุดได้เผยแพร่หรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
const updateData = ref<boolean>(false); //ตรวจสอบการแก้ไขข้อมูลว่าได้แก้ไขหรือไม่
|
||||||
|
|
||||||
|
const checkValidate = ref<boolean>(false);
|
||||||
|
|
||||||
|
const columns = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ชื่อตำแหน่ง",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "createdAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่สร้าง",
|
||||||
|
sortable: true,
|
||||||
|
field: "createdAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "note",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเหตุ",
|
||||||
|
sortable: true,
|
||||||
|
field: "note",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumns = ref<String[]>([]);
|
||||||
|
manageData.position.path.columns.length == 0
|
||||||
|
? (visibleColumns.value = [
|
||||||
|
"name",
|
||||||
|
"createdAt",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
"note",
|
||||||
|
])
|
||||||
|
: (visibleColumns.value = manageData.position.path.columns);
|
||||||
|
|
||||||
|
const columnsHistory = ref<QTableProps["columns"]>([
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
align: "left",
|
||||||
|
label: "ชื่อตำแหน่ง",
|
||||||
|
sortable: true,
|
||||||
|
field: "name",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdatedAt",
|
||||||
|
align: "center",
|
||||||
|
label: "วันที่แก้ไข",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdatedAt",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "lastUpdateFullName",
|
||||||
|
align: "left",
|
||||||
|
label: "ผู้ดำเนินการ",
|
||||||
|
sortable: true,
|
||||||
|
field: "lastUpdateFullName",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "isActive",
|
||||||
|
align: "left",
|
||||||
|
label: "สถานะ",
|
||||||
|
sortable: true,
|
||||||
|
field: "isActive",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "note",
|
||||||
|
align: "left",
|
||||||
|
label: "หมายเหตุ",
|
||||||
|
sortable: true,
|
||||||
|
field: "note",
|
||||||
|
headerStyle: "font-size: 14px",
|
||||||
|
style: "font-size: 14px",
|
||||||
|
sort: (a: string, b: string) =>
|
||||||
|
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const visibleColumnsHistory = ref<String[]>([
|
||||||
|
"name",
|
||||||
|
"lastUpdatedAt",
|
||||||
|
"lastUpdateFullName",
|
||||||
|
"isActive",
|
||||||
|
"note",
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เมื่อเข้าหน้านี้จะเรียกฟังชันนี้ก่อน(get list data)
|
||||||
|
*/
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchData();
|
||||||
|
await fetchHistory();
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(visibleColumns, async (count: String[], prevCount: String[]) => {
|
||||||
|
await changeManageColumns(3, "path", count);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* แจ้งเตือนข้อมูลในกรณี success
|
||||||
|
*/
|
||||||
|
const $q = useQuasar();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน get data ล่าสุด
|
||||||
|
*/
|
||||||
|
const fetchData = async () => {
|
||||||
|
await props.fetchDataComponent();
|
||||||
|
rows.value.splice(0);
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionPathHistory)
|
||||||
|
.then((res) => {
|
||||||
|
let data = res.data.result;
|
||||||
|
version.value = data.version; //ตัวแปรที่บอกว่าข้อมูลเผยแพร่ไปหรือยัง published=เผยแพร่แล้ว draft=ยังไม่เผยแพร่
|
||||||
|
idVersion.value = data.id; //เลข id ใน mongodb
|
||||||
|
data.items.map((e: RequestItemsHistoryObject) => {
|
||||||
|
rows.value.push({
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
note: e.note,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
updateData.value = false;
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลทั้งหมด
|
||||||
|
*/
|
||||||
|
const fetchHistory = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionPathPublishedHistory)
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result;
|
||||||
|
rawHistory.value = [];
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.map((e: RequestItemsPublishHistoryObject) => {
|
||||||
|
e.items.map((i: RequestItemsHistoryObject) => {
|
||||||
|
rawHistory.value.push({
|
||||||
|
createdAt: i.createdAt,
|
||||||
|
createdFullName: i.createdFullName,
|
||||||
|
createdUserId: i.createdUserId,
|
||||||
|
id: i.id,
|
||||||
|
isActive: i.isActive,
|
||||||
|
lastUpdateFullName: i.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: i.lastUpdateUserId,
|
||||||
|
lastUpdatedAt: i.lastUpdatedAt,
|
||||||
|
name: i.name,
|
||||||
|
note: i.note,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชัน clear data แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clearPublishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.delete(config.API.listPositionPathHistory)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "ลบข้อมูลร่างสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchHistory();
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเผยแพร่แบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const publishedData = async () => {
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.get(config.API.listPositionPathPublished)
|
||||||
|
.then((res) => {
|
||||||
|
success($q, "เผยแพร่ข้อมูลสำเร็จ");
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(async () => {
|
||||||
|
await fetchData();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเพิ่มข้อมูล
|
||||||
|
*/
|
||||||
|
const clickAdd = async () => {
|
||||||
|
const filterRowNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) =>
|
||||||
|
f.id === "00000000-0000-0000-0000-000000000000" && f.name == "" //เช็คข้อมูลใน array ว่าเป็นข้อมูลที่เพิ่มมาใหม่และยังไม่มีการกรอกข้อมูล
|
||||||
|
);
|
||||||
|
if (filterRowNull.length == 0) {
|
||||||
|
//ถ้าไม่เจอค่าจะให้เพิ่มข้อมูลใหม่ได้
|
||||||
|
rows.value.push({
|
||||||
|
createdAt: new Date(),
|
||||||
|
createdFullName: "",
|
||||||
|
createdUserId: "",
|
||||||
|
id: "00000000-0000-0000-0000-000000000000",
|
||||||
|
isActive: true,
|
||||||
|
lastUpdateFullName:
|
||||||
|
keycloak.tokenParsed == null ? "" : keycloak.tokenParsed.name,
|
||||||
|
lastUpdateUserId: "",
|
||||||
|
lastUpdatedAt: new Date(),
|
||||||
|
name: "",
|
||||||
|
note: "",
|
||||||
|
});
|
||||||
|
updateData.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันบันทึกแบบร่าง
|
||||||
|
* เมื่อเรียก api เสร็จแล้วจะ get data มาใหม่
|
||||||
|
* publish เมื่อบันทึกแบบร่างแล้วจะเผยแพร่เลยไหม true=บันทึกและเผยแพร่ false=บันทึกอย่างเดียว
|
||||||
|
*/
|
||||||
|
const save = async (publish: boolean) => {
|
||||||
|
await validateData();
|
||||||
|
if (checkValidate.value == false) return;
|
||||||
|
rows.value.map((e: ResponseHistoryObject) => ({
|
||||||
|
//จัด data ก่อนส่งไป backend
|
||||||
|
id: e.id,
|
||||||
|
createdAt: e.createdAt,
|
||||||
|
lastUpdatedAt: e.lastUpdatedAt,
|
||||||
|
name: e.name,
|
||||||
|
isActive: e.isActive,
|
||||||
|
createdFullName: e.createdFullName,
|
||||||
|
createdUserId: e.createdUserId,
|
||||||
|
lastUpdateFullName: e.lastUpdateFullName,
|
||||||
|
lastUpdateUserId: e.lastUpdateUserId,
|
||||||
|
}));
|
||||||
|
loaderPage(true);
|
||||||
|
await http
|
||||||
|
.post(config.API.listPositionPathHistoryId(idVersion.value), {
|
||||||
|
id: idVersion.value,
|
||||||
|
version: "draft",
|
||||||
|
items: rows.value,
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (publish === false) {
|
||||||
|
success($q, "บันทึกข้อมูลร่างสำเร็จ");
|
||||||
|
await fetchData(); //ไม่เผยแพร่และ get data ล่าสุดมาใหม่
|
||||||
|
} else {
|
||||||
|
await publishedData(); //เผยแพร่ข้อมูลต
|
||||||
|
}
|
||||||
|
edit.value = false;
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
messageError($q, e);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loaderPage(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* เช็คชื่อซ้ำกับข้อมูลที่มีอยู่แล้ว
|
||||||
|
* @param val input ชื่อ
|
||||||
|
*/
|
||||||
|
const checkDupDataName = (val: string) => {
|
||||||
|
const filterNameNull = rows.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.name == val
|
||||||
|
); //เช็คข้อมูลว่ากรอกชื่อซ้ำไหม
|
||||||
|
if (filterNameNull.length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มแก้ไข ให้ get data มาใหม่
|
||||||
|
*/
|
||||||
|
const clickEdit = async () => {
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มบันทึกแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickSave = async () => {
|
||||||
|
await save(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบแบบร่าง
|
||||||
|
*/
|
||||||
|
const clickDelete = async () => {
|
||||||
|
await clearPublishedData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มยกเลิกการแก้ไขข้อมูล
|
||||||
|
*/
|
||||||
|
const clickCancel = async () => {
|
||||||
|
edit.value = false;
|
||||||
|
await fetchData();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มเผยแพร่ข้อมูล
|
||||||
|
* เช็คข้อมูลก่อนว่าใน array กรอกข้อมูลครบไหมถ้าครบก็ให้เผยแพร่ได้
|
||||||
|
* ถ้าค่าใน array ไม่มีข้อมูลใน row ก้จะให้บันทึกได้
|
||||||
|
*/
|
||||||
|
const clickPublish = async () => {
|
||||||
|
if (myForm.value !== null) {
|
||||||
|
myForm.value.validate().then(async (result: boolean) => {
|
||||||
|
if (result) {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await save(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันปุ่มลบ row data
|
||||||
|
* @param val data ใน row ที่จะลบ
|
||||||
|
*/
|
||||||
|
const clickDeleteRow = (val: RequestItemsHistoryObject) => {
|
||||||
|
rows.value = rows.value.filter((x: RequestItemsHistoryObject) => x !== val);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันเช็ค input ว่ามีการแก้ไขหรือยัง
|
||||||
|
*/
|
||||||
|
const clickEditRow = () => {
|
||||||
|
myForm.value.validate(false);
|
||||||
|
updateData.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||||
|
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||||
|
*/
|
||||||
|
const clickHistory = async (row: RequestItemsHistoryObject) => {
|
||||||
|
modalHistory.value = true;
|
||||||
|
rowsHistory.value = rawHistory.value.filter(
|
||||||
|
(f: RequestItemsHistoryObject) => f.id == row.id
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ฟังก์ชันแปลง date เป็นภาษาไทย
|
||||||
|
* @param value วันที่ type datetime ที่จะแปลงเป็นไทย
|
||||||
|
*/
|
||||||
|
const textDate = (value: Date) => {
|
||||||
|
return dateText(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate component
|
||||||
|
*/
|
||||||
|
const validateData = async () => {
|
||||||
|
checkValidate.value = true;
|
||||||
|
await myForm.value.validate().then((result: boolean) => {
|
||||||
|
if (result == false) {
|
||||||
|
checkValidate.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* สีของnoti */
|
||||||
|
.my-notif-class {
|
||||||
|
background: rgba(33, 186, 69, 0.5) !important;
|
||||||
|
color: #008f17 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue