Initial Smartproc
2
.env
Normal file
@ -0,0 +1,2 @@
|
||||
VUE_APP_ROOT_API=http://localhost:9090/api
|
||||
VUE_APP_PUBLIC_KEY=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx3MRA7zxvaWKrtmPl2hRJLFiyryvj0ZUlmWw9OZIgqwJUDBTsg5yFX4hCQrANV1yy5ibTqAn2APdNCdhGgp8R2YLWrUR2vVGbmnKXXzEDsFpT6cgo
|
2
.env.production
Normal file
@ -0,0 +1,2 @@
|
||||
VUE_APP_ROOT_API=https://pln.co.id/smartproc-service/api
|
||||
VUE_APP_PUBLIC_KEY=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx3MRA7zxvaWKrtmPl2hRJLFiyryvj0ZUlmWw9OZIgqwJUDBTsg5yFX4hCQrANV1yy5ibTqAn2APdNCdhGgp8R2YLWrUR2vVGbmnKXXzEDsFpT6cgo
|
18
.gitignore
vendored
@ -48,3 +48,21 @@ Thumbs.db
|
||||
*.mov
|
||||
*.wmv
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
41
README.md
Normal file
@ -0,0 +1,41 @@
|
||||
# vue
|
||||
|
||||
## Project setup
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||
|
||||
## Extreme dev Reference
|
||||
### Add a View to Application
|
||||
|
||||
```
|
||||
devextreme add view view-name [--icon]
|
||||
example :
|
||||
devextreme add view jenis-kontrak --icon=doc
|
||||
// ===== or =====
|
||||
npx devextreme-cli add view view-name [--icon]
|
||||
```
|
||||
|
||||
[Icon Reference](https://js.devexpress.com/Documentation/Guide/Themes_and_Styles/Icons/#Built-In_Icon_Library)
|
||||
|
||||
npm run build
|
||||
|
||||
npm run build-themes
|
5
babel.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
39
devextreme.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"applicationEngine": "vue",
|
||||
"vue": {
|
||||
"version": 3,
|
||||
"template": "javascript"
|
||||
},
|
||||
"build": {
|
||||
"commands": [
|
||||
{
|
||||
"command": "build-theme",
|
||||
"options": {
|
||||
"inputFile": "src/themes/metadata.base.json",
|
||||
"outputFile": "src/themes/generated/theme.base.css"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "build-theme",
|
||||
"options": {
|
||||
"inputFile": "src/themes/metadata.additional.json",
|
||||
"outputFile": "src/themes/generated/theme.additional.css"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "export-theme-vars",
|
||||
"options": {
|
||||
"inputFile": "src/themes/metadata.base.json",
|
||||
"outputFile": "src/themes/generated/variables.base.scss"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "export-theme-vars",
|
||||
"options": {
|
||||
"inputFile": "src/themes/metadata.additional.json",
|
||||
"outputFile": "src/themes/generated/variables.additional.scss"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
19
jsconfig.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "esnext",
|
||||
"baseUrl": "./",
|
||||
"moduleResolution": "node",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
}
|
||||
}
|
14281
package-lock.json
generated
Normal file
56
package.json
Normal file
@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "vue",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint",
|
||||
"build-themes": "devextreme build",
|
||||
"postinstall": "npm run build-themes"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^3.8.3",
|
||||
"devextreme": "^22.2.4",
|
||||
"devextreme-vue": "^22.2.4",
|
||||
"exceljs": "^4.3.0",
|
||||
"file-saver-es": "^2.0.5",
|
||||
"jspdf": "^2.5.1",
|
||||
"node-forge": "^1.3.1",
|
||||
"sass": "^1.34.1",
|
||||
"vue": "^3.2.13",
|
||||
"vue-router": "^4.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.16",
|
||||
"@babel/eslint-parser": "^7.12.16",
|
||||
"@vue/cli-plugin-babel": "~5.0.0",
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"devextreme-cli": "1.5.1",
|
||||
"devextreme-themebuilder": "^22.2.4",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"sass-loader": "^10"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/vue3-essential",
|
||||
"eslint:recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"parser": "@babel/eslint-parser"
|
||||
},
|
||||
"rules": {}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not dead",
|
||||
"not ie 11"
|
||||
]
|
||||
}
|
10629
public/css/bootstrap.min.css
vendored
Normal file
6
public/css/owl.carousel.min.css
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Owl Carousel v2.3.4
|
||||
* Copyright 2013-2018 David Deutsch
|
||||
* Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
|
||||
*/
|
||||
.owl-carousel,.owl-carousel .owl-item{-webkit-tap-highlight-color:transparent;position:relative}.owl-carousel{display:none;width:100%;z-index:1}.owl-carousel .owl-stage{position:relative;-ms-touch-action:pan-Y;touch-action:manipulation;-moz-backface-visibility:hidden}.owl-carousel .owl-stage:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0}.owl-carousel .owl-stage-outer{position:relative;overflow:hidden;-webkit-transform:translate3d(0,0,0)}.owl-carousel .owl-item,.owl-carousel .owl-wrapper{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0)}.owl-carousel .owl-item{min-height:1px;float:left;-webkit-backface-visibility:hidden;-webkit-touch-callout:none}.owl-carousel .owl-item img{display:block;width:100%}.owl-carousel .owl-dots.disabled,.owl-carousel .owl-nav.disabled{display:none}.no-js .owl-carousel,.owl-carousel.owl-loaded{display:block}.owl-carousel .owl-dot,.owl-carousel .owl-nav .owl-next,.owl-carousel .owl-nav .owl-prev{cursor:pointer;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.owl-carousel .owl-nav button.owl-next,.owl-carousel .owl-nav button.owl-prev,.owl-carousel button.owl-dot{background:0 0;color:inherit;border:none;padding:0!important;font:inherit}.owl-carousel.owl-loading{opacity:0;display:block}.owl-carousel.owl-hidden{opacity:0}.owl-carousel.owl-refresh .owl-item{visibility:hidden}.owl-carousel.owl-drag .owl-item{-ms-touch-action:pan-y;touch-action:pan-y;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.owl-carousel.owl-grab{cursor:move;cursor:grab}.owl-carousel.owl-rtl{direction:rtl}.owl-carousel.owl-rtl .owl-item{float:right}.owl-carousel .animated{animation-duration:1s;animation-fill-mode:both}.owl-carousel .owl-animated-in{z-index:0}.owl-carousel .owl-animated-out{z-index:1}.owl-carousel .fadeOut{animation-name:fadeOut}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.owl-height{transition:height .5s ease-in-out}.owl-carousel .owl-item .owl-lazy{opacity:0;transition:opacity .4s ease}.owl-carousel .owl-item .owl-lazy:not([src]),.owl-carousel .owl-item .owl-lazy[src^=""]{max-height:0}.owl-carousel .owl-item img.owl-lazy{transform-style:preserve-3d}.owl-carousel .owl-video-wrapper{position:relative;height:100%;background:#000}.owl-carousel .owl-video-play-icon{position:absolute;height:80px;width:80px;left:50%;top:50%;margin-left:-40px;margin-top:-40px;background:url(owl.video.play.png) no-repeat;cursor:pointer;z-index:1;-webkit-backface-visibility:hidden;transition:transform .1s ease}.owl-carousel .owl-video-play-icon:hover{-ms-transform:scale(1.3,1.3);transform:scale(1.3,1.3)}.owl-carousel .owl-video-playing .owl-video-play-icon,.owl-carousel .owl-video-playing .owl-video-tn{display:none}.owl-carousel .owl-video-tn{opacity:0;height:100%;background-position:center center;background-repeat:no-repeat;background-size:contain;transition:opacity .4s ease}.owl-carousel .owl-video-frame{position:relative;z-index:1;height:100%;width:100%}
|
228
public/css/style.css
Normal file
@ -0,0 +1,228 @@
|
||||
body {
|
||||
font-family: "Roboto", sans-serif;
|
||||
background-color: #fff; }
|
||||
|
||||
p {
|
||||
color: #b3b3b3;
|
||||
font-weight: 300; }
|
||||
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
.h1, .h2, .h3, .h4, .h5, .h6 {
|
||||
font-family: "Roboto", sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
-webkit-transition: .3s all ease;
|
||||
-o-transition: .3s all ease;
|
||||
transition: .3s all ease; }
|
||||
a:hover {
|
||||
text-decoration: none !important; }
|
||||
|
||||
.content {
|
||||
padding: 7rem 0; }
|
||||
|
||||
h2 {
|
||||
font-size: 20px; }
|
||||
|
||||
.half, .half .container > .row {
|
||||
height: 100vh; }
|
||||
|
||||
@media (max-width: 991.98px) {
|
||||
.half .bg {
|
||||
height: 500px; } }
|
||||
|
||||
.half .contents, .half .bg {
|
||||
width: 50%; }
|
||||
@media (max-width: 1199.98px) {
|
||||
.half .contents, .half .bg {
|
||||
width: 100%; } }
|
||||
.half .contents .form-group, .half .bg .form-group {
|
||||
overflow: hidden;
|
||||
margin-bottom: 0;
|
||||
border: 1px solid #efefef;
|
||||
padding: 15px 15px;
|
||||
border-bottom: none;
|
||||
position: relative; }
|
||||
.half .contents .form-group label, .half .bg .form-group label {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
-webkit-transform: translateY(-50%);
|
||||
-ms-transform: translateY(-50%);
|
||||
transform: translateY(-50%);
|
||||
-webkit-transition: .3s all ease;
|
||||
-o-transition: .3s all ease;
|
||||
transition: .3s all ease; }
|
||||
.half .contents .form-group input:focus + label, .half .bg .form-group input:focus + label {
|
||||
margin-top: -20px; }
|
||||
.half .contents .form-group.first, .half .bg .form-group.first {
|
||||
border-top-left-radius: 7px;
|
||||
border-top-right-radius: 7px; }
|
||||
.half .contents .form-group.last, .half .bg .form-group.last {
|
||||
border-bottom: 1px solid #efefef;
|
||||
border-bottom-left-radius: 7px;
|
||||
border-bottom-right-radius: 7px; }
|
||||
.half .contents .form-group label, .half .bg .form-group label {
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
margin-bottom: 0;
|
||||
color: #b3b3b3; }
|
||||
.half .contents .form-group.field--not-empty label, .half .bg .form-group.field--not-empty label {
|
||||
margin-top: -20px; }
|
||||
.half .contents .form-control, .half .bg .form-control {
|
||||
border: none;
|
||||
padding: 0;
|
||||
font-size: 20px;
|
||||
border-radius: 0; }
|
||||
.half .contents .form-control:active, .half .contents .form-control:focus, .half .bg .form-control:active, .half .bg .form-control:focus {
|
||||
outline: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none; }
|
||||
|
||||
.half .bg {
|
||||
background-size: cover;
|
||||
background-position: center; }
|
||||
|
||||
.half a {
|
||||
color: #888;
|
||||
text-decoration: underline; }
|
||||
|
||||
.half .btn {
|
||||
height: 54px;
|
||||
padding-left: 30px;
|
||||
padding-right: 30px; }
|
||||
|
||||
.half .forgot-pass {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
font-size: 14px; }
|
||||
|
||||
.social-login a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
margin-bottom: 10px; }
|
||||
.social-login a:hover {
|
||||
color: #fff; }
|
||||
.social-login a.facebook {
|
||||
background: #3b5998; }
|
||||
.social-login a.facebook:hover {
|
||||
background: #344e86; }
|
||||
.social-login a.twitter {
|
||||
background: #1da1f2; }
|
||||
.social-login a.twitter:hover {
|
||||
background: #0d95e8; }
|
||||
.social-login a.google {
|
||||
background: #ea4335; }
|
||||
.social-login a.google:hover {
|
||||
background: #e82e1e; }
|
||||
|
||||
.control {
|
||||
display: block;
|
||||
position: relative;
|
||||
padding-left: 30px;
|
||||
margin-bottom: 15px;
|
||||
cursor: pointer;
|
||||
font-size: 14px; }
|
||||
.control .caption {
|
||||
position: relative;
|
||||
top: .2rem;
|
||||
color: #888; }
|
||||
|
||||
.control input {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
opacity: 0; }
|
||||
|
||||
.control__indicator {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 0;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
background: #e6e6e6;
|
||||
border-radius: 4px; }
|
||||
|
||||
.control--radio .control__indicator {
|
||||
border-radius: 50%; }
|
||||
|
||||
.control:hover input ~ .control__indicator,
|
||||
.control input:focus ~ .control__indicator {
|
||||
background: #ccc; }
|
||||
|
||||
.control input:checked ~ .control__indicator {
|
||||
background: #007bff; }
|
||||
|
||||
.control:hover input:not([disabled]):checked ~ .control__indicator,
|
||||
.control input:checked:focus ~ .control__indicator {
|
||||
background: #1a88ff; }
|
||||
|
||||
.control input:disabled ~ .control__indicator {
|
||||
background: #e6e6e6;
|
||||
opacity: 0.9;
|
||||
pointer-events: none; }
|
||||
|
||||
.control__indicator:after {
|
||||
font-family: 'icomoon';
|
||||
content: '\e5ca';
|
||||
position: absolute;
|
||||
display: none;
|
||||
font-size: 16px;
|
||||
-webkit-transition: .3s all ease;
|
||||
-o-transition: .3s all ease;
|
||||
transition: .3s all ease; }
|
||||
|
||||
.control input:checked ~ .control__indicator:after {
|
||||
display: block;
|
||||
color: #fff; }
|
||||
|
||||
.control--checkbox .control__indicator:after {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -1px;
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%); }
|
||||
|
||||
.control--checkbox input:disabled ~ .control__indicator:after {
|
||||
border-color: #7b7b7b; }
|
||||
|
||||
.control--checkbox input:disabled:checked ~ .control__indicator {
|
||||
background-color: #7e0cf5;
|
||||
opacity: .2; }
|
||||
|
||||
/* Add by Titan 2023/05/19 */
|
||||
h3 {
|
||||
color: #0996C2;
|
||||
}
|
||||
.dx-link .dx-link-edit .dx-icon-edit .dx-link-icon {
|
||||
color: #e8d102;
|
||||
}
|
||||
.dx-link .dx-link-delete .dx-icon-trash .dx-link-icon {
|
||||
color: #FF2C2C;
|
||||
}
|
||||
.dx-item-content .dx-toolbar-item-content {
|
||||
margin: 0 5px;
|
||||
}
|
||||
.dx-widget.dx-button.dx-button-mode-text.dx-button-normal.dx-button-has-icon.dx-closebutton {
|
||||
left: 0px;
|
||||
}
|
||||
.dx-datagrid-addrow-button {
|
||||
background: #0996C2;
|
||||
color: #fff;
|
||||
}
|
||||
.dx-datagrid-addrow-button.dx-state-hover {
|
||||
background: #0ea4d3;
|
||||
color: #fff;
|
||||
}
|
||||
.dx-button-mode-contained .dx-icon {
|
||||
color: #fff;
|
||||
}
|
||||
.dx-datagrid-headers {
|
||||
background: #DAF0FA;
|
||||
}
|
||||
.dx-widget.dx-button.dx-button-mode-contained.dx-button-normal.dx-button-has-text {
|
||||
left: 0px;
|
||||
}
|
BIN
public/favicon.ico
Normal file
After Width: | Height: | Size: 64 KiB |
4919
public/fonts/icomoon/style.css
Normal file
BIN
public/images/bg-header.jpg
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
public/images/bg-login.jpg
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
public/images/icon/ico-1-master.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/images/icon/ico-2-config.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
public/images/icon/ico-3-template.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
public/images/icon/ico-4-drp.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/images/icon/ico-5-rks.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
public/images/icon/ico-6-hps.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
public/images/icon/ico-7-kontrak.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
public/images/logo.jpg
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
public/images/logo_pln.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
17
public/index.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body class="dx-viewport">
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
7
public/js/bootstrap.min.js
vendored
Normal file
2
public/js/jquery-3.3.1.min.js
vendored
Normal file
13
public/js/main.js
Normal file
@ -0,0 +1,13 @@
|
||||
$(function() {
|
||||
'use strict';
|
||||
|
||||
$('.form-control').on('input', function() {
|
||||
var $field = $(this).closest('.form-group');
|
||||
if (this.value) {
|
||||
$field.addClass('field--not-empty');
|
||||
} else {
|
||||
$field.removeClass('field--not-empty');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
5
public/js/popper.min.js
vendored
Normal file
69
public/login.html
Normal file
@ -0,0 +1,69 @@
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="fonts/icomoon/style.css">
|
||||
<link rel="stylesheet" href="css/owl.carousel.min.css">
|
||||
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css">
|
||||
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<title>Login Smartproc</title>
|
||||
<script nonce="42c04549-e79d-458b-9668-a594fd1782ea">(function(w,d){!function(bg,bh,bi,bj){bg[bi]=bg[bi]||{};bg[bi].executed=[];bg.zaraz={deferred:[],listeners:[]};bg.zaraz.q=[];bg.zaraz._f=function(bk){return function(){var bl=Array.prototype.slice.call(arguments);bg.zaraz.q.push({m:bk,a:bl})}};for(const bm of["track","set","debug"])bg.zaraz[bm]=bg.zaraz._f(bm);bg.zaraz.init=()=>{var bn=bh.getElementsByTagName(bj)[0],bo=bh.createElement(bj),bp=bh.getElementsByTagName("title")[0];bp&&(bg[bi].t=bh.getElementsByTagName("title")[0].text);bg[bi].x=Math.random();bg[bi].w=bg.screen.width;bg[bi].h=bg.screen.height;bg[bi].j=bg.innerHeight;bg[bi].e=bg.innerWidth;bg[bi].l=bg.location.href;bg[bi].r=bh.referrer;bg[bi].k=bg.screen.colorDepth;bg[bi].n=bh.characterSet;bg[bi].o=(new Date).getTimezoneOffset();if(bg.dataLayer)for(const bt of Object.entries(Object.entries(dataLayer).reduce(((bu,bv)=>({...bu[1],...bv[1]})))))zaraz.set(bt[0],bt[1],{scope:"page"});bg[bi].q=[];for(;bg.zaraz.q.length;){const bw=bg.zaraz.q.shift();bg[bi].q.push(bw)}bo.defer=!0;for(const bx of[localStorage,sessionStorage])Object.keys(bx||{}).filter((bz=>bz.startsWith("_zaraz_"))).forEach((by=>{try{bg[bi]["z_"+by.slice(7)]=JSON.parse(bx.getItem(by))}catch{bg[bi]["z_"+by.slice(7)]=bx.getItem(by)}}));bo.referrerPolicy="origin";bo.src="/cdn-cgi/zaraz/s.js?z="+btoa(encodeURIComponent(JSON.stringify(bg[bi])));bn.parentNode.insertBefore(bo,bn)};["complete","interactive"].includes(bh.readyState)?zaraz.init():bg.addEventListener("DOMContentLoaded",zaraz.init)}(w,d,"zarazData","script");})(window,document);</script></head>
|
||||
<body>
|
||||
<div class="d-lg-flex half">
|
||||
<div class="bg order-1 order-md-2" style="background-image: url('images/bg-login.jpg');">
|
||||
<div class="container">
|
||||
<div class="row align-items-center justify-content-center">
|
||||
<div class="col-md-10">
|
||||
<div class="mb-4">
|
||||
<h1 class="text-white text-bold">SMARTPROC</h1>
|
||||
<p class="mb-4 text-white">Manajemen kontrak Pengadaan yang termonitoring dan Efisien</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contents order-2 order-md-1" style="background: transparent;border: 1px solid #F3F3F3;box-shadow: 0px 4px 20px rgba(51, 51, 51, 0.1);border-radius: 0px 24px 24px 0px;">
|
||||
<div class="container">
|
||||
<div class="row align-items-center justify-content-center">
|
||||
<div class="col-md-7">
|
||||
<div class="mb-4">
|
||||
<h3>Log In</h3>
|
||||
<p class="mb-4"></p>
|
||||
</div>
|
||||
<form action="#" method="post">
|
||||
<div class="form-group first">
|
||||
<label for="username">Email</label>
|
||||
<input type="text" class="form-control" id="email">
|
||||
</div>
|
||||
<div class="form-group last mb-3">
|
||||
<label for="password">Password</label>
|
||||
<input type="password" class="form-control" id="password">
|
||||
</div>
|
||||
<div class="d-flex mb-5 align-items-center">
|
||||
<label class="control control--checkbox mb-0"><span class="caption">Ingat saya</span>
|
||||
<input type="checkbox" checked="checked" />
|
||||
<div class="control__indicator"></div>
|
||||
</label>
|
||||
<span class="ml-auto"><a href="#" class="forgot-pass">Lupa Password ?</a></span>
|
||||
</div>
|
||||
<input type="submit" value="Log In" class="btn btn-block btn-primary">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/jquery-3.3.1.min.js"></script>
|
||||
<script src="js/popper.min.js"></script>
|
||||
<script src="js/bootstrap.min.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v52afc6f149f6479b8c77fa569edb01181681764108816" integrity="sha512-jGCTpDpBAYDGNYR5ztKt4BQPGef1P0giN6ZGVUi835kFF88FOmmn8jBQWNgrNd8g/Yu421NdgWhwQoaOPFflDw==" data-cf-beacon='{"rayId":"7c8750ecaec94ab2","token":"cd0b4b3a733644fc843ef0b185f98241","version":"2023.4.0","si":100}' crossorigin="anonymous"></script>
|
||||
</body>
|
||||
</html>
|
101
src/App.vue
Normal file
@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<div id="root">
|
||||
<div :class="cssClasses">
|
||||
<component
|
||||
:is="$route.meta.layout"
|
||||
:title="title"
|
||||
:is-x-small="screen.getScreenSizeInfo.isXSmall"
|
||||
:is-large="screen.getScreenSizeInfo.isLarge"
|
||||
>
|
||||
<div class="content">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
<template #footer>
|
||||
<app-footer />
|
||||
</template>
|
||||
</component>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AppFooter from "./components/app-footer";
|
||||
import { sizes, subscribe, unsubscribe } from "./utils/media-query";
|
||||
import {
|
||||
getCurrentInstance,
|
||||
reactive,
|
||||
onMounted,
|
||||
onBeforeUnmount,
|
||||
computed
|
||||
} from "vue";
|
||||
|
||||
function getScreenSizeInfo() {
|
||||
const screenSizes = sizes();
|
||||
|
||||
return {
|
||||
isXSmall: screenSizes["screen-x-small"],
|
||||
isLarge: screenSizes["screen-large"],
|
||||
cssClasses: Object.keys(screenSizes).filter(cl => screenSizes[cl])
|
||||
};
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AppFooter
|
||||
},
|
||||
setup() {
|
||||
const vm = getCurrentInstance();
|
||||
|
||||
const title = vm.proxy.$appInfo.title;
|
||||
const screen = reactive({ getScreenSizeInfo: {} });
|
||||
screen.getScreenSizeInfo = getScreenSizeInfo();
|
||||
|
||||
function screenSizeChanged () {
|
||||
screen.getScreenSizeInfo = getScreenSizeInfo();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
subscribe(screenSizeChanged);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
unsubscribe(screenSizeChanged);
|
||||
});
|
||||
|
||||
const cssClasses = computed(() => {
|
||||
return ["app"].concat(screen.getScreenSizeInfo.cssClasses);
|
||||
});
|
||||
|
||||
return {
|
||||
title,
|
||||
screen,
|
||||
cssClasses
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
html,
|
||||
body {
|
||||
margin: 0px;
|
||||
min-height: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#root {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.app {
|
||||
@import "./themes/generated/variables.base.scss";
|
||||
background-color: darken($base-bg, 5);
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
3
src/app-info.js
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
title: "Smartproc"
|
||||
};
|
145
src/app-navigation.js
Normal file
@ -0,0 +1,145 @@
|
||||
export default [
|
||||
{
|
||||
text: "Home",
|
||||
path: "/home",
|
||||
icon: "home"
|
||||
},
|
||||
|
||||
{
|
||||
text: "Master Data",
|
||||
icon: "images/icon/ico-1-master.png",
|
||||
items: [
|
||||
{
|
||||
text: 'Jenis Pengadaan',
|
||||
path: '/master-data/jenis-pengadaan',
|
||||
},
|
||||
{
|
||||
text: 'Divisi/Unit Inisiator Pengadaan',
|
||||
path: '/master-data/unit-inisiator',
|
||||
},
|
||||
{
|
||||
text: 'Metode Pengadaan',
|
||||
path: '/master-data/metode-pengadaan',
|
||||
},
|
||||
{
|
||||
text: 'Metode Penyampaian Dokumen Penawaran',
|
||||
path: '/master-data/metode-penyampaian',
|
||||
},
|
||||
{
|
||||
text: 'Jenis Perjanjian/Kontrak',
|
||||
path: '/master-data/jenis-kontrak',
|
||||
},
|
||||
// {
|
||||
// text: 'User',
|
||||
// path: '/user-page',
|
||||
// icon: 'user'
|
||||
// }, , ,
|
||||
{
|
||||
text: 'Sumber Dana',
|
||||
path: '/master-data/sumber-dana',
|
||||
},
|
||||
{
|
||||
text: 'Strategi Pengadaan',
|
||||
path: '/master-data/strategi-pengadaan',
|
||||
},
|
||||
{
|
||||
text: 'Lokasi',
|
||||
path: '/master-data/lokasi-pengadaan',
|
||||
},
|
||||
{
|
||||
text: 'Supply Positioning Matrix',
|
||||
path: '/master-data/supply-positioning-matrix',
|
||||
},
|
||||
{
|
||||
text: 'Jenis Anggaran',
|
||||
path: '/master-data/jenis-anggaran',
|
||||
},
|
||||
{
|
||||
text: 'Instansi',
|
||||
path: '/master-data/instansi-page',
|
||||
},
|
||||
{
|
||||
text: 'Bidang',
|
||||
path: '/master-data/bidang-page',
|
||||
},
|
||||
{
|
||||
text: 'Jabatan',
|
||||
path: '/master-data/jabatan-page',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Master Konfigurasi",
|
||||
icon: "images/icon/ico-2-config.png",
|
||||
items: [
|
||||
{
|
||||
text: 'Manajemen Roles',
|
||||
path: '/master-config/roles-config',
|
||||
},
|
||||
{
|
||||
text: 'Manajemen User',
|
||||
path: '/master-config/users-config',
|
||||
},
|
||||
{
|
||||
text: 'Manajemen Permission',
|
||||
path: '/master-config/permissions-config',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Master Template",
|
||||
icon: "images/icon/ico-3-template.png",
|
||||
items: [
|
||||
{
|
||||
text: 'Daftar Isi RKS',
|
||||
path: '/rks-daftar',
|
||||
},
|
||||
{
|
||||
text: 'Template RKS',
|
||||
path: '/rks-template',
|
||||
},
|
||||
{
|
||||
text: 'Daftar Isi Kontrak',
|
||||
path: '/kontrak-daftar',
|
||||
},
|
||||
{
|
||||
text: 'Template Kontrak',
|
||||
path: '/kontrak-template',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "DRP",
|
||||
icon: "images/icon/ico-4-drp.png",
|
||||
items: [
|
||||
{
|
||||
text: 'Penyusunan DRP',
|
||||
path: '/drp/drp-penyusunan',
|
||||
},
|
||||
{
|
||||
text: 'Approval DRP',
|
||||
path: '/drp/drp-approval',
|
||||
},
|
||||
{
|
||||
text: 'Revisi DRP',
|
||||
path: '/drp/drp-revisi',
|
||||
},
|
||||
{
|
||||
text: 'Cetak DRP',
|
||||
path: '/drp/drp-cetak',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "RKS & HPE",
|
||||
icon: "images/icon/ico-5-rks.png",
|
||||
},
|
||||
{
|
||||
text: "HPS",
|
||||
icon: "images/icon/ico-6-hps.png",
|
||||
},
|
||||
{
|
||||
text: "Kontrak",
|
||||
icon: "images/icon/ico-7-kontrak.png",
|
||||
},
|
||||
];
|
BIN
src/assets/logo.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
101
src/auth.js
Normal file
@ -0,0 +1,101 @@
|
||||
const defaultUser = {
|
||||
email: 'titan@hadiyan.net',
|
||||
avatarUrl: 'https://js.devexpress.com/Demos/WidgetsGallery/JSDemos/images/employees/06.png'
|
||||
};
|
||||
|
||||
export default {
|
||||
_user: defaultUser,
|
||||
loggedIn() {
|
||||
return !!this._user;
|
||||
},
|
||||
|
||||
async logIn(email, password) {
|
||||
try {
|
||||
// Send request
|
||||
console.log(email, password);
|
||||
this._user = { ...defaultUser, email };
|
||||
|
||||
return {
|
||||
isOk: true,
|
||||
data: this._user
|
||||
};
|
||||
}
|
||||
catch {
|
||||
return {
|
||||
isOk: false,
|
||||
message: "Authentication failed"
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
async logOut() {
|
||||
this._user = null;
|
||||
},
|
||||
|
||||
async getUser() {
|
||||
try {
|
||||
// Send request
|
||||
|
||||
return {
|
||||
isOk: true,
|
||||
data: this._user
|
||||
};
|
||||
}
|
||||
catch {
|
||||
return {
|
||||
isOk: false
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
async resetPassword(email) {
|
||||
try {
|
||||
// Send request
|
||||
console.log(email);
|
||||
|
||||
return {
|
||||
isOk: true
|
||||
};
|
||||
}
|
||||
catch {
|
||||
return {
|
||||
isOk: false,
|
||||
message: "Failed to reset password"
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
async changePassword(email, recoveryCode) {
|
||||
try {
|
||||
// Send request
|
||||
console.log(email, recoveryCode);
|
||||
|
||||
return {
|
||||
isOk: true
|
||||
};
|
||||
}
|
||||
catch {
|
||||
return {
|
||||
isOk: false,
|
||||
message: "Failed to change password"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async createAccount(email, password) {
|
||||
try {
|
||||
// Send request
|
||||
console.log(email, password);
|
||||
|
||||
return {
|
||||
isOk: true
|
||||
};
|
||||
}
|
||||
catch {
|
||||
return {
|
||||
isOk: false,
|
||||
message: "Failed to create account"
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
58
src/components/HelloWorld.vue
Normal file
@ -0,0 +1,58 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<p>
|
||||
For a guide and recipes on how to configure / customize this project,<br>
|
||||
check out the
|
||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
||||
</p>
|
||||
<h3>Installed CLI Plugins</h3>
|
||||
<ul>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
||||
</ul>
|
||||
<h3>Essential Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
||||
</ul>
|
||||
<h3>Ecosystem</h3>
|
||||
<ul>
|
||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
props: {
|
||||
msg: String
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
20
src/components/app-footer.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div class="content-block">
|
||||
<footer class="footer">
|
||||
Copyright © 2013-{{new Date().getFullYear()}} {{this.$appInfo.title}}.
|
||||
<br />By <strong>PLN</strong> Gas & Geothermal
|
||||
</footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../themes/generated/variables.base.scss";
|
||||
|
||||
.footer {
|
||||
display: block;
|
||||
color: rgba($base-text-color, alpha($base-text-color) * 0.7);
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
padding-top: 20px;
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
</style>
|
161
src/components/header-toolbar.vue
Normal file
@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<header class="header-component">
|
||||
<dx-toolbar class="header-toolbar" style="background-image: url('images/bg-header.jpg');">
|
||||
<dx-item
|
||||
:visible="menuToggleEnabled"
|
||||
location="before"
|
||||
css-class="menu-button"
|
||||
>
|
||||
<template #default>
|
||||
<dx-button
|
||||
icon="menu"
|
||||
styling-mode="text"
|
||||
@click="toggleMenuFunc"
|
||||
/>
|
||||
</template>
|
||||
</dx-item>
|
||||
|
||||
<dx-item
|
||||
v-if="title"
|
||||
location="before"
|
||||
css-class="header-title dx-toolbar-label"
|
||||
>
|
||||
<img src="images/logo_pln.png" style="float: left;"/>
|
||||
</dx-item>
|
||||
|
||||
<dx-item
|
||||
location="after"
|
||||
locate-in-menu="auto"
|
||||
menu-item-template="menuUserItem"
|
||||
>
|
||||
<template #default>
|
||||
<div>
|
||||
<dx-button
|
||||
class="user-button authorization"
|
||||
:width="210"
|
||||
height="100%"
|
||||
styling-mode="text"
|
||||
>
|
||||
<user-panel :email="email" :menu-items="userMenuItems" menu-mode="context" />
|
||||
</dx-button>
|
||||
</div>
|
||||
</template>
|
||||
</dx-item>
|
||||
|
||||
<template #menuUserItem>
|
||||
<user-panel
|
||||
:email="email"
|
||||
:menu-items="userMenuItems"
|
||||
menu-mode="list"
|
||||
/>
|
||||
</template>
|
||||
</dx-toolbar>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxButton from "devextreme-vue/button";
|
||||
import DxToolbar, { DxItem } from "devextreme-vue/toolbar";
|
||||
import auth from "../auth";
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { ref } from 'vue';
|
||||
|
||||
import UserPanel from "./user-panel";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
menuToggleEnabled: Boolean,
|
||||
title: String,
|
||||
toggleMenuFunc: Function,
|
||||
logOutFunc: Function
|
||||
},
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
const email = ref("");
|
||||
auth.getUser().then((e) => email.value = e.data.email);
|
||||
|
||||
const userMenuItems = [{
|
||||
text: "Profile",
|
||||
icon: "user",
|
||||
onClick: onProfileClick
|
||||
},
|
||||
{
|
||||
text: "Logout",
|
||||
icon: "runner",
|
||||
onClick: onLogoutClick
|
||||
}];
|
||||
|
||||
function onLogoutClick() {
|
||||
auth.logOut();
|
||||
router.push({
|
||||
path: "/login-form",
|
||||
query: { redirect: route.path }
|
||||
});
|
||||
}
|
||||
|
||||
function onProfileClick() {
|
||||
router.push({
|
||||
path: "/profile",
|
||||
query: { redirect: route.path }
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
email,
|
||||
userMenuItems
|
||||
};
|
||||
},
|
||||
components: {
|
||||
DxButton,
|
||||
DxToolbar,
|
||||
DxItem,
|
||||
UserPanel
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../themes/generated/variables.base.scss";
|
||||
@import "../dx-styles.scss";
|
||||
|
||||
.header-component {
|
||||
flex: 0 0 auto;
|
||||
z-index: 1;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
|
||||
|
||||
.dx-toolbar .dx-toolbar-item.menu-button > .dx-toolbar-item-content .dx-icon {
|
||||
color: $base-accent;
|
||||
}
|
||||
}
|
||||
|
||||
.dx-toolbar.header-toolbar .dx-toolbar-items-container .dx-toolbar-after {
|
||||
padding: 0 40px;
|
||||
|
||||
.screen-x-small & {
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.dx-toolbar .dx-toolbar-item.dx-toolbar-button.menu-button {
|
||||
width: $side-panel-min-width;
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.header-title .dx-item-content {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.dx-theme-generic {
|
||||
.dx-toolbar {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.user-button > .dx-button-content {
|
||||
padding: 3px;
|
||||
}
|
||||
}
|
||||
</style>
|
224
src/components/side-nav-menu ori.vue
Normal file
@ -0,0 +1,224 @@
|
||||
<template>
|
||||
<div id="container">
|
||||
<dxMenu>
|
||||
<dxItem
|
||||
icon="home"
|
||||
>
|
||||
</dxItem>
|
||||
<dxItem
|
||||
text="About"
|
||||
>
|
||||
</dxItem>
|
||||
<dxItem
|
||||
text="Products"
|
||||
>
|
||||
</dxItem>
|
||||
<dxItem
|
||||
icon="cart"
|
||||
>
|
||||
</dxItem>
|
||||
</dxMenu>
|
||||
</div>
|
||||
<div
|
||||
class="dx-swatch-additional side-navigation-menu"
|
||||
@click="forwardClick"
|
||||
>
|
||||
<slot />
|
||||
<div class="menu-container">
|
||||
<dx-tree-view
|
||||
ref="treeViewRef"
|
||||
:items="items"
|
||||
key-expr="path"
|
||||
selection-mode="single"
|
||||
:focus-state-enabled="false"
|
||||
expand-event="click"
|
||||
@item-click="handleItemClick"
|
||||
width="100%"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxTreeView from "devextreme-vue/ui/tree-view";
|
||||
import { sizes } from '../utils/media-query';
|
||||
import navigation from '../app-navigation';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
compactMode: Boolean
|
||||
},
|
||||
setup(props, context) {
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const isLargeScreen = sizes()['screen-large'];
|
||||
const items = navigation.map((item) => {
|
||||
if(item.path && !(/^\//.test(item.path))){
|
||||
item.path = `/${item.path}`;
|
||||
}
|
||||
return {...item, expanded: isLargeScreen}
|
||||
});
|
||||
|
||||
const treeViewRef = ref(null);
|
||||
|
||||
function forwardClick (...args) {
|
||||
context.emit("click", args);
|
||||
}
|
||||
|
||||
function handleItemClick(e) {
|
||||
if (!e.itemData.path || props.compactMode) {
|
||||
return;
|
||||
}
|
||||
router.push(e.itemData.path);
|
||||
|
||||
const pointerEvent = e.event;
|
||||
pointerEvent.stopPropagation();
|
||||
}
|
||||
|
||||
function updateSelection () {
|
||||
if (!treeViewRef.value || !treeViewRef.value.instance) {
|
||||
return;
|
||||
}
|
||||
|
||||
treeViewRef.value.instance.selectItem(route.path);
|
||||
treeViewRef.value.instance.expandItem(route.path);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
updateSelection();
|
||||
if (props.compactMode) {
|
||||
treeViewRef.value.instance.collapseAll();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
updateSelection();
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.compactMode,
|
||||
() => {
|
||||
if (props.compactMode) {
|
||||
treeViewRef.value.instance.collapseAll();
|
||||
} else {
|
||||
updateSelection();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
treeViewRef,
|
||||
items,
|
||||
forwardClick,
|
||||
handleItemClick,
|
||||
updateSelection
|
||||
};
|
||||
},
|
||||
components: {
|
||||
DxTreeView
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../dx-styles.scss";
|
||||
@import "../themes/generated/variables.additional.scss";
|
||||
|
||||
.side-navigation-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100%;
|
||||
height: 100%;
|
||||
width: 250px !important;
|
||||
|
||||
.menu-container {
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
||||
.dx-treeview {
|
||||
// ## Long text positioning
|
||||
white-space: nowrap;
|
||||
// ##
|
||||
|
||||
// ## Icon width customization
|
||||
.dx-treeview-item {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
|
||||
.dx-icon {
|
||||
width: $side-panel-min-width !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
}
|
||||
// ##
|
||||
|
||||
// ## Arrow customization
|
||||
.dx-treeview-node {
|
||||
padding: 0 0 !important;
|
||||
}
|
||||
|
||||
.dx-treeview-toggle-item-visibility {
|
||||
right: 10px;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.dx-rtl .dx-treeview-toggle-item-visibility {
|
||||
left: 10px;
|
||||
right: auto;
|
||||
}
|
||||
// ##
|
||||
|
||||
// ## Item levels customization
|
||||
.dx-treeview-node {
|
||||
&[aria-level="1"] {
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid $base-border-color;
|
||||
}
|
||||
|
||||
&[aria-level="2"] .dx-treeview-item-content {
|
||||
font-weight: normal;
|
||||
padding: 0 $side-panel-min-width;
|
||||
}
|
||||
}
|
||||
// ##
|
||||
}
|
||||
|
||||
// ## Selected & Focuced items customization
|
||||
.dx-treeview {
|
||||
.dx-treeview-node-container {
|
||||
.dx-treeview-node {
|
||||
&.dx-state-selected:not(.dx-state-focused) > .dx-treeview-item {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&.dx-state-selected > .dx-treeview-item * {
|
||||
color: $base-accent;
|
||||
}
|
||||
|
||||
&:not(.dx-state-focused) > .dx-treeview-item.dx-state-hover {
|
||||
background-color: lighten($base-bg, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dx-theme-generic .dx-treeview {
|
||||
.dx-treeview-node-container
|
||||
.dx-treeview-node.dx-state-selected.dx-state-focused
|
||||
> .dx-treeview-item
|
||||
* {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
// ##
|
||||
}
|
||||
}
|
||||
</style>
|
204
src/components/side-nav-menu.vue
Normal file
@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<div
|
||||
class="dx-swatch-additional side-navigation-menu"
|
||||
@click="forwardClick"
|
||||
>
|
||||
<slot />
|
||||
<div class="menu-container">
|
||||
<dx-tree-view
|
||||
ref="treeViewRef"
|
||||
:items="items"
|
||||
key-expr="path"
|
||||
selection-mode="single"
|
||||
:focus-state-enabled="false"
|
||||
expand-event="click"
|
||||
@item-click="handleItemClick"
|
||||
width="100%"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxTreeView from "devextreme-vue/ui/tree-view";
|
||||
import { sizes } from '../utils/media-query';
|
||||
import navigation from '../app-navigation';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
compactMode: Boolean
|
||||
},
|
||||
setup(props, context) {
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const isLargeScreen = sizes()['screen-large'];
|
||||
const items = navigation.map((item) => {
|
||||
if(item.path && !(/^\//.test(item.path))){
|
||||
item.path = `/${item.path}`;
|
||||
}
|
||||
return {...item, expanded: isLargeScreen}
|
||||
});
|
||||
|
||||
const treeViewRef = ref(null);
|
||||
|
||||
function forwardClick (...args) {
|
||||
context.emit("click", args);
|
||||
}
|
||||
|
||||
function handleItemClick(e) {
|
||||
if (!e.itemData.path || props.compactMode) {
|
||||
return;
|
||||
}
|
||||
router.push(e.itemData.path);
|
||||
|
||||
const pointerEvent = e.event;
|
||||
pointerEvent.stopPropagation();
|
||||
}
|
||||
|
||||
function updateSelection () {
|
||||
if (!treeViewRef.value || !treeViewRef.value.instance) {
|
||||
return;
|
||||
}
|
||||
|
||||
treeViewRef.value.instance.selectItem(route.path);
|
||||
treeViewRef.value.instance.expandItem(route.path);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
updateSelection();
|
||||
if (props.compactMode) {
|
||||
treeViewRef.value.instance.collapseAll();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
updateSelection();
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => props.compactMode,
|
||||
() => {
|
||||
if (props.compactMode) {
|
||||
treeViewRef.value.instance.collapseAll();
|
||||
} else {
|
||||
updateSelection();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
treeViewRef,
|
||||
items,
|
||||
forwardClick,
|
||||
handleItemClick,
|
||||
updateSelection
|
||||
};
|
||||
},
|
||||
components: {
|
||||
DxTreeView
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../dx-styles.scss";
|
||||
@import "../themes/generated/variables.additional.scss";
|
||||
|
||||
.side-navigation-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100%;
|
||||
height: 100%;
|
||||
width: 250px !important;
|
||||
|
||||
.menu-container {
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
||||
.dx-treeview {
|
||||
// ## Long text positioning
|
||||
white-space: nowrap;
|
||||
// ##
|
||||
|
||||
// ## Icon width customization
|
||||
.dx-treeview-item {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
|
||||
.dx-icon {
|
||||
width: $side-panel-min-width !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
}
|
||||
// ##
|
||||
|
||||
// ## Arrow customization
|
||||
.dx-treeview-node {
|
||||
padding: 0 0 !important;
|
||||
}
|
||||
|
||||
.dx-treeview-toggle-item-visibility {
|
||||
right: 10px;
|
||||
left: auto;
|
||||
}
|
||||
|
||||
.dx-rtl .dx-treeview-toggle-item-visibility {
|
||||
left: 10px;
|
||||
right: auto;
|
||||
}
|
||||
// ##
|
||||
|
||||
// ## Item levels customization
|
||||
.dx-treeview-node {
|
||||
&[aria-level="1"] {
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid $base-border-color;
|
||||
}
|
||||
|
||||
&[aria-level="2"] .dx-treeview-item-content {
|
||||
font-weight: normal;
|
||||
padding: 0 $side-panel-min-width;
|
||||
}
|
||||
}
|
||||
// ##
|
||||
}
|
||||
|
||||
// ## Selected & Focuced items customization
|
||||
.dx-treeview {
|
||||
.dx-treeview-node-container {
|
||||
.dx-treeview-node {
|
||||
&.dx-state-selected:not(.dx-state-focused) > .dx-treeview-item {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&.dx-state-selected > .dx-treeview-item * {
|
||||
color: $base-accent;
|
||||
}
|
||||
|
||||
&:not(.dx-state-focused) > .dx-treeview-item.dx-state-hover {
|
||||
background-color: lighten($base-bg, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dx-theme-generic .dx-treeview {
|
||||
.dx-treeview-node-container
|
||||
.dx-treeview-node.dx-state-selected.dx-state-focused
|
||||
> .dx-treeview-item
|
||||
* {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
// ##
|
||||
}
|
||||
}
|
||||
</style>
|
114
src/components/user-panel.vue
Normal file
@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<div class="user-panel">
|
||||
<div class="user-info">
|
||||
<div class="image-container">
|
||||
<div class="user-image" />
|
||||
</div>
|
||||
<div class="user-name">{{email}}</div>
|
||||
</div>
|
||||
|
||||
<dx-context-menu
|
||||
v-if="menuMode === 'context'"
|
||||
target=".user-button"
|
||||
:items="menuItems"
|
||||
:width="210"
|
||||
show-event="dxclick"
|
||||
css-class="user-menu"
|
||||
>
|
||||
<dx-position my="top center" at="bottom center" />
|
||||
</dx-context-menu>
|
||||
|
||||
<dx-list
|
||||
v-if="menuMode === 'list'"
|
||||
class="dx-toolbar-menu-action"
|
||||
:items="menuItems"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxContextMenu, { DxPosition } from "devextreme-vue/context-menu";
|
||||
import DxList from "devextreme-vue/list";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
menuMode: String,
|
||||
menuItems: Array,
|
||||
email: String
|
||||
},
|
||||
components: {
|
||||
DxContextMenu,
|
||||
DxPosition,
|
||||
DxList
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../themes/generated/variables.base.scss";
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.dx-toolbar-menu-section & {
|
||||
padding: 10px 6px;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.image-container {
|
||||
overflow: hidden;
|
||||
border-radius: 50%;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
margin: 0 4px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
|
||||
|
||||
.user-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: url("https://js.devexpress.com/Demos/WidgetsGallery/JSDemos/images/employees/06.png")
|
||||
no-repeat #fff;
|
||||
background-size: cover;
|
||||
}
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 14px;
|
||||
color: $base-text-color;
|
||||
margin: 0 9px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-panel {
|
||||
.dx-list-item .dx-icon {
|
||||
vertical-align: middle;
|
||||
color: $base-text-color;
|
||||
margin-right: 16px;
|
||||
}
|
||||
.dx-rtl .dx-list-item .dx-icon {
|
||||
margin-right: 0;
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.dx-context-menu.user-menu.dx-menu-base {
|
||||
&.dx-rtl {
|
||||
.dx-submenu .dx-menu-items-container .dx-icon {
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
.dx-submenu .dx-menu-items-container .dx-icon {
|
||||
margin-right: 16px;
|
||||
}
|
||||
.dx-menu-item .dx-menu-item-content {
|
||||
padding: 3px 15px 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.dx-theme-generic .user-menu .dx-menu-item-content .dx-menu-item-text {
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
</style>
|
69
src/dx-styles.scss
Normal file
@ -0,0 +1,69 @@
|
||||
.content {
|
||||
line-height: 1.5;
|
||||
flex-grow: 1;
|
||||
|
||||
h2 {
|
||||
font-size: 30px;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.layout-body {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.side-nav-outer-toolbar .dx-drawer {
|
||||
height: calc(100% - 56px)
|
||||
}
|
||||
|
||||
.content-block {
|
||||
margin-left: 40px;
|
||||
margin-right: 40px;
|
||||
margin-top: 20px;
|
||||
|
||||
.screen-x-small & {
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.responsive-paddings {
|
||||
padding: 20px;
|
||||
|
||||
.screen-large & {
|
||||
padding: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.dx-card.wide-card {
|
||||
border-radius: 0;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
border-right: 0;
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.with-footer > .dx-scrollable-wrapper >
|
||||
.dx-scrollable-container > .dx-scrollable-content {
|
||||
height: 100%;
|
||||
|
||||
& > .dx-scrollview-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#app {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
$side-panel-min-width: 60px;
|
178
src/layouts/side-nav-inner-toolbar.vue
Normal file
@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div class="side-nav-inner-toolbar">
|
||||
<dx-drawer
|
||||
class="drawer"
|
||||
position="before"
|
||||
template="menuTemplate"
|
||||
v-model:opened="menuOpened"
|
||||
:opened-state-mode="drawerOptions.menuMode"
|
||||
:reveal-mode="drawerOptions.menuRevealMode"
|
||||
:min-size="drawerOptions.minMenuSize"
|
||||
:max-size="drawerOptions.maxMenuSize"
|
||||
:shading="drawerOptions.shaderEnabled"
|
||||
:close-on-outside-click="drawerOptions.closeOnOutsideClick"
|
||||
>
|
||||
<div class="container">
|
||||
<header-toolbar
|
||||
:menu-toggle-enabled="headerMenuTogglerEnabled"
|
||||
:toggle-menu-func="toggleMenu"
|
||||
/>
|
||||
<dx-scroll-view ref="scrollViewRef" class="layout-body with-footer">
|
||||
<slot />
|
||||
<slot name="footer" />
|
||||
</dx-scroll-view>
|
||||
</div>
|
||||
<template #menuTemplate>
|
||||
<side-nav-menu
|
||||
:compact-mode="!menuOpened"
|
||||
@click="handleSideBarClick"
|
||||
>
|
||||
<dx-toolbar id="navigation-header">
|
||||
<dx-item v-if="!isXSmall" location="before" css-class="menu-button">
|
||||
<template #default>
|
||||
<dx-button
|
||||
icon="menu"
|
||||
styling-mode="text"
|
||||
@click="toggleMenu"
|
||||
/>
|
||||
</template>
|
||||
</dx-item>
|
||||
<dx-item location="before" css-class="header-title dx-toolbar-label">
|
||||
<template #default>
|
||||
<div>{{ title }}</div>
|
||||
</template>
|
||||
</dx-item>
|
||||
</dx-toolbar>
|
||||
</side-nav-menu>
|
||||
</template>
|
||||
</dx-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxButton from "devextreme-vue/button";
|
||||
import DxDrawer from "devextreme-vue/drawer";
|
||||
import DxScrollView from "devextreme-vue/scroll-view";
|
||||
import DxToolbar, { DxItem } from "devextreme-vue/toolbar";
|
||||
|
||||
import HeaderToolbar from "../components/header-toolbar";
|
||||
import SideNavMenu from "../components/side-nav-menu";
|
||||
import menuItems from "../app-navigation";
|
||||
import { ref, watch, computed } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
title: String,
|
||||
isXSmall: Boolean,
|
||||
isLarge: Boolean
|
||||
},
|
||||
setup(props) {
|
||||
const route = useRoute();
|
||||
|
||||
const scrollViewRef = ref(null);
|
||||
const menuOpened = ref(props.isLarge);
|
||||
const menuTemporaryOpened = ref(false);
|
||||
|
||||
function toggleMenu (e) {
|
||||
const pointerEvent = e.event;
|
||||
pointerEvent.stopPropagation();
|
||||
if (menuOpened.value) {
|
||||
menuTemporaryOpened.value = false;
|
||||
}
|
||||
|
||||
menuOpened.value = !menuOpened.value;
|
||||
}
|
||||
|
||||
function handleSideBarClick () {
|
||||
if (menuOpened.value === false) {
|
||||
menuTemporaryOpened.value = true;
|
||||
}
|
||||
|
||||
menuOpened.value = true;
|
||||
}
|
||||
|
||||
const drawerOptions = computed(() => {
|
||||
const shaderEnabled = !props.isLarge;
|
||||
|
||||
return {
|
||||
menuMode: props.isLarge ? "shrink" : "overlap",
|
||||
menuRevealMode: props.isXSmall ? "slide" : "expand",
|
||||
minMenuSize: props.isXSmall ? 0 : 60,
|
||||
//minMenuSize: 0,
|
||||
maxMenuSize: props.isXSmall ? 250 : undefined,
|
||||
closeOnOutsideClick: shaderEnabled,
|
||||
shaderEnabled
|
||||
};
|
||||
});
|
||||
|
||||
const headerMenuTogglerEnabled = computed(() => {
|
||||
return props.isXSmall;
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.isLarge,
|
||||
() => {
|
||||
if (!menuTemporaryOpened.value) {
|
||||
menuOpened.value = props.isLarge;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
if (menuTemporaryOpened.value || !props.isLarge) {
|
||||
menuOpened.value = false;
|
||||
menuTemporaryOpened.value = false;
|
||||
}
|
||||
scrollViewRef.value.instance.scrollTo(0);
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
scrollViewRef,
|
||||
menuOpened,
|
||||
drawerOptions,
|
||||
menuItems,
|
||||
headerMenuTogglerEnabled,
|
||||
toggleMenu,
|
||||
handleSideBarClick
|
||||
};
|
||||
},
|
||||
components: {
|
||||
DxButton,
|
||||
DxDrawer,
|
||||
DxScrollView,
|
||||
DxToolbar,
|
||||
DxItem,
|
||||
HeaderToolbar,
|
||||
SideNavMenu
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.side-nav-inner-toolbar {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#navigation-header {
|
||||
@import "../themes/generated/variables.additional.scss";
|
||||
background-color: $base-accent;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
|
||||
|
||||
.menu-button .dx-icon {
|
||||
color: $base-text-color;
|
||||
}
|
||||
|
||||
.screen-x-small & {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.dx-theme-generic & {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
135
src/layouts/side-nav-outer-toolbar.vue
Normal file
@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<div class="side-nav-outer-toolbar">
|
||||
<header-toolbar
|
||||
class="layout-header"
|
||||
:menu-toggle-enabled="true"
|
||||
:toggle-menu-func="toggleMenu"
|
||||
:title="title"
|
||||
/>
|
||||
<dx-drawer
|
||||
class="layout-body"
|
||||
position="before"
|
||||
template="menuTemplate"
|
||||
v-model:opened="menuOpened"
|
||||
:opened-state-mode="drawerOptions.menuMode"
|
||||
:reveal-mode="drawerOptions.menuRevealMode"
|
||||
:min-size="drawerOptions.minMenuSize"
|
||||
:max-size="drawerOptions.maxMenuSize"
|
||||
:shading="drawerOptions.shaderEnabled"
|
||||
:close-on-outside-click="drawerOptions.closeOnOutsideClick"
|
||||
>
|
||||
<dx-scroll-view ref="scrollViewRef" class="with-footer">
|
||||
<slot />
|
||||
<slot name="footer" />
|
||||
</dx-scroll-view>
|
||||
<template #menuTemplate>
|
||||
<side-nav-menu
|
||||
:compact-mode="!menuOpened"
|
||||
@click="handleSideBarClick"
|
||||
/>
|
||||
</template>
|
||||
</dx-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDrawer from "devextreme-vue/drawer";
|
||||
import DxScrollView from "devextreme-vue/scroll-view";
|
||||
|
||||
import menuItems from "../app-navigation";
|
||||
import HeaderToolbar from "../components/header-toolbar";
|
||||
import SideNavMenu from "../components/side-nav-menu";
|
||||
import { computed, ref, watch} from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
title: String,
|
||||
isXSmall: Boolean,
|
||||
isLarge: Boolean
|
||||
},
|
||||
setup(props) {
|
||||
const route = useRoute();
|
||||
|
||||
const scrollViewRef = ref(null);
|
||||
const menuOpened = ref(props.isLarge);
|
||||
const menuTemporaryOpened = ref(false);
|
||||
|
||||
function toggleMenu(e) {
|
||||
const pointerEvent = e.event;
|
||||
pointerEvent.stopPropagation();
|
||||
if (menuOpened.value) {
|
||||
menuTemporaryOpened.value = false;
|
||||
}
|
||||
menuOpened.value = !menuOpened.value;
|
||||
}
|
||||
|
||||
function handleSideBarClick() {
|
||||
if (menuOpened.value === false) {
|
||||
menuTemporaryOpened.value = true;
|
||||
}
|
||||
menuOpened.value = true;
|
||||
}
|
||||
|
||||
const drawerOptions = computed(() => {
|
||||
const shaderEnabled = !props.isLarge;
|
||||
|
||||
return {
|
||||
menuMode: props.isLarge ? "shrink" : "overlap",
|
||||
menuRevealMode: props.isXSmall ? "slide" : "expand",
|
||||
minMenuSize: props.isXSmall ? 0 : 60,
|
||||
maxMenuSize: props.isXSmall ? 250 : undefined,
|
||||
closeOnOutsideClick: shaderEnabled,
|
||||
shaderEnabled
|
||||
};
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.isLarge,
|
||||
() => {
|
||||
if (!menuTemporaryOpened.value) {
|
||||
menuOpened.value = props.isLarge;
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
if (menuTemporaryOpened.value || !props.isLarge) {
|
||||
menuOpened.value = false;
|
||||
menuTemporaryOpened.value = false;
|
||||
}
|
||||
scrollViewRef.value.instance.scrollTo(0);
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
menuOpened,
|
||||
menuItems,
|
||||
toggleMenu,
|
||||
handleSideBarClick,
|
||||
drawerOptions,
|
||||
scrollViewRef
|
||||
};
|
||||
},
|
||||
components: {
|
||||
DxDrawer,
|
||||
DxScrollView,
|
||||
HeaderToolbar,
|
||||
SideNavMenu
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.side-nav-outer-toolbar {
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.layout-header {
|
||||
z-index: 1501;
|
||||
}
|
||||
</style>
|
83
src/layouts/single-card.vue
Normal file
@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<dx-scroll-view height="100%" width="100%" class="with-footer single-card">
|
||||
<div class="dx-card content">
|
||||
<div class="header">
|
||||
<div class="title">{{title}}</div>
|
||||
<div class="description">{{description}}</div>
|
||||
</div>
|
||||
<slot />
|
||||
</div>
|
||||
</dx-scroll-view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxScrollView from "devextreme-vue/scroll-view";
|
||||
|
||||
import { useRoute } from 'vue-router';
|
||||
import { watch, ref } from 'vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxScrollView
|
||||
},
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
|
||||
const title = ref(route.meta.title);
|
||||
const description = ref("");
|
||||
|
||||
watch(() => route.path,
|
||||
() => {
|
||||
title.value = route.meta.title;
|
||||
description.value = route.meta.description;
|
||||
}
|
||||
)
|
||||
return {
|
||||
title,
|
||||
description
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../themes/generated/variables.base.scss";
|
||||
|
||||
.single-card {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.dx-card {
|
||||
width: 330px;
|
||||
margin: auto auto;
|
||||
padding: 40px;
|
||||
flex-grow: 0;
|
||||
|
||||
.screen-x-small & {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 30px;
|
||||
|
||||
.title {
|
||||
color: $base-text-color;
|
||||
line-height: 28px;
|
||||
font-weight: 500;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: rgba($base-text-color, alpha($base-text-color) * 0.7);
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
16
src/main.js
Normal file
@ -0,0 +1,16 @@
|
||||
import 'devextreme/dist/css/dx.light.css';
|
||||
import './themes/generated/theme.base.css';
|
||||
import './themes/generated/theme.additional.css';
|
||||
import { createApp } from "vue";
|
||||
import router from "./router";
|
||||
import themes from "devextreme/ui/themes";
|
||||
|
||||
import App from "./App";
|
||||
import appInfo from "./app-info";
|
||||
|
||||
themes.initialized(() => {
|
||||
const app = createApp(App);
|
||||
app.use(router);
|
||||
app.config.globalProperties.$appInfo = appInfo;
|
||||
app.mount('#app');
|
||||
});
|
321
src/router.js
Normal file
@ -0,0 +1,321 @@
|
||||
/* Master Data */
|
||||
import JenisPengadaan from './views/master-data/jenis-pengadaan';
|
||||
import UnitInisiator from './views/master-data/unit-inisiator';
|
||||
import MetodePengadaan from './views/master-data/metode-pengadaan';
|
||||
import MetodePenyampaian from './views/master-data/metode-penyampaian';
|
||||
import JenisKontrak from './views/master-data/jenis-kontrak';
|
||||
import SumberDana from './views/master-data/sumber-dana';
|
||||
import StrategiPengadaan from './views/master-data/strategi-pengadaan';
|
||||
import LokasiPengadaan from './views/master-data/lokasi-pengadaan';
|
||||
import SupplyPositioningMatrix from './views/master-data/supply-positioning-matrix';
|
||||
import JenisAnggaran from './views/master-data/jenis-anggaran';
|
||||
import InstansiPage from './views/master-data/instansi-page';
|
||||
import BidangPage from './views/master-data/bidang-page';
|
||||
import JabatanPage from './views/master-data/jabatan-page';
|
||||
|
||||
/* Master Konfigurasi */
|
||||
import RolesConfig from './views/master-config/roles-config';
|
||||
import UsersConfig from './views/master-config/users-config';
|
||||
import PermissionsConfig from './views/master-config/permissions-config';
|
||||
import User from './views/user-page';
|
||||
|
||||
/* Master Template */
|
||||
import RksDaftar from './views/rks-daftar';
|
||||
|
||||
/* DRP */
|
||||
import DrpPenyusunan from './views/drp/drp-penyusunan';
|
||||
|
||||
/* General */
|
||||
import auth from "./auth";
|
||||
import { createRouter, createWebHashHistory } from "vue-router";
|
||||
|
||||
import Home from "./views/home-page";
|
||||
import Profile from "./views/profile-page";
|
||||
import Tasks from "./views/tasks-page";
|
||||
import defaultLayout from "./layouts/side-nav-outer-toolbar";
|
||||
import simpleLayout from "./layouts/single-card";
|
||||
|
||||
function loadView(view) {
|
||||
return () => import (/* webpackChunkName: "login" */ `./views/${view}.vue`)
|
||||
}
|
||||
|
||||
const router = new createRouter({
|
||||
routes: [
|
||||
{
|
||||
path: "/home",
|
||||
name: "home",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: Home
|
||||
},
|
||||
{
|
||||
path: "/profile",
|
||||
name: "profile",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: Profile
|
||||
},
|
||||
{
|
||||
path: "/tasks",
|
||||
name: "tasks",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: Tasks
|
||||
},
|
||||
{
|
||||
path: "/login-form",
|
||||
name: "login-form",
|
||||
meta: {
|
||||
requiresAuth: false,
|
||||
layout: simpleLayout,
|
||||
title: "Sign In"
|
||||
},
|
||||
component: loadView("login-form")
|
||||
},
|
||||
{
|
||||
path: "/reset-password",
|
||||
name: "reset-password",
|
||||
meta: {
|
||||
requiresAuth: false,
|
||||
layout: simpleLayout,
|
||||
title: "Reset Password",
|
||||
description: "Please enter the email address that you used to register, and we will send you a link to reset your password via Email."
|
||||
},
|
||||
component: loadView("reset-password-form")
|
||||
},
|
||||
{
|
||||
path: "/create-account",
|
||||
name: "create-account",
|
||||
meta: {
|
||||
requiresAuth: false,
|
||||
layout: simpleLayout,
|
||||
title: "Sign Up"
|
||||
},
|
||||
component: loadView("create-account-form"),
|
||||
},
|
||||
{
|
||||
path: "/change-password/:recoveryCode",
|
||||
name: "change-password",
|
||||
meta: {
|
||||
requiresAuth: false,
|
||||
layout: simpleLayout,
|
||||
title: "Change Password"
|
||||
},
|
||||
component: loadView("change-password-form")
|
||||
},
|
||||
{
|
||||
path: "/",
|
||||
redirect: "/home"
|
||||
},
|
||||
{
|
||||
path: "/recovery",
|
||||
redirect: "/home"
|
||||
},
|
||||
{
|
||||
path: "/:pathMatch(.*)*",
|
||||
redirect: "/home"
|
||||
},
|
||||
{
|
||||
path: "/user-page",
|
||||
name: "user-page",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: User
|
||||
},
|
||||
{
|
||||
path: "/master-data/jenis-pengadaan",
|
||||
name: "jenis-pengadaan",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: JenisPengadaan
|
||||
},
|
||||
{
|
||||
path: "/master-data/unit-inisiator",
|
||||
name: "unit-inisiator",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: UnitInisiator
|
||||
},
|
||||
{
|
||||
path: "/master-data/metode-pengadaan",
|
||||
name: "metode-pengadaan",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: MetodePengadaan
|
||||
},
|
||||
{
|
||||
path: "/master-data/metode-penyampaian",
|
||||
name: "metode-penyampaian",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: MetodePenyampaian
|
||||
},
|
||||
{
|
||||
path: "/master-data/jenis-kontrak",
|
||||
name: "jenis-kontrak",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: JenisKontrak
|
||||
},
|
||||
{
|
||||
path: "/master-data/sumber-dana",
|
||||
name: "sumber-dana",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: SumberDana
|
||||
},
|
||||
{
|
||||
path: "/master-data/strategi-pengadaan",
|
||||
name: "strategi-pengadaan",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: StrategiPengadaan
|
||||
},
|
||||
{
|
||||
path: "/master-data/lokasi-pengadaan",
|
||||
name: "lokasi-pengadaan",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: LokasiPengadaan
|
||||
},
|
||||
{
|
||||
path: "/master-data/supply-positioning-matrix",
|
||||
name: "supply-positioning-matrix",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: SupplyPositioningMatrix
|
||||
},
|
||||
{
|
||||
path: "/master-data/jenis-anggaran",
|
||||
name: "jenis-anggaran",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: JenisAnggaran
|
||||
},
|
||||
{
|
||||
path: "/master-data/instansi-page",
|
||||
name: "instansi-page",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: InstansiPage
|
||||
},
|
||||
{
|
||||
path: "/master-data/bidang-page",
|
||||
name: "bidang-page",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: BidangPage
|
||||
},
|
||||
{
|
||||
path: "/master-data/jabatan-page",
|
||||
name: "jabatan-page",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: JabatanPage
|
||||
},
|
||||
{
|
||||
path: "/master-config/roles-config",
|
||||
name: "roles-config",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: RolesConfig
|
||||
},
|
||||
{
|
||||
path: "/master-config/users-config",
|
||||
name: "users-config",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: UsersConfig
|
||||
},
|
||||
{
|
||||
path: "/master-config/permissions-config",
|
||||
name: "permissions-config",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: PermissionsConfig
|
||||
},
|
||||
{
|
||||
path: "/rks-daftar",
|
||||
name: "rks-daftar",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: RksDaftar
|
||||
},
|
||||
{
|
||||
path: "/drp/drp-penyusunan",
|
||||
name: "drp-penyusunan",
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
layout: defaultLayout
|
||||
},
|
||||
component: DrpPenyusunan
|
||||
},
|
||||
|
||||
|
||||
],
|
||||
history: createWebHashHistory()
|
||||
});
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
|
||||
if (to.name === "login-form" && auth.loggedIn()) {
|
||||
next({ name: "home" });
|
||||
}
|
||||
|
||||
if (to.matched.some(record => record.meta.requiresAuth)) {
|
||||
if (!auth.loggedIn()) {
|
||||
next({
|
||||
name: "login-form",
|
||||
query: { redirect: to.fullPath }
|
||||
});
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
22976
src/themes/generated/dx.generic.soft-blue.css
Normal file
BIN
src/themes/generated/icons/dxicons.ttf
Normal file
BIN
src/themes/generated/icons/dxicons.woff
Normal file
BIN
src/themes/generated/icons/dxicons.woff2
Normal file
5386
src/themes/generated/theme.additional.css
Normal file
22975
src/themes/generated/theme.base.css
Normal file
5
src/themes/generated/variables.additional.scss
Normal file
@ -0,0 +1,5 @@
|
||||
$base-accent: #7ab8eb;
|
||||
$base-text-color: #333333;
|
||||
$base-bg: #ffffff;
|
||||
$base-border-color: #e8eaeb;
|
||||
$base-border-radius: 2px;
|
209
src/themes/generated/variables.base.scss
Normal file
@ -0,0 +1,209 @@
|
||||
$base-font-family: "SF Pro Display", sans-serif;
|
||||
$base-accent: #7ab8eb;
|
||||
$base-label-color: #8c8c8c;
|
||||
$base-link-color: #7ab8eb;
|
||||
$base-icon-color: #99a1a8;
|
||||
$base-text-color: #333333;
|
||||
$base-bg: #ffffff;
|
||||
$base-border-color: #e8eaeb;
|
||||
$base-border-radius: 2px;
|
||||
$base-success: #5cb85c;
|
||||
$base-warning: #f0ad4e;
|
||||
$base-danger: #d9534f;
|
||||
$base-hover-color: #333333;
|
||||
$base-hover-bg: #0000000a;
|
||||
$base-focus-color: #ffffff;
|
||||
$base-focus-bg: #7ab8eb;
|
||||
$base-invalid-color: #d9534f;
|
||||
$base-invalid-faded-border-color: #d9534f66;
|
||||
$base-border-radius-small: 1px;
|
||||
$base-border-radius-large: 4px;
|
||||
$button-normal-color: #333333;
|
||||
$button-normal-bg: #ffffff;
|
||||
$button-normal-border-color: #cacfd1;
|
||||
$button-default-color: #ffffff;
|
||||
$button-default-bg: #7ab8eb;
|
||||
$button-default-border-color: #64ace8;
|
||||
$button-danger-color: #ffffff;
|
||||
$button-danger-bg: #d9534f;
|
||||
$button-danger-border-color: #d43f3a;
|
||||
$button-success-color: #ffffff;
|
||||
$button-success-bg: #5cb85c;
|
||||
$button-success-border-color: #4cae4c;
|
||||
$list-border-color: #e8eaeb;
|
||||
$list-group-color: #99a1a8;
|
||||
$list-group-header-bg: #fafafa;
|
||||
$list-normal-color: #333333;
|
||||
$list-item-hover-bg: #0000000a;
|
||||
$list-item-selected-bg: #0000001a;
|
||||
$list-item-focused-selected-bg: #7ab8ebb3;
|
||||
$list-focused-bg: #7ab8eb;
|
||||
$list-item-active-bg: #7ab8eb;
|
||||
$fieldset-field-label-color: #8c8c8c;
|
||||
$checkbox-border-color: #e8eaeb;
|
||||
$checkbox-focused-borderd-color: #7ab8eb;
|
||||
$checkbox-bg: #ffffff;
|
||||
$checkbox-hover-border-color: #459ce3;
|
||||
$checkbox-active-icon-bg: #60606033;
|
||||
$button-group-normal-selected-color: #333333;
|
||||
$button-group-normal-selected-bg: #0000002b;
|
||||
$button-group-default-selected-color: #7ab8eb;
|
||||
$button-group-default-selected-bg: #7ab8eb4d;
|
||||
$button-group-danger-selected-color: #d9534f;
|
||||
$button-group-danger-selected-bg: #d9534f4d;
|
||||
$button-group-success-selected-color: #5cb85c;
|
||||
$button-group-success-selected-bg: #5cb85c4d;
|
||||
$scrollable-scroll-bg: #3895e1cc;
|
||||
$scrollable-scrollbar-active-bg: #bfbfbf33;
|
||||
$switch-border-color: #e8eaeb;
|
||||
$switch-on-color: #333333;
|
||||
$switch-container-active-bg: #60606033;
|
||||
$switch-off-color: #999999;
|
||||
$tabs-tab-color: #333333;
|
||||
$tabs-tab-selected-color: #333333;
|
||||
$tabs-tab-bg: #f7f7f7;
|
||||
$tabs-tab-selected-bg: #ffffff;
|
||||
$tabs-border-color: #e8eaeb;
|
||||
$tabs-focused-border-color: #7ab8eb;
|
||||
$tabs-tab-hover-bg: #ffffff;
|
||||
$badge-color: #ffffff;
|
||||
$badge-bg: #63a1d4;
|
||||
$overlay-content-bg: #ffffff;
|
||||
$overlay-shader-bg: #ffffffcc;
|
||||
$overlay-focus-border-color: #e8eaeb;
|
||||
$textbox-search-icon-color: #99a1a8;
|
||||
$texteditor-color: #333333;
|
||||
$texteditor-placeholder-color: #999999;
|
||||
$texteditor-bg: #ffffff;
|
||||
$texteditor-filled-bg: #3333330d;
|
||||
$texteditor-border-color: #e8eaeb;
|
||||
$texteditor-focused-border-color: #7ab8eb;
|
||||
$texteditor-hover-border-color: #7ab8eb66;
|
||||
$dropdowneditor-button-hover-bg: #e6e6e6;
|
||||
$dropdowneditor-button-active-bg: #b3b3b3;
|
||||
$dropdowneditor-icon-color: #99a1a8;
|
||||
$dropdowneditor-icon-active-color: #99a1a8;
|
||||
$numberbox-spin-active-bg: #b3b3b3;
|
||||
$numberbox-spin-hover-border-color: transparent;
|
||||
$numberbox-spin-icon-color: #99a1a8;
|
||||
$calendar-color: #333333;
|
||||
$calendar-header-color: #99a1a8;
|
||||
$calendar-cell-other-color: #b0b0b0;
|
||||
$calendar-bg: #ffffff;
|
||||
$calendar-hover-bg: #edf0f2;
|
||||
$calendar-cell-selected-bg: #7ab8eb;
|
||||
$calendar-cell-active-bg: #60606033;
|
||||
$calendar-border-color: #e8eaeb;
|
||||
$calendar-navigator-border-color: #e8eaeb;
|
||||
$calendar-navigator-hover-border-color: #e8eaeb;
|
||||
$calendar-shevron-icon-color: #7ab8eb;
|
||||
$loadindicator-bg: #7ab8eb;
|
||||
$treeview-focused-bg: #7ab8eb;
|
||||
$treeview-hover-bg: #0000000a;
|
||||
$treeview-border-color: #e8eaeb;
|
||||
$treeview-item-selected-color: #333333;
|
||||
$treeview-spin-icon-color: #99a1a8;
|
||||
$menu-popup-bg: #ffffff;
|
||||
$menu-item-hover-bg: #0000000a;
|
||||
$menu-color: #333333;
|
||||
$menu-item-hovered-color: #333333;
|
||||
$menu-item-expanded-color: #333333;
|
||||
$menu-item-selected-bg: #e6e6e6;
|
||||
$menu-popup-border-color: #e8eaeb;
|
||||
$selectbox-list-bg: #ffffff;
|
||||
$toolbar-bg: #ffffff;
|
||||
$popup-title-bg: transparent;
|
||||
$tileview-color: #333333;
|
||||
$toast-color: #ffffff;
|
||||
$toast-info-bg: #7ab8eb;
|
||||
$toast-warning-bg: #f0ad4e;
|
||||
$toast-error-bg: #d9534f;
|
||||
$toast-success-bg: #5cb85c;
|
||||
$progressbar-bg: #dddddd;
|
||||
$progressbar-range-bg: #7ab8eb;
|
||||
$tooltip-color: #333333;
|
||||
$tooltip-bg: #ffffff;
|
||||
$tooltip-border-color: #e8eaeb;
|
||||
$slider-bar-bg: #e8eaeb;
|
||||
$slider-range-bg: #7ab8eb;
|
||||
$gallery-indicator-bg: #ffffff;
|
||||
$gallery-indicator-item-selected-bg: #7ab8eb;
|
||||
$gallery-indicator-focused-bg: #3895e1;
|
||||
$gallery-navbutton-hover-color: #7ab8eb80;
|
||||
$gallery-nav-arrow-color: #ffffff;
|
||||
$gallery-navbutton-active-color: #7ab8ebb3;
|
||||
$loadpanel-content-bg: #ffffff;
|
||||
$tagbox-tag-color: #333333;
|
||||
$tagbox-tag-bg: #dddddd;
|
||||
$tagbox-tag-button-remove-bg: #aaaaaa;
|
||||
$radiogroup-checked-bg: #7ab8eb;
|
||||
$radiobutton-active-bg: #60606033;
|
||||
$accordion-color: #333333;
|
||||
$accordion-title-color: #333333;
|
||||
$accordion-item-title-opened-bg: transparent;
|
||||
$accordion-item-border-color: #e8eaeb;
|
||||
$accordion-item-focused-border-color: #7ab8eb;
|
||||
$accordion-title-active-color: #333333;
|
||||
$accordion-item-hover-bg: #0000000a;
|
||||
$accordion-icon-active-color: #333333;
|
||||
$colorbox-overlay-bg: #ffffff;
|
||||
$datagrid-base-color: #333333;
|
||||
$datagrid-base-background-color: #ffffff;
|
||||
$datagrid-border-color: #e8eaeb;
|
||||
$datagrid-columnchooser-item-color: #0996c2;
|
||||
$datagrid-columnchooser-font-weight: bold;
|
||||
$datagrid-drag-header-border-color: #7ab8eb80;
|
||||
$datagrid-selection-bg: #d1e0ed;
|
||||
$datagrid-row-selected-border-color: #e1ecf5;
|
||||
$datagrid-row-selected-color: #333333;
|
||||
$datagrid-row-focused-color: #ffffff;
|
||||
$datagrid-row-focused-bg: #95c6ef;
|
||||
$datagrid-hover-bg: #edf0f2;
|
||||
$datagrid-menu-icon-color: #99a1a8;
|
||||
$datagrid-cell-modified-border-color: #5cb85c80;
|
||||
$datagrid-row-invalid-faded-border-color: #d9534f66;
|
||||
$datagrid-nodata-color: #99a1a8;
|
||||
$datagrid-group-row-color: #99a1a8;
|
||||
$datagrid-group-row-bg: #fafafa;
|
||||
$datagrid-search-color: #ffffff;
|
||||
$datagrid-spin-icon-color: #99a1a8;
|
||||
$datagrid-search-bg: #7ab8eb;
|
||||
$datagrid-row-error-color: #ffffff;
|
||||
$datagrid-row-error-bg: #e89895;
|
||||
$datagrid-link-color: #7ab8eb;
|
||||
$datagrid-focused-border-color: #95c6ef;
|
||||
$datagrid-editor-bg: #ffffff;
|
||||
$datagrid-columnchooser-bg: #ffffff;
|
||||
$datagrid-row-alternation-bg: #fafafa;
|
||||
$datagrid-summary-color: #99a1a8;
|
||||
$pager-page-selected-color: #333333;
|
||||
$pager-page-selected-bg: #e8eaeb;
|
||||
$pivotgrid-area-color: #99a1a8;
|
||||
$pivotgrid-totalcolor: #f5f5f5b3;
|
||||
$pivotgrid-grandtotalcolor: #f5f5f5;
|
||||
$pivotgrid-field-area-text-color: #565e65;
|
||||
$pivotgrid-spin-icon-color: #99a1a8;
|
||||
$fileuploader-filename-color: #333333;
|
||||
$fileuploader-falename-status-color: #999999;
|
||||
$fileuploader-border-color: #e8eaeb;
|
||||
$scheduler-base-border-color: #e8eaeb99;
|
||||
$scheduler-accent-border-color: #cdd1d3;
|
||||
$scheduler-appointment-text-color: #ffffff;
|
||||
$scheduler-appointment-base-color: #7ab8eb;
|
||||
$scheduler-appointment-start-color: #0000004d;
|
||||
$scheduler-first-month-border-color: #b1b8bc;
|
||||
$scheduler-workspace-focused-cell-color: #e9f3fc;
|
||||
$scheduler-current-time-cell-color: #7ab8eb;
|
||||
$scheduler-time-indicator-color: #bddcf5;
|
||||
$form-field-item-color: #8c8c8c;
|
||||
$form-group-border-color: #d5d9da;
|
||||
$filterbuilder-text-color: #333333;
|
||||
$filterbuilder-text-focus-color: #ffffff;
|
||||
$filterbuilder-plus-icon-color: #5cb85c4d;
|
||||
$filterbuilder-remove-icon-color: #d9534f4d;
|
||||
$filterbuilder-group-operation-color: #d9534f4d;
|
||||
$filterbuilder-item-field-color: #7ab8eb4d;
|
||||
$filterbuilder-item-operator-color: #5cb85c4d;
|
||||
$filterbuilder-item-value-color: #e8eaeb80;
|
||||
$filterbuilder-menu-icon-color: #99a1a8;
|
||||
$drawer-shader-background-color: #00000080;
|
11
src/themes/metadata.additional.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"items": [],
|
||||
"baseTheme": "generic.softblue",
|
||||
"assetsBasePath": "../../../node_modules/devextreme/dist/css/",
|
||||
"outputColorScheme": "additional",
|
||||
"makeSwatch": true,
|
||||
"base": true,
|
||||
"widgets": [
|
||||
"treeview"
|
||||
]
|
||||
}
|
7
src/themes/metadata.base copy.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"items": [],
|
||||
"baseTheme": "material.orange.light",
|
||||
"assetsBasePath": "../../../node_modules/devextreme/dist/css/",
|
||||
"outputColorScheme": "base",
|
||||
"base": true
|
||||
}
|
22
src/themes/metadata.base.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"key": "$datagrid-columnchooser-item-color",
|
||||
"value": "rgba(9, 150, 194, 1)"
|
||||
},
|
||||
{
|
||||
"key": "$datagrid-columnchooser-font-weight",
|
||||
"value": "bold"
|
||||
},
|
||||
{
|
||||
"key": "$base-font-family",
|
||||
"value": "\"SF Pro Display\", sans-serif"
|
||||
}
|
||||
],
|
||||
"baseTheme": "generic.softblue",
|
||||
"outputColorScheme": "soft-blue",
|
||||
"makeSwatch": false,
|
||||
"version": "22.2.6",
|
||||
"widgets": [],
|
||||
"removeExternalResources": false
|
||||
}
|
33
src/utils/media-query.js
Normal file
@ -0,0 +1,33 @@
|
||||
const Breakpoints = {
|
||||
XSmall: "(max-width: 599.99px)",
|
||||
Small: "(min-width: 600px) and (max-width: 959.99px)",
|
||||
Medium: "(min-width: 960px) and (max-width: 1279.99px)",
|
||||
Large: "(min-width: 1280px)"
|
||||
};
|
||||
|
||||
let handlers = [];
|
||||
const xSmallMedia = window.matchMedia(Breakpoints.XSmall);
|
||||
const smallMedia = window.matchMedia(Breakpoints.Small);
|
||||
const mediumMedia = window.matchMedia(Breakpoints.Medium);
|
||||
const largeMedia = window.matchMedia(Breakpoints.Large);
|
||||
|
||||
[xSmallMedia, smallMedia, mediumMedia, largeMedia].forEach(media => {
|
||||
media.addListener(() => {
|
||||
handlers.forEach(handler => handler());
|
||||
});
|
||||
});
|
||||
|
||||
export const sizes = () => {
|
||||
return {
|
||||
"screen-x-small": xSmallMedia.matches,
|
||||
"screen-small": smallMedia.matches,
|
||||
"screen-medium": mediumMedia.matches,
|
||||
"screen-large": largeMedia.matches
|
||||
};
|
||||
};
|
||||
|
||||
export const subscribe = handler => handlers.push(handler);
|
||||
|
||||
export const unsubscribe = handler => {
|
||||
handlers = handlers.filter(item => item !== handler);
|
||||
};
|
115
src/views/change-password-form.vue
Normal file
@ -0,0 +1,115 @@
|
||||
<template>
|
||||
<form @submit.prevent="onSubmit">
|
||||
<dx-form :form-data="formData" :disabled="loading">
|
||||
<dx-item
|
||||
data-field="password"
|
||||
editor-type="dxTextBox"
|
||||
:editor-options="{ stylingMode: 'filled', placeholder: 'Password', mode: 'password' }"
|
||||
>
|
||||
<dx-required-rule message="Password is required" />
|
||||
<dx-label :visible="false" />
|
||||
</dx-item>
|
||||
<dx-item
|
||||
data-field="confirmedPassword"
|
||||
editor-type="dxTextBox"
|
||||
:editor-options="{ stylingMode: 'filled', placeholder: 'Confirm Password', mode: 'password' }"
|
||||
>
|
||||
<dx-required-rule message="Password is required" />
|
||||
<dx-custom-rule
|
||||
message="Passwords do not match"
|
||||
:validation-callback="confirmPassword"
|
||||
/>
|
||||
<dx-label :visible="false" />
|
||||
</dx-item>
|
||||
<dx-button-item>
|
||||
<dx-button-options
|
||||
width="100%"
|
||||
type="default"
|
||||
template="changePassword"
|
||||
:use-submit-behavior="true"
|
||||
>
|
||||
</dx-button-options>
|
||||
</dx-button-item>
|
||||
|
||||
<template #changePassword>
|
||||
<div>
|
||||
<span class="dx-button-text">
|
||||
<dx-loadIndicator v-if="loading" width="24px" height="24px" :visible="true" />
|
||||
<span v-if="!loading">Continue</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</dx-form>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxForm, {
|
||||
DxItem,
|
||||
DxLabel,
|
||||
DxButtonItem,
|
||||
DxButtonOptions,
|
||||
DxCustomRule,
|
||||
DxRequiredRule
|
||||
} from 'devextreme-vue/form';
|
||||
import DxLoadIndicator from 'devextreme-vue/load-indicator';
|
||||
import notify from 'devextreme/ui/notify';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { ref, reactive } from "vue";
|
||||
|
||||
import auth from "../auth";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxForm,
|
||||
DxItem,
|
||||
DxLabel,
|
||||
DxButtonItem,
|
||||
DxButtonOptions,
|
||||
DxRequiredRule,
|
||||
DxCustomRule,
|
||||
DxLoadIndicator
|
||||
},
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
const recoveryCode = ref("");
|
||||
const loading = ref(false);
|
||||
const formData = reactive({
|
||||
password:""
|
||||
});
|
||||
|
||||
recoveryCode.value = route.params.recoveryCode;
|
||||
|
||||
async function onSubmit() {
|
||||
const { password } = formData;
|
||||
loading.value = true;
|
||||
|
||||
const result = await auth.changePassword(password, recoveryCode.value);
|
||||
loading.value = false;
|
||||
|
||||
if (result.isOk) {
|
||||
router.push("/login-form");
|
||||
} else {
|
||||
notify(result.message, 'error', 2000);
|
||||
}
|
||||
}
|
||||
|
||||
function confirmPassword (e) {
|
||||
return e.value === formData.password;
|
||||
}
|
||||
|
||||
return {
|
||||
loading,
|
||||
formData,
|
||||
onSubmit,
|
||||
confirmPassword
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
155
src/views/create-account-form.vue
Normal file
@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<form class="create-account-form" @submit.prevent="onSubmit">
|
||||
<dx-form :form-data="formData" :disabled="loading">
|
||||
<dx-item
|
||||
data-field="email"
|
||||
editor-type="dxTextBox"
|
||||
:editor-options="{ stylingMode: 'filled', placeholder: 'Email', mode: 'email' }"
|
||||
>
|
||||
<dx-required-rule message="Email is required" />
|
||||
<dx-email-rule message="Email is invalid" />
|
||||
<dx-label :visible="false" />
|
||||
</dx-item>
|
||||
<dx-item
|
||||
data-field="password"
|
||||
editor-type="dxTextBox"
|
||||
:editor-options="{ stylingMode: 'filled', placeholder: 'Password', mode: 'password' }"
|
||||
>
|
||||
<dx-required-rule message="Password is required" />
|
||||
<dx-label :visible="false" />
|
||||
</dx-item>
|
||||
<dx-item
|
||||
data-field="confirmedPassword"
|
||||
editor-type="dxTextBox"
|
||||
:editor-options="{ stylingMode: 'filled', placeholder: 'Confirm Password', mode: 'password' }"
|
||||
>
|
||||
<dx-required-rule message="Password is required" />
|
||||
<dx-custom-rule
|
||||
message="Passwords do not match"
|
||||
:validation-callback="confirmPassword"
|
||||
/>
|
||||
<dx-label :visible="false" />
|
||||
</dx-item>
|
||||
<dx-item>
|
||||
<template #default>
|
||||
<div class='policy-info'>
|
||||
By creating an account, you agree to the <router-link to="#">Terms of Service</router-link> and <router-link to="#">Privacy Policy</router-link>
|
||||
</div>
|
||||
</template>
|
||||
</dx-item>
|
||||
<dx-button-item>
|
||||
<dx-button-options
|
||||
width="100%"
|
||||
type="default"
|
||||
template="createAccount"
|
||||
:use-submit-behavior="true"
|
||||
>
|
||||
</dx-button-options>
|
||||
</dx-button-item>
|
||||
<dx-item>
|
||||
<template #default>
|
||||
<div class="login-link">
|
||||
Have an account? <router-link to="/login-form">Sign In</router-link>
|
||||
</div>
|
||||
</template>
|
||||
</dx-item>
|
||||
<template #createAccount>
|
||||
<div>
|
||||
<span class="dx-button-text">
|
||||
<dx-loadIndicator v-if="loading" width="24px" height="24px" :visible="true" />
|
||||
<span v-if="!loading">Create a new account</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</dx-form>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxForm, {
|
||||
DxItem,
|
||||
DxLabel,
|
||||
DxButtonItem,
|
||||
DxButtonOptions,
|
||||
DxCustomRule,
|
||||
DxRequiredRule,
|
||||
DxEmailRule
|
||||
} from 'devextreme-vue/form';
|
||||
import DxLoadIndicator from 'devextreme-vue/load-indicator';
|
||||
import notify from 'devextreme/ui/notify';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { ref, reactive } from 'vue';
|
||||
|
||||
import auth from "../auth";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxForm,
|
||||
DxItem,
|
||||
DxLabel,
|
||||
DxButtonItem,
|
||||
DxButtonOptions,
|
||||
DxRequiredRule,
|
||||
DxCustomRule,
|
||||
DxEmailRule,
|
||||
DxLoadIndicator
|
||||
},
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
|
||||
const loading = ref(false);
|
||||
const formData = reactive({
|
||||
email:"",
|
||||
password:""
|
||||
});
|
||||
|
||||
const onSubmit = async () => {
|
||||
const { email, password } = formData;
|
||||
loading.value = true;
|
||||
|
||||
const result = await auth.createAccount(email, password);
|
||||
loading.value = false;
|
||||
|
||||
if (result.isOk) {
|
||||
router.push("/login-form");
|
||||
} else {
|
||||
notify(result.message, 'error', 2000);
|
||||
}
|
||||
};
|
||||
|
||||
function confirmPassword(e) {
|
||||
return e.value === formData.password;
|
||||
}
|
||||
|
||||
return {
|
||||
formData,
|
||||
loading,
|
||||
onSubmit,
|
||||
confirmPassword
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../themes/generated/variables.base.scss";
|
||||
|
||||
.create-account-form {
|
||||
.policy-info {
|
||||
margin: 10px 0;
|
||||
color: rgba($base-text-color, alpha($base-text-color) * 0.7);
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
|
||||
a {
|
||||
color: rgba($base-text-color, alpha($base-text-color) * 0.7);
|
||||
}
|
||||
}
|
||||
|
||||
.login-link {
|
||||
color: $base-accent;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
226
src/views/drp/drp-penyusunan.vue
Normal file
@ -0,0 +1,226 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Penyusunan DRP</h3>
|
||||
<p class="content-block">Penyusunan DRP</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="tahun" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Penyusunan DRP">
|
||||
</DxPopup>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn cell-template="row-cell-template" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="tahun" caption="Tahun DRP"></DxColumn>
|
||||
<DxColumn data-field="isApprove" caption="Status Approve"></DxColumn>
|
||||
<DxColumn data-field="approveDate" caption="Tanggal Approve"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
<DxButton
|
||||
text="Detail"
|
||||
icon="increaseindent"
|
||||
hint="Detail"
|
||||
:on-click="linkDetail"
|
||||
/>
|
||||
</DxColumn>
|
||||
<DxColumn type="adaptive" :width="50">
|
||||
<DxButton hint="detail" icon="copy"/>
|
||||
</DxColumn>
|
||||
<template #row-cell-template="{ data }">
|
||||
<DxText>{{ data.rowIndex +1 }}</DxText>
|
||||
</template>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Penyusunan DRP..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxButton
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/jenisanggaran';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL+'?size=100')
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
return {
|
||||
data: response.data,
|
||||
totalCount: response.pagination.totalRecords
|
||||
};
|
||||
})
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxButton
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Penyusunan DRP');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
cloneIconClick(e) {
|
||||
e.event.preventDefault();
|
||||
},
|
||||
linkDetail(e) {
|
||||
console.log(e.id);
|
||||
window.location.href= '/#/drp/drp-penyusunan';
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
173
src/views/home-page.vue
Normal file
@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2 class="content-block">Home</h2>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div class="logos-container">
|
||||
<svg
|
||||
class="devextreme-logo"
|
||||
viewBox="0 0 200 34"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M21.269 16.6304C21.269 21.9331 20.1851 25.9907 18.0171 28.8032C15.8638 31.6011 12.7583 33 8.70068 33H0.834473V0.875977H9.42578C13.1611 0.875977 16.0688 2.26025 18.1489 5.02881C20.229 7.78271 21.269 11.6499 21.269 16.6304ZM15.1387 16.8062C15.1387 9.62842 13.1611 6.03955 9.20605 6.03955H6.81104V27.7705H8.74463C10.9272 27.7705 12.5386 26.8623 13.5786 25.0459C14.6187 23.2148 15.1387 20.4683 15.1387 16.8062ZM33.7504 33.4395C30.6889 33.4395 28.2719 32.3555 26.4994 30.1875C24.7416 28.0049 23.8627 24.9214 23.8627 20.937C23.8627 16.894 24.661 13.7373 26.2577 11.4668C27.8544 9.19629 30.081 8.06104 32.9374 8.06104C35.6034 8.06104 37.7055 9.03516 39.2436 10.9834C40.7816 12.917 41.5507 15.6343 41.5507 19.1353V22.2554H29.7953C29.8393 24.438 30.286 26.064 31.1356 27.1333C31.9853 28.188 33.1571 28.7153 34.6513 28.7153C36.5556 28.7153 38.5038 28.1221 40.496 26.9355V31.7476C38.621 32.8755 36.3725 33.4395 33.7504 33.4395ZM32.8935 12.5654C32.0585 12.5654 31.37 13.0122 30.828 13.9058C30.286 14.7847 29.9711 16.1543 29.8832 18.0146H35.8158C35.7865 16.2275 35.5155 14.8726 35.0028 13.9497C34.4901 13.0269 33.787 12.5654 32.8935 12.5654ZM48.429 33L42.035 8.52246H48.0994L51.2195 22.6948C51.3514 23.354 51.5052 24.3208 51.681 25.5952C51.8714 26.855 51.9886 27.7632 52.0325 28.3198H52.1204C52.1351 27.8804 52.1937 27.2505 52.2962 26.4302C52.4134 25.6099 52.5306 24.8555 52.6478 24.167C52.7649 23.4785 53.8929 18.2637 56.0315 8.52246H62.096L55.68 33H48.429ZM78.5324 33H64.0524V0.875977H78.5324V6.03955H70.029V13.686H77.9172V18.8716H70.029V27.7705H78.5324V33ZM86.1798 20.4976L80.0714 8.52246H86.1358L89.3878 15.9932L92.398 8.52246H98.4186L92.2662 20.4976L98.6822 33H92.5738L89.1021 25.1777L85.8722 33H79.7857L86.1798 20.4976ZM109.12 28.4956C109.94 28.4956 110.827 28.2905 111.779 27.8804V32.4507C110.827 33.1099 109.398 33.4395 107.494 33.4395C105.37 33.4395 103.795 32.8096 102.77 31.5498C101.745 30.2754 101.232 28.3711 101.232 25.8369V13.1587H98.8589V10.5439L101.913 8.43457L103.407 3.24902H107.143V8.52246H111.581V13.1587H107.143V26.0347C107.143 27.6753 107.802 28.4956 109.12 28.4956ZM124.744 8.06104C125.461 8.06104 126.164 8.1709 126.853 8.39062L126.172 14.0596C125.762 13.9131 125.227 13.8398 124.568 13.8398C123.147 13.8398 122.056 14.4038 121.294 15.5317C120.532 16.645 120.151 18.271 120.151 20.4097V33H114.307V8.52246H119.119L119.778 12.3457H119.975C120.62 10.8076 121.323 9.70898 122.085 9.0498C122.847 8.39062 123.733 8.06104 124.744 8.06104ZM137.598 33.4395C134.537 33.4395 132.12 32.3555 130.347 30.1875C128.59 28.0049 127.711 24.9214 127.711 20.937C127.711 16.894 128.509 13.7373 130.106 11.4668C131.702 9.19629 133.929 8.06104 136.785 8.06104C139.451 8.06104 141.554 9.03516 143.092 10.9834C144.63 12.917 145.399 15.6343 145.399 19.1353V22.2554H133.643C133.687 24.438 134.134 26.064 134.984 27.1333C135.833 28.188 137.005 28.7153 138.499 28.7153C140.404 28.7153 142.352 28.1221 144.344 26.9355V31.7476C142.469 32.8755 140.221 33.4395 137.598 33.4395ZM136.742 12.5654C135.907 12.5654 135.218 13.0122 134.676 13.9058C134.134 14.7847 133.819 16.1543 133.731 18.0146H139.664C139.635 16.2275 139.364 14.8726 138.851 13.9497C138.338 13.0269 137.635 12.5654 136.742 12.5654ZM172.668 33V18.4102C172.668 14.8213 171.781 13.0269 170.009 13.0269C168.72 13.0269 167.797 13.6714 167.24 14.9604C166.684 16.2349 166.405 18.2856 166.405 21.1128V33H160.517V18.4102C160.517 14.8213 159.616 13.0269 157.814 13.0269C156.554 13.0269 155.639 13.6641 155.068 14.9385C154.496 16.2129 154.211 18.3149 154.211 21.2446V33H148.366V8.52246H153.002L153.705 11.6646H154.079C154.665 10.4194 155.463 9.51123 156.474 8.93994C157.499 8.354 158.591 8.06104 159.748 8.06104C162.736 8.06104 164.728 9.47461 165.724 12.3018H165.944C167.189 9.47461 169.189 8.06104 171.943 8.06104C174.111 8.06104 175.751 8.82275 176.864 10.3462C177.992 11.8696 178.556 14.0962 178.556 17.0259V33H172.668ZM191.433 33.4395C188.372 33.4395 185.955 32.3555 184.182 30.1875C182.424 28.0049 181.546 24.9214 181.546 20.937C181.546 16.894 182.344 13.7373 183.941 11.4668C185.537 9.19629 187.764 8.06104 190.62 8.06104C193.286 8.06104 195.388 9.03516 196.926 10.9834C198.464 12.917 199.233 15.6343 199.233 19.1353V22.2554H187.478C187.522 24.438 187.969 26.064 188.818 27.1333C189.668 28.188 190.84 28.7153 192.334 28.7153C194.238 28.7153 196.187 28.1221 198.179 26.9355V31.7476C196.304 32.8755 194.055 33.4395 191.433 33.4395ZM190.576 12.5654C189.741 12.5654 189.053 13.0122 188.511 13.9058C187.969 14.7847 187.654 16.1543 187.566 18.0146H193.499C193.469 16.2275 193.198 14.8726 192.686 13.9497C192.173 13.0269 191.47 12.5654 190.576 12.5654Z"
|
||||
fill="#F05B41"
|
||||
></path>
|
||||
</svg>
|
||||
<svg
|
||||
class="plus"
|
||||
viewBox="0 0 22 22"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M21.6309 13.3433H13.1714V21.8027H8.73291V13.3433H0.229492V8.88281H8.73291V0.379395H13.1714V8.88281H21.6309V13.3433Z"
|
||||
fill="#BCBCBC"
|
||||
></path>
|
||||
</svg>
|
||||
|
||||
<svg
|
||||
class="vue-logo"
|
||||
viewBox="0 0 180 62"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<polygon
|
||||
style="fill:#41B782;"
|
||||
points="44.3,0 36,14.3 27.7,0 0,0 36,62 72,0 "
|
||||
/>
|
||||
<polygon
|
||||
style="fill:#35495E;"
|
||||
points="44.3,0 36,14.3 27.7,0 14.4,0 36,37.2 57.6,0 "
|
||||
/>
|
||||
<g>
|
||||
<path
|
||||
style="fill:#35495E;"
|
||||
d="M77.2,15c0-0.4,0.2-0.8,0.7-1c0.5-0.3,0.9-0.4,1.4-0.4c0.7,0,1.1,0.3,1.3,0.8l7.2,24.4L95,14.4
|
||||
c0.2-0.5,0.6-0.8,1.2-0.8c0.5,0,1,0.1,1.4,0.4c0.4,0.3,0.7,0.6,0.7,1c0,0,0,0.1,0,0.1c0,0.1,0,0.1,0,0.2l-8.3,27.3
|
||||
c-0.3,0.8-1,1.2-2.1,1.2s-1.8-0.4-2.1-1.2l-8.4-27.3C77.2,15.2,77.2,15.1,77.2,15z"
|
||||
/>
|
||||
<path
|
||||
style="fill:#35495E;"
|
||||
d="M99.8,36V25.4c0-0.3,0.2-0.6,0.5-0.9c0.3-0.2,0.7-0.4,1.2-0.4c0.4,0,0.8,0.1,1.2,0.4
|
||||
s0.5,0.5,0.5,0.8V36c0,1.2,0.5,2.3,1.4,3.3c0.9,1,2,1.5,3.3,1.5c1.3,0,2.4-0.5,3.3-1.5c0.9-1,1.4-2.1,1.4-3.3V25.3
|
||||
c0-0.3,0.2-0.6,0.5-0.8c0.3-0.2,0.7-0.4,1.2-0.4c0.5,0,0.9,0.1,1.2,0.3c0.3,0.2,0.5,0.5,0.5,0.8V36c0,2.1-0.8,3.9-2.4,5.5
|
||||
c-1.6,1.6-3.5,2.4-5.7,2.4c-2.2,0-4.1-0.8-5.7-2.4C100.6,40,99.8,38.1,99.8,36z"
|
||||
/>
|
||||
<path
|
||||
style="fill:#35495E;"
|
||||
d="M119.9,35.9v-4.3c0-2.1,0.8-3.9,2.4-5.5c1.6-1.5,3.5-2.3,5.8-2.3c2.1,0,4,0.7,5.5,2.1
|
||||
s2.3,3.2,2.3,5.4c0,0.8-0.1,1.4-0.3,1.9s-0.5,0.8-0.9,1c-0.4,0.2-0.8,0.3-1.1,0.4s-0.8,0.1-1.4,0.1h-9v1.2c0,1.5,0.5,2.7,1.6,3.6
|
||||
c1.1,0.9,2.5,1.4,4.2,1.4c0.9,0,1.7-0.1,2.4-0.4c0.7-0.3,1.2-0.5,1.6-0.8c0.4-0.3,0.7-0.4,1-0.4c0.4,0,0.7,0.2,1,0.5
|
||||
c0.3,0.3,0.4,0.7,0.4,1c0,0.6-0.6,1.3-1.9,1.9c-1.2,0.7-2.8,1-4.6,1c-2.7,0-4.9-0.7-6.6-2.2S119.9,38.3,119.9,35.9z M123.3,32.5
|
||||
h7.6c0.7,0,1.2-0.1,1.4-0.3c0.2-0.2,0.4-0.5,0.4-1c0-1.2-0.5-2.3-1.4-3.2c-0.9-0.9-2-1.4-3.3-1.4c-1.3,0-2.4,0.4-3.3,1.3
|
||||
c-0.9,0.9-1.4,1.9-1.4,3.2V32.5z"
|
||||
/>
|
||||
<path
|
||||
style="fill:#35495E;"
|
||||
d="M138.8,41.9c0-0.5,0.2-1,0.6-1.4c0.4-0.4,0.9-0.6,1.5-0.6c0.6,0,1.1,0.2,1.5,0.6
|
||||
c0.4,0.4,0.6,0.8,0.6,1.4c0,0.5-0.2,1-0.6,1.4s-0.9,0.6-1.5,0.6c-0.6,0-1.1-0.2-1.5-0.6S138.8,42.4,138.8,41.9z"
|
||||
/>
|
||||
<path
|
||||
style="fill:#35495E;"
|
||||
d="M143,51.4c0-0.5,0.1-0.8,0.4-1.1c0.3-0.3,0.6-0.4,1-0.4c1.1,0,1.8-0.4,2.1-1.2
|
||||
c0.3-0.8,0.5-2,0.5-3.6V25.3c0-0.4,0.2-0.6,0.5-0.9c0.3-0.2,0.7-0.3,1.2-0.3c0.5,0,0.9,0.1,1.2,0.3c0.3,0.2,0.5,0.5,0.5,0.9v19.9
|
||||
c0,2.4-0.5,4.3-1.4,5.7c-0.9,1.4-2.3,2.1-4.2,2.1C143.6,53,143,52.4,143,51.4z M147.2,18.2c-0.4-0.4-0.6-0.9-0.6-1.4
|
||||
c0-0.5,0.2-1,0.6-1.4c0.4-0.4,0.9-0.6,1.5-0.6c0.6,0,1.1,0.2,1.5,0.6c0.4,0.4,0.6,0.8,0.6,1.4c0,0.5-0.2,1-0.6,1.4
|
||||
c-0.4,0.4-0.9,0.6-1.5,0.6C148.1,18.8,147.6,18.6,147.2,18.2z"
|
||||
/>
|
||||
<path
|
||||
style="fill:#35495E;"
|
||||
d="M154.1,40.8c0-0.4,0.1-0.7,0.3-1c0.2-0.3,0.5-0.5,0.8-0.5c0.2,0,0.5,0.2,0.9,0.5s1,0.7,1.8,1
|
||||
c0.8,0.3,1.7,0.5,2.7,0.5c1.4,0,2.4-0.2,3-0.7s0.9-1.1,0.9-1.9c0-0.9-0.3-1.6-1-2.2c-0.7-0.5-1.5-0.9-2.5-1.2c-1-0.3-2-0.6-3-0.9
|
||||
s-1.8-0.9-2.5-1.7c-0.7-0.8-1-1.8-1-3.1c0-1.5,0.6-2.9,1.7-4c1.1-1.1,2.8-1.7,5.1-1.7c1.4,0,2.8,0.2,4,0.7c1.2,0.4,1.8,0.9,1.8,1.5
|
||||
c0,0.3-0.1,0.7-0.4,1.1c-0.3,0.4-0.6,0.6-1,0.6c-0.1,0-0.6-0.2-1.6-0.6c-0.9-0.4-1.9-0.6-2.8-0.6c-1.3,0-2.2,0.3-2.8,0.9
|
||||
c-0.6,0.6-0.9,1.3-0.9,2c0,0.8,0.3,1.4,1,1.8c0.7,0.4,1.5,0.8,2.5,1c1,0.2,2,0.6,3,0.9c1,0.4,1.8,1,2.5,1.8c0.7,0.9,1,2,1,3.4
|
||||
c0,1.7-0.6,3-1.8,4c-1.2,1-2.9,1.5-5,1.5c-1.9,0-3.4-0.3-4.8-1C154.7,42.2,154.1,41.5,154.1,40.8z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Thanks for using the DevExtreme Vue App Template.
|
||||
</p>
|
||||
<p>This application was built using <a href="https://cli.vuejs.org/" target="_blank" rel="noopener noreferrer">Vue CLI</a>
|
||||
and <a href="https://js.devexpress.com/Documentation/Guide/Common/DevExtreme_CLI/" target="_blank" rel="noopener noreferrer">DevExtreme CLI</a>
|
||||
and includes the following DevExtreme components:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://js.devexpress.com/Documentation/Guide/UI_Components/DataGrid/Getting_Started_with_DataGrid/" target="_blank" rel="noopener noreferrer">DataGrid</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://js.devexpress.com/Documentation/Guide/Widgets/Form/Overview/" target="_blank" rel="noopener noreferrer">Form</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://js.devexpress.com/Documentation/Guide/Widgets/Drawer/Getting_Started_with_Navigation_Drawer/" target="_blank" rel="noopener noreferrer">Drawer</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
To customize your DevExtreme Vue application further, please refer to the following help topics:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://js.devexpress.com/Documentation/Guide/Vue_Components/Application_Template/#Layouts" target="_blank" rel="noopener noreferrer">Layouts</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://js.devexpress.com/Documentation/Guide/Vue_Components/Application_Template/#Add_a_New_View" target="_blank" rel="noopener noreferrer">Add a New View</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://js.devexpress.com/Documentation/Guide/Vue_Components/Application_Template/#Configure_the_Navigation_Menu" target="_blank" rel="noopener noreferrer">Configure the Navigation Menu</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://js.devexpress.com/Documentation/Guide/Vue_Components/Application_Template/#Configure_Themes" target="_blank" rel="noopener noreferrer">Configure Themes</a>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
For technical content related to DevExtreme Vue components, feel free to explore
|
||||
our <a href="https://js.devexpress.com/documentation/" target="_blank" rel="noopener noreferrer">online documentation</a>
|
||||
and <a href="https://js.devexpress.com/Demos/Widgetsgallery/" target="_blank" rel="noopener noreferrer">technical demos</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.logos-container {
|
||||
margin: 20px 0 40px 0;
|
||||
text-align: center;
|
||||
svg {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.devextreme-logo {
|
||||
width: 200px;
|
||||
height: 34px;
|
||||
margin-bottom: 17px;
|
||||
}
|
||||
|
||||
.vue-logo {
|
||||
width: 180px;
|
||||
height: 62px;
|
||||
}
|
||||
|
||||
.plus {
|
||||
margin: 20px 10px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.screen-x-small .logos-container {
|
||||
svg {
|
||||
width: 100%;
|
||||
display: block;
|
||||
&.plus {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
146
src/views/login-form copy.vue
Normal file
@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<form class="login-form" @submit.prevent="onSubmit">
|
||||
<dx-form :form-data="formData" :disabled="loading">
|
||||
<dx-item
|
||||
data-field="email"
|
||||
editor-type="dxTextBox"
|
||||
:editor-options="{ stylingMode: 'filled', placeholder: 'Email', mode: 'email' }"
|
||||
>
|
||||
<dx-required-rule message="Email is required" />
|
||||
<dx-email-rule message="Email is invalid" />
|
||||
<dx-label :visible="false" />
|
||||
</dx-item>
|
||||
<dx-item
|
||||
data-field='password'
|
||||
editor-type='dxTextBox'
|
||||
:editor-options="{ stylingMode: 'filled', placeholder: 'Password', mode: 'password' }"
|
||||
>
|
||||
<dx-required-rule message="Password is required" />
|
||||
<dx-label :visible="false" />
|
||||
</dx-item>
|
||||
<dx-item
|
||||
data-field="rememberMe"
|
||||
editor-type="dxCheckBox"
|
||||
:editor-options="{ text: 'Remember me', elementAttr: { class: 'form-text' } }"
|
||||
>
|
||||
<dx-label :visible="false" />
|
||||
</dx-item>
|
||||
<dx-button-item>
|
||||
<dx-button-options
|
||||
width="100%"
|
||||
type="default"
|
||||
template="signInTemplate"
|
||||
:use-submit-behavior="true"
|
||||
>
|
||||
</dx-button-options>
|
||||
</dx-button-item>
|
||||
<dx-item>
|
||||
<template #default>
|
||||
<div class="link">
|
||||
<router-link to="/reset-password">Forgot password?</router-link>
|
||||
</div>
|
||||
</template>
|
||||
</dx-item>
|
||||
<dx-button-item>
|
||||
<dx-button-options
|
||||
text="Create an account"
|
||||
width="100%"
|
||||
:on-click="onCreateAccountClick"
|
||||
/>
|
||||
</dx-button-item>
|
||||
<template #signInTemplate>
|
||||
<div>
|
||||
<span class="dx-button-text">
|
||||
<dx-load-indicator v-if="loading" width="24px" height="24px" :visible="true" />
|
||||
<span v-if="!loading">Sign In</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</dx-form>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxLoadIndicator from "devextreme-vue/load-indicator";
|
||||
import DxForm, {
|
||||
DxItem,
|
||||
DxEmailRule,
|
||||
DxRequiredRule,
|
||||
DxLabel,
|
||||
DxButtonItem,
|
||||
DxButtonOptions
|
||||
} from "devextreme-vue/form";
|
||||
import notify from 'devextreme/ui/notify';
|
||||
|
||||
import auth from "../auth";
|
||||
|
||||
import { reactive, ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const formData = reactive({
|
||||
email:"",
|
||||
password:""
|
||||
});
|
||||
const loading = ref(false);
|
||||
|
||||
function onCreateAccountClick() {
|
||||
router.push("/create-account");
|
||||
}
|
||||
|
||||
async function onSubmit() {
|
||||
const { email, password } = formData;
|
||||
loading.value = true;
|
||||
const result = await auth.logIn(email, password);
|
||||
if (!result.isOk) {
|
||||
loading.value = false;
|
||||
notify(result.message, "error", 2000);
|
||||
} else {
|
||||
router.push(route.query.redirect || "/home");
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
formData,
|
||||
loading,
|
||||
onCreateAccountClick,
|
||||
onSubmit
|
||||
};
|
||||
},
|
||||
components: {
|
||||
DxLoadIndicator,
|
||||
DxForm,
|
||||
DxEmailRule,
|
||||
DxRequiredRule,
|
||||
DxItem,
|
||||
DxLabel,
|
||||
DxButtonItem,
|
||||
DxButtonOptions
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../themes/generated/variables.base.scss";
|
||||
|
||||
.login-form {
|
||||
.link {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.form-text {
|
||||
margin: 10px 0;
|
||||
color: rgba($base-text-color, alpha($base-text-color) * 0.7);
|
||||
}
|
||||
}
|
||||
</style>
|
143
src/views/login-form.vue
Normal file
@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<div class="content-wrapper">
|
||||
<form class="login-form" @submit.prevent="onSubmit">
|
||||
<dx-form :form-data="formData" :disabled="loading">
|
||||
<dx-item
|
||||
data-field="email"
|
||||
editor-type="dxTextBox"
|
||||
:editor-options="{ stylingMode: 'filled', placeholder: 'Email', mode: 'email' }"
|
||||
>
|
||||
<dx-required-rule message="Dibutuhkan alamat email" />
|
||||
<dx-email-rule message="Alamat email tidak valid" />
|
||||
<dx-label :visible="false" />
|
||||
</dx-item>
|
||||
<dx-item
|
||||
data-field='password'
|
||||
editor-type='dxTextBox'
|
||||
:editor-options="{ stylingMode: 'filled', placeholder: 'Password', mode: 'password' }"
|
||||
>
|
||||
<dx-required-rule message="Password harus diisi" />
|
||||
<dx-label :visible="false" />
|
||||
</dx-item>
|
||||
<dx-item
|
||||
data-field="rememberMe"
|
||||
editor-type="dxCheckBox"
|
||||
:editor-options="{ text: 'Ingat saya', elementAttr: { class: 'form-text' } }"
|
||||
>
|
||||
<dx-label :visible="false" />
|
||||
</dx-item>
|
||||
<dx-button-item>
|
||||
<dx-button-options
|
||||
width="100%"
|
||||
type="default"
|
||||
template="signInTemplate"
|
||||
:use-submit-behavior="true"
|
||||
>
|
||||
</dx-button-options>
|
||||
</dx-button-item>
|
||||
<dx-item>
|
||||
<template #default>
|
||||
<div class="link">
|
||||
<router-link to="/reset-password">Lupa password?</router-link>
|
||||
</div>
|
||||
</template>
|
||||
</dx-item>
|
||||
<template #signInTemplate>
|
||||
<div>
|
||||
<span class="dx-button-text">
|
||||
<dx-load-indicator v-if="loading" width="24px" height="24px" :visible="true" />
|
||||
<span v-if="!loading">Log In</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</dx-form>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxLoadIndicator from "devextreme-vue/load-indicator";
|
||||
import DxForm, {
|
||||
DxItem,
|
||||
DxEmailRule,
|
||||
DxRequiredRule,
|
||||
DxLabel,
|
||||
DxButtonItem,
|
||||
DxButtonOptions
|
||||
} from "devextreme-vue/form";
|
||||
import notify from 'devextreme/ui/notify';
|
||||
|
||||
import auth from "../auth";
|
||||
|
||||
import { reactive, ref } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const formData = reactive({
|
||||
email:"",
|
||||
password:""
|
||||
});
|
||||
const loading = ref(false);
|
||||
|
||||
function onCreateAccountClick() {
|
||||
router.push("/create-account");
|
||||
}
|
||||
|
||||
async function onSubmit() {
|
||||
const { email, password } = formData;
|
||||
loading.value = true;
|
||||
const result = await auth.logIn(email, password);
|
||||
if (!result.isOk) {
|
||||
loading.value = false;
|
||||
notify(result.message, "error", 2000);
|
||||
} else {
|
||||
router.push(route.query.redirect || "/home");
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
formData,
|
||||
loading,
|
||||
onCreateAccountClick,
|
||||
onSubmit
|
||||
};
|
||||
},
|
||||
components: {
|
||||
DxLoadIndicator,
|
||||
DxForm,
|
||||
DxEmailRule,
|
||||
DxRequiredRule,
|
||||
DxItem,
|
||||
DxLabel,
|
||||
DxButtonItem,
|
||||
DxButtonOptions
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../themes/generated/variables.base.scss";
|
||||
|
||||
.login-form {
|
||||
.link {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.form-text {
|
||||
margin: 10px 0;
|
||||
color: rgba($base-text-color, alpha($base-text-color) * 0.7);
|
||||
}
|
||||
}
|
||||
</style>
|
216
src/views/master-config/permissions-config.vue
Normal file
@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Manajemen Permission</h3>
|
||||
<p class="content-block">Manajemen Permission</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="role" />
|
||||
<DxItem dataField="keterangan" />
|
||||
<DxItem dataField="is_active" editor-type="dxCheckBox" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Manajemen Permission"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="role" caption="Role"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn data-field="is_active" caption="Status"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Manajemen Permission..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/permission';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL+'?size=100')
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Manajemen Roles');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
216
src/views/master-config/roles-config.vue
Normal file
@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Manajemen Role</h3>
|
||||
<p class="content-block">Manajemen Role</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="role" />
|
||||
<DxItem dataField="keterangan" />
|
||||
<DxItem dataField="is_active" editor-type="dxCheckBox" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Manajemen Roles"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="role" caption="Role"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn data-field="is_active" caption="Status"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Manajemen Roles..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/roles';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL+'?size=100')
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Manajemen Roles');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
224
src/views/master-config/users-config.vue
Normal file
@ -0,0 +1,224 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Manajemen User</h3>
|
||||
<p class="content-block">Manajemen User</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxFilterPanel :visible="true"/>
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="username" />
|
||||
<DxItem dataField="email" />
|
||||
<DxItem dataField="password"/>
|
||||
<DxItem dataField="nama" />
|
||||
<DxItem dataField="jabatan" />
|
||||
<DxItem dataField="instansi" />
|
||||
<DxItem dataField="bidang" />
|
||||
<DxItem dataField="role_id" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="600"
|
||||
:height="600"
|
||||
title="Form Manajemen User"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="nama" caption="Nama"></DxColumn>
|
||||
<DxColumn data-field="username" caption="Username"></DxColumn>
|
||||
<DxColumn data-field="jabatan" caption="Jabatan"></DxColumn>
|
||||
<DxColumn data-field="role_id" caption="Role"></DxColumn>
|
||||
<DxColumn data-field="email" caption="Email"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Manajemen User..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/users';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL)
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Manajemen User');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
247
src/views/master-data/bidang-page.vue
Normal file
@ -0,0 +1,247 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Bidang</h3>
|
||||
<p class="content-block">Bidang</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
form="popup"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="instansi_id" editor-type="dxSelectBox"/>
|
||||
<!--<DxItem dataField="instansix_id" :data-source="instansiEditorOptions" editor-type="dxDropDownBox"/>-->
|
||||
<DxItem dataField="bidang">
|
||||
<DxRequiredRule message="Bidang harus diisi" />
|
||||
</DxItem>
|
||||
<DxItem dataField="keterangan" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Bidang"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="instansi_id" caption="Instansi">
|
||||
<DxLookup display-expr="instansi" value-expr="id" :data-source="instansiEditorOptions" />
|
||||
</DxColumn>
|
||||
<DxColumn data-field="bidang" caption="Bidang"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Bidang..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule,
|
||||
DxLookup
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/bidang';
|
||||
const URL_instansi = process.env.VUE_APP_ROOT_API+'/instansi';
|
||||
|
||||
const instansiOptions = new CustomStore({
|
||||
load:() => {
|
||||
return fetch(URL_instansi+'?size=1000')
|
||||
.then((response) => response.json())
|
||||
.then(response => {
|
||||
console.log(response.data);
|
||||
return {
|
||||
data: response.data
|
||||
};
|
||||
})
|
||||
// .then(data => {
|
||||
// console.log(JSON.parse(data));
|
||||
// })
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
}
|
||||
});
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL+'?size=1000')
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule,
|
||||
DxLookup
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Bidang.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Bidang');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
instansiEditorOptions: {
|
||||
items: instansiOptions,
|
||||
searchEnabled: true, value: ''
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
221
src/views/master-data/instansi-page.vue
Normal file
@ -0,0 +1,221 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Instansi</h3>
|
||||
<p class="content-block">Instansi</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
form="popup"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="instansi">
|
||||
<DxRequiredRule message="Instansi harus diisi" />
|
||||
</DxItem>
|
||||
<DxItem dataField="alamat"/>
|
||||
<DxItem dataField="keterangan" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Instansi"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="instansi" caption="Instansi"></DxColumn>
|
||||
<DxColumn data-field="alamat" caption="Alamat"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Instansi..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/instansi';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL+'?size=1000')
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Instansi');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
219
src/views/master-data/jabatan-page.vue
Normal file
@ -0,0 +1,219 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Jabatan</h3>
|
||||
<p class="content-block">Jabatan</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
form="popup"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="jabatan">
|
||||
<DxRequiredRule message="Nama Jabatan harus diisi" />
|
||||
</DxItem>
|
||||
<DxItem dataField="keterangan" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Jabatan"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="jabatan" caption="Nama Jabatan"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Jabatan..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/jabatan';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL+'?size=100')
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Jabatan');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
209
src/views/master-data/jenis-anggaran copy.vue
Normal file
@ -0,0 +1,209 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Jenis Anggaran</h3>
|
||||
<p class="content-block">Jenis Anggaran</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :paging="true" :filtering="true" :sorting="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="jenisAnggaran" />
|
||||
<DxItem dataField="keterangan" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Jenis Anggaran">
|
||||
</DxPopup>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager :show-page-size-selector="true" :show-info="true" :show-navigation-buttons="true" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn cell-template="row-cell-template" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="jenisAnggaran" caption="Jenis Anggaran"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
<DxButton hint="detail" icon="copy"/>
|
||||
</DxColumn>
|
||||
<template #row-cell-template="{ data }">
|
||||
<DxText>{{ data.rowIndex+1 }}</DxText>
|
||||
</template>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Jenis Anggaran..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRemoteOperations
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/jenisanggaran?=1000';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL)
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
return {
|
||||
data: response.data,
|
||||
totalCount: response.pagination.totalRecords
|
||||
};
|
||||
})
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRemoteOperations
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Jenis Anggaran');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
cloneIconClick(e) {
|
||||
e.event.preventDefault();
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
216
src/views/master-data/jenis-anggaran.vue
Normal file
@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Jenis Anggaran</h3>
|
||||
<p class="content-block">Jenis Anggaran</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="jenisAnggaran">
|
||||
<DxRequiredRule message="Jenis Anggaran harus diisi" />
|
||||
</DxItem>
|
||||
<DxItem dataField="keterangan" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Jenis Anggaran">
|
||||
</DxPopup>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn cell-template="row-cell-template" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="jenisAnggaran" caption="Jenis Anggaran"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<template #row-cell-template="{ data }">
|
||||
<DxText>{{ data.rowIndex +1 }}</DxText>
|
||||
</template>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Jenis Anggaran..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/jenisanggaran';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL+'?size=100')
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
return {
|
||||
data: response.data,
|
||||
totalCount: response.pagination.totalRecords
|
||||
};
|
||||
})
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Jenis Anggaran');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
cloneIconClick(e) {
|
||||
e.event.preventDefault();
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
198
src/views/master-data/jenis-kontrak copy.vue
Normal file
@ -0,0 +1,198 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2 class="content-block">Jenis Kontrak</h2>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
mode="popup">
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="kontrak" />
|
||||
<DxItem dataField="keterangan" />
|
||||
<DxItem dataField="isactive" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Jenis Kontrak"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxSelection mode="multiple"/>
|
||||
<DxColumn data-field="id" caption="ID"></DxColumn>
|
||||
<DxColumn data-field="kontrak" caption="Jenis Kontrak"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn data-field="isactive" caption="Status">
|
||||
<dx-lookup
|
||||
display-expr="name"
|
||||
value-expr="value"
|
||||
:data-source="statuses"
|
||||
/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" />
|
||||
<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxLookup,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxExport,
|
||||
DxSelection,
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const statuses = [
|
||||
{ name: "Aktif", value: 1 },
|
||||
{ name: "Tidak Aktif", value: 0 }
|
||||
];
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/jeniskontrak';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL)
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
return {
|
||||
statuses
|
||||
};
|
||||
},
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxLookup,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxExport,
|
||||
DxSelection,
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jeniskontrak.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Jenis Kontrak');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
218
src/views/master-data/jenis-kontrak.vue
Normal file
@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Jenis Kontrak</h3>
|
||||
<p class="content-block">Jenis Kontrak</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="jeniskontrak">
|
||||
<DxRequiredRule message="Jenis kontrak harus diisi" />
|
||||
</DxItem>
|
||||
<DxItem dataField="keterangan" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Jenis Kontrak"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="jeniskontrak" caption="Jenis Kontrak"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Jenis Kontrak..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/jeniskontrak';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL+'?size=100')
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Jenis Kontrak');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
226
src/views/master-data/jenis-pengadaan.vue
Normal file
@ -0,0 +1,226 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Jenis Pengadaan</h3>
|
||||
<p class="content-block">Jenis Pengadaan</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
form="popup"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="jenisPengadaan">
|
||||
<DxRequiredRule message="Jenis pengadaan harus diisi" />
|
||||
</DxItem>
|
||||
<DxItem dataField="keterangan" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Jenis Pengadaan">
|
||||
<DxPosition
|
||||
at="center"
|
||||
my="center"
|
||||
v-model:of="positionOf"
|
||||
collision="fit"/>
|
||||
</DxPopup>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="jenisPengadaan" caption="Jenis Pengadaan"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Jenis Pengadaan..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
import { DxPosition } from "devextreme-vue/context-menu";
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/jenispengadaan';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL+'?size=100')
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxPosition,
|
||||
DxRequiredRule
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Jenis Pengadaan');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
218
src/views/master-data/lokasi-pengadaan.vue
Normal file
@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Lokasi</h3>
|
||||
<p class="content-block">Lokasi</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="lokasi">
|
||||
<DxRequiredRule message="Lokasi harus diisi" />
|
||||
</DxItem>
|
||||
<DxItem dataField="keterangan" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Lokasi"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="lokasi" caption="Lokasi"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Lokasi..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/lokasi';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL+'?size=100')
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Lokasi');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
221
src/views/master-data/metode-pengadaan.vue
Normal file
@ -0,0 +1,221 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Metode Pengadaan</h3>
|
||||
<p class="content-block">Metode Pengadaan</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxColumnChooser :enabled="false"/>
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="metodePengadaan">
|
||||
<DxRequiredRule message="Metode pengadaan harus diisi" />
|
||||
</DxItem>
|
||||
<DxItem dataField="keterangan" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Metode Pengadaan"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" location="after">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="metodePengadaan" caption="Metode Pengadaan"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Metode Pengadaan..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxColumnChooser,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/metodepengadaan';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL+'?size=100')
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxColumnChooser,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Metode Pengadaan');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
218
src/views/master-data/metode-penyampaian.vue
Normal file
@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Metode Penyampaian</h3>
|
||||
<p class="content-block">Metode Penyampaian</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="metodepenyampaian">
|
||||
<DxRequiredRule message="Metode penyampaian harus diisi" />
|
||||
</DxItem>
|
||||
<DxItem dataField="keterangan" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Metode Penyampaian"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="metodepenyampaian" caption="Metode Penyampaian"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Metode Penyampaian..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/metodepenyampaian';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL+'?size=100')
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Metode Penyampaian');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
218
src/views/master-data/strategi-pengadaan.vue
Normal file
@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Strategi Pengadaan</h3>
|
||||
<p class="content-block">Strategi Pengadaan</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="strategipengadaan">
|
||||
<DxRequiredRule message="Strategi pengadaan harus diisi" />
|
||||
</DxItem>
|
||||
<DxItem dataField="keterangan" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Strategi Pengadaan"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="strategipengadaan" caption="Strategi Pengadaan"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Strategi Pengadaan..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/strategipengadaan';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL)
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Strategi Pengadaan');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
218
src/views/master-data/sumber-dana.vue
Normal file
@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Sumber Dana</h3>
|
||||
<p class="content-block">Sumber Dana</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="sumberDana">
|
||||
<DxRequiredRule message="Sumber dana harus diisi" />
|
||||
</DxItem>
|
||||
<DxItem dataField="keterangan" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Sumber Dana"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="sumberDana" caption="Sumber Dana"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Sumber Dana..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/sumberdana';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL+'?size=100')
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Sumber Dana');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
218
src/views/master-data/supply-positioning-matrix.vue
Normal file
@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Supply Positioning Matrix</h3>
|
||||
<p class="content-block">Supply Positioning Matrix</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="supplypositioningmatrix">
|
||||
<DxRequiredRule message="Supply positioning matrix harus diisi" />
|
||||
</DxItem>
|
||||
<DxItem dataField="keterangan" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Supply Positioning Matrix"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="supplypositioningmatrix" caption="Supply Positioning Matrix"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Supply Positioning Matrix..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/supplypositioningmatrix';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL)
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Supply Positioning Matrix');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
218
src/views/master-data/unit-inisiator.vue
Normal file
@ -0,0 +1,218 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Divisi/Unit Inisiator Pengadaan</h3>
|
||||
<p class="content-block">Divisi/Unit Inisiator Pengadaan</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="unitInisiator">
|
||||
<DxRequiredRule message="Unit inisiator harus diisi" />
|
||||
</DxItem>
|
||||
<DxItem dataField="keterangan" />
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="400"
|
||||
:height="400"
|
||||
title="Form Divisi/Unit Inisiator Pengadaan"
|
||||
/>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="unitInisiator" caption="Divisi/Unit Inisiator Pengadaan"></DxColumn>
|
||||
<DxColumn data-field="keterangan" caption="Keterangan"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Divisi/Unit Inisiator Pengadaan..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/unitinisiator';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL)
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxRequiredRule
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('unitinisiator.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Jenis Pengadaan');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
88
src/views/profile-page.vue
Normal file
@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2 class="content-block">Profile</h2>
|
||||
|
||||
<div class="content-block dx-card responsive-paddings">
|
||||
<div class="form-avatar">
|
||||
<img :src="imageSrc" />
|
||||
</div>
|
||||
<span>{{ formData.Notes }}</span>
|
||||
</div>
|
||||
|
||||
<div class="content-block dx-card responsive-paddings">
|
||||
<dx-form
|
||||
id="form"
|
||||
label-location="top"
|
||||
:form-data="formData"
|
||||
:colCountByScreen="colCountByScreen"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxForm from "devextreme-vue/form";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
picture: String
|
||||
},
|
||||
setup() {
|
||||
const picture = "images/employees/06.png";
|
||||
|
||||
const imageSrc = `https://js.devexpress.com/Demos/WidgetsGallery/JSDemos/${picture}`;
|
||||
const formData = {
|
||||
ID: 7,
|
||||
FirstName: "Sandra",
|
||||
LastName: "Johnson",
|
||||
Prefix: "Mrs.",
|
||||
Position: "Controller",
|
||||
Picture: picture,
|
||||
BirthDate: new Date("1974/11/5"),
|
||||
HireDate: new Date("2005/05/11"),
|
||||
Notes:
|
||||
"Sandra is a CPA and has been our controller since 2008. " +
|
||||
"She loves to interact with staff so if you`ve not met her, be certain to say hi." +
|
||||
"\r\n\r\n" +
|
||||
"Sandra has 2 daughters both of whom are accomplished gymnasts.",
|
||||
Address: "4600 N Virginia Rd."
|
||||
};
|
||||
const colCountByScreen = {
|
||||
xs: 1,
|
||||
sm: 2,
|
||||
md: 3,
|
||||
lg: 4
|
||||
}
|
||||
|
||||
return {
|
||||
imageSrc,
|
||||
formData,
|
||||
colCountByScreen
|
||||
};
|
||||
},
|
||||
components: {
|
||||
DxForm
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.form-avatar {
|
||||
float: left;
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
margin-right: 20px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
height: 120px;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
</style>
|
117
src/views/reset-password-form.vue
Normal file
@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<form class="reset-password-form" @submit.prevent="onSubmit">
|
||||
<dx-form :form-data="formData" :disabled="loading">
|
||||
<dx-item
|
||||
data-field="email"
|
||||
editor-type="dxTextBox"
|
||||
:editor-options="{ stylingMode: 'filled', placeholder: 'Email', mode: 'email' }"
|
||||
>
|
||||
<dx-required-rule message="Email is required" />
|
||||
<dx-email-rule message="Email is invalid" />
|
||||
<dx-label :visible="false" />
|
||||
</dx-item>
|
||||
<dx-button-item>
|
||||
<dx-button-options
|
||||
:element-attr="{ class: 'submit-button' }"
|
||||
width="100%"
|
||||
type="default"
|
||||
template="resetTemplate"
|
||||
:use-submit-behavior="true"
|
||||
>
|
||||
</dx-button-options>
|
||||
</dx-button-item>
|
||||
<dx-item>
|
||||
<template #default>
|
||||
<div class="login-link">
|
||||
Return to <router-link to="/login-form">Sign In</router-link>
|
||||
</div>
|
||||
</template>
|
||||
</dx-item>
|
||||
<template #resetTemplate>
|
||||
<div>
|
||||
<span class="dx-button-text">
|
||||
<dx-load-indicator v-if="loading" width="24px" height="24px" :visible="true" />
|
||||
<span v-if="!loading">Reset my password</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</dx-form>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxForm, {
|
||||
DxItem,
|
||||
DxLabel,
|
||||
DxButtonItem,
|
||||
DxButtonOptions,
|
||||
DxRequiredRule,
|
||||
DxEmailRule
|
||||
} from 'devextreme-vue/form';
|
||||
import DxLoadIndicator from 'devextreme-vue/load-indicator';
|
||||
import notify from 'devextreme/ui/notify';
|
||||
import { ref, reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import auth from "../auth";
|
||||
|
||||
const notificationText = 'We\'ve sent a link to reset your password. Check your inbox.';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxForm,
|
||||
DxItem,
|
||||
DxLabel,
|
||||
DxButtonItem,
|
||||
DxButtonOptions,
|
||||
DxRequiredRule,
|
||||
DxEmailRule,
|
||||
DxLoadIndicator
|
||||
},
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
|
||||
const loading = ref(false);
|
||||
const formData = reactive({
|
||||
email:""
|
||||
});
|
||||
|
||||
async function onSubmit() {
|
||||
const { email } = formData;
|
||||
loading.value = true;
|
||||
|
||||
const result = await auth.resetPassword(email);
|
||||
loading.value = false;
|
||||
|
||||
if (result.isOk) {
|
||||
router.push("/login-form");
|
||||
notify(notificationText, "success", 2500);
|
||||
} else {
|
||||
notify(result.message, "error", 2000);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
loading,
|
||||
formData,
|
||||
onSubmit
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../themes/generated/variables.base.scss";
|
||||
|
||||
.reset-password-form {
|
||||
.submit-button {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.login-link {
|
||||
color: $base-accent;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
229
src/views/rks-daftar.vue
Normal file
@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<div>
|
||||
<h3 class="content-block main-title">Daftar Isi RKS</h3>
|
||||
<p class="content-block">Daftar Isi RKS</p>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
<div id="app-container">
|
||||
<DxDataGrid ref="currDataGrid"
|
||||
:data-source="customDataSource"
|
||||
key-expr="ID"
|
||||
:allow-column-reordering="true"
|
||||
:column-auto-width="true"
|
||||
@exporting="onExporting">
|
||||
<DxRemoteOperations :group-paging="true" />
|
||||
<DxEditing
|
||||
:allow-adding="true"
|
||||
:allow-updating="true"
|
||||
:allow-deleting="true"
|
||||
:use-icons="true"
|
||||
form="popup"
|
||||
mode="popup">
|
||||
<DxTexts
|
||||
add-row="Tambah"
|
||||
edit-row="Ubah"
|
||||
delete-row="Hapus"
|
||||
confirm-delete-message="Apakah anda yakin untuk menghapus data ini?"
|
||||
save-row-changes="Simpan"
|
||||
cancel-row-changes="Batal"
|
||||
></DxTexts>
|
||||
<DxForm label-location="top" :col-count="1">
|
||||
<DxItem dataField="kodeTemplate" />
|
||||
<DxItem dataField="namaTemplate" />
|
||||
<DxItem dataField="metodePengadaanId" />
|
||||
<DxItem dataField="versi" />
|
||||
<DxSelectBox dataField="isStatus"/>
|
||||
<DxCheckBox dataField="isStatus1"/>
|
||||
</DxForm>
|
||||
<DxPopup
|
||||
:hide-on-outside-click="true"
|
||||
:show-title="true"
|
||||
:width="500"
|
||||
:height="500"
|
||||
title="Form Daftar Isi RKS">
|
||||
<DxPosition
|
||||
at="center"
|
||||
my="center"
|
||||
v-model:of="positionOf"
|
||||
collision="fit"/>
|
||||
</DxPopup>
|
||||
</DxEditing>
|
||||
<DxToolbar>
|
||||
<DxItem name="groupPanel" />
|
||||
<DxItem name="searchPanel" location="before"/>
|
||||
<DxItem name="addRowButton" show-text="always" css-class="">
|
||||
<DxTexts add-row="Tambah"></DxTexts>
|
||||
</DxItem>
|
||||
<DxItem name="exportButton" />
|
||||
<DxItem name="columnChooserButton" />
|
||||
</DxToolbar>
|
||||
<DxPaging :page-size="5" />
|
||||
<DxPager
|
||||
:visible="true"
|
||||
:allowed-page-sizes="[5, 10, 50]"
|
||||
:display-mode="compact"
|
||||
:show-page-size-selector="true"
|
||||
:show-info="true"
|
||||
:show-navigation-buttons="true"
|
||||
info-text="Hal {0} dari {1} ({2} data)" />
|
||||
<DxFilterRow :visible="false" />
|
||||
<DxColumn data-field="id" caption="No" :width="45"></DxColumn>
|
||||
<DxColumn data-field="kodeTemplate" caption="Kode Template"></DxColumn>
|
||||
<DxColumn data-field="namaTemplate" caption="Nama Template"></DxColumn>
|
||||
<DxColumn data-field="metodePengadaanId" caption="Metode Pengadaan"></DxColumn>
|
||||
<DxColumn data-field="versi" caption="Versi"></DxColumn>
|
||||
<DxColumn data-field="isStatus" caption="Status"></DxColumn>
|
||||
<DxColumn type="buttons" caption="Aksi">
|
||||
<DxButton name="edit"/>
|
||||
<DxButton name="delete"/>
|
||||
</DxColumn>
|
||||
<DxSearchPanel :visible="true" :highlight-case-sensitive="true" :width="300" placeholder="Cari Daftar Isi RKS..."/>
|
||||
<!--<DxExport
|
||||
:enabled="true"
|
||||
:formats="['xlsx', 'pdf']"
|
||||
:allow-export-selected-data="true"
|
||||
/>-->
|
||||
</DxDataGrid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DxDataGrid, {
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts
|
||||
} from "devextreme-vue/data-grid";
|
||||
import CustomStore from "devextreme/data/custom_store";
|
||||
import { Workbook } from 'exceljs';
|
||||
import { saveAs } from 'file-saver-es';
|
||||
import { exportDataGrid as exportDataGridToExcel } from 'devextreme/excel_exporter';
|
||||
import { jsPDF } from 'jspdf';
|
||||
import { exportDataGrid as exportDataGridToPDF } from 'devextreme/pdf_exporter';
|
||||
import { DxPosition } from "devextreme-vue/context-menu";
|
||||
|
||||
const URL = process.env.VUE_APP_ROOT_API+'/rkspengadaan';
|
||||
|
||||
const customDataSource = new CustomStore({
|
||||
key: 'id',
|
||||
|
||||
load: () => {
|
||||
return fetch(URL+'?size=100')
|
||||
.then((response) => response.json())
|
||||
.catch(() => { throw new Error('Terdapat kesalahan memuat data'); });
|
||||
},
|
||||
|
||||
insert: (values) => {
|
||||
return fetch(URL, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
update: (key, values) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "PUT",
|
||||
body: JSON.stringify(values),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
remove: (key) => {
|
||||
return fetch(URL + "/" + encodeURIComponent(key), {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxEditing,
|
||||
DxItem,
|
||||
DxForm,
|
||||
DxPopup,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxPager,
|
||||
DxPaging,
|
||||
DxSearchPanel,
|
||||
DxToolbar,
|
||||
DxTexts,
|
||||
DxPosition
|
||||
},
|
||||
methods: {
|
||||
onExporting(e) {
|
||||
e.cancel = true;
|
||||
|
||||
switch (e.format) {
|
||||
case "pdf": {
|
||||
const doc = new jsPDF();
|
||||
exportDataGridToPDF({
|
||||
jsPDFDocument: doc,
|
||||
component: e.component,
|
||||
indent: 5,
|
||||
}).then(() => {
|
||||
doc.save('Jenispengadaan.pdf');
|
||||
});
|
||||
}
|
||||
break;
|
||||
|
||||
case "xlsx": {
|
||||
const workbook = new Workbook();
|
||||
const worksheet = workbook.addWorksheet('Daftar Isi RKS');
|
||||
|
||||
exportDataGridToExcel({
|
||||
component: e.component,
|
||||
worksheet: worksheet,
|
||||
autoFilterEnabled: true,
|
||||
}).then(() => {
|
||||
workbook.xlsx.writeBuffer().then((buffer) => {
|
||||
saveAs(new Blob([buffer], { type: 'application/octet-stream' }), 'DataGrid.xlsx');
|
||||
});
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
},
|
||||
onCellPrepared(e) {
|
||||
var isEditing = e.row.isEditing, $links = e.cellElement.find(".dx-link");
|
||||
|
||||
$links.text("");
|
||||
|
||||
if(isEditing){
|
||||
$links.filter(".dx-link-save").addClass("dx-icon-save").addClass("yellowClass");
|
||||
$links.filter(".dx-link-cancel").addClass("dx-icon-revert").addClass("yellowClass");
|
||||
} else {
|
||||
$links.filter(".dx-link-edit").addClass("dx-icon-edit").addClass("greenClass");
|
||||
$links.filter(".dx-link-delete").addClass("dx-icon-trash").addClass("redClass");
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
//jsonUrl: URL,
|
||||
customDataSource,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
133
src/views/tasks-page.vue
Normal file
@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2 class="content-block">Tasks</h2>
|
||||
|
||||
<dx-data-grid
|
||||
class="dx-card wide-card"
|
||||
:data-source="dataSourceConfig"
|
||||
:focused-row-index="0"
|
||||
:show-borders="false"
|
||||
:focused-row-enabled="true"
|
||||
:column-auto-width="true"
|
||||
:column-hiding-enabled="true"
|
||||
>
|
||||
<dx-paging :page-size="10" />
|
||||
<dx-pager :show-page-size-selector="true" :show-info="true" />
|
||||
<dx-filter-row :visible="true" />
|
||||
|
||||
<dx-column data-field="Task_ID" :width="90" :hiding-priority="2" />
|
||||
|
||||
<dx-column
|
||||
data-field="Task_Subject"
|
||||
caption="Subject"
|
||||
:width="190"
|
||||
:hiding-priority="8"
|
||||
/>
|
||||
|
||||
<dx-column
|
||||
data-field="Task_Status"
|
||||
caption="Status"
|
||||
:hiding-priority="6"
|
||||
/>
|
||||
|
||||
<dx-column
|
||||
data-field="Task_Priority"
|
||||
caption="Priority"
|
||||
:hiding-priority="5"
|
||||
>
|
||||
<dx-lookup
|
||||
display-expr="name"
|
||||
value-expr="value"
|
||||
:data-source="priorities"
|
||||
/>
|
||||
</dx-column>
|
||||
|
||||
<dx-column
|
||||
data-field="ResponsibleEmployee.Employee_Full_Name"
|
||||
caption="Assigned To"
|
||||
:allow-sorting="false"
|
||||
:hiding-priority="7"
|
||||
/>
|
||||
|
||||
<dx-column
|
||||
data-field="Task_Start_Date"
|
||||
caption="Start Date"
|
||||
data-type="date"
|
||||
:hiding-priority="3"
|
||||
/>
|
||||
|
||||
<dx-column
|
||||
data-field="Task_Due_Date"
|
||||
caption="Due Date"
|
||||
data-type="date"
|
||||
:hiding-priority="4"
|
||||
/>
|
||||
|
||||
<dx-column
|
||||
data-field="Task_Priority"
|
||||
caption="Priority"
|
||||
name="Priority"
|
||||
:hiding-priority="1"
|
||||
/>
|
||||
|
||||
<dx-column
|
||||
data-field="Task_Completion"
|
||||
caption="Completion"
|
||||
:hiding-priority="0"
|
||||
/>
|
||||
</dx-data-grid>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import "devextreme/data/odata/store";
|
||||
import DxDataGrid, {
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxLookup,
|
||||
DxPager,
|
||||
DxPaging
|
||||
} from "devextreme-vue/data-grid";
|
||||
|
||||
const priorities = [
|
||||
{ name: "High", value: 4 },
|
||||
{ name: "Urgent", value: 3 },
|
||||
{ name: "Normal", value: 2 },
|
||||
{ name: "Low", value: 1 }
|
||||
];
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const dataSourceConfig = {
|
||||
store: {
|
||||
type: "odata",
|
||||
key: "Task_ID",
|
||||
url: "https://js.devexpress.com/Demos/DevAV/odata/Tasks"
|
||||
},
|
||||
expand: "ResponsibleEmployee",
|
||||
select: [
|
||||
"Task_ID",
|
||||
"Task_Subject",
|
||||
"Task_Start_Date",
|
||||
"Task_Due_Date",
|
||||
"Task_Status",
|
||||
"Task_Priority",
|
||||
"Task_Completion",
|
||||
"ResponsibleEmployee/Employee_Full_Name"
|
||||
]
|
||||
};
|
||||
return {
|
||||
dataSourceConfig,
|
||||
priorities
|
||||
};
|
||||
},
|
||||
components: {
|
||||
DxDataGrid,
|
||||
DxColumn,
|
||||
DxFilterRow,
|
||||
DxLookup,
|
||||
DxPager,
|
||||
DxPaging
|
||||
}
|
||||
};
|
||||
</script>
|
13
src/views/user-page.vue
Normal file
@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2 class="content-block">User</h2>
|
||||
<div class="content-block">
|
||||
<div class="dx-card responsive-paddings">
|
||||
Put your content here
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
3
vue.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
process.env.VUE_APP_VERSION = require('./package.json').version
|
||||
|
||||
module.exports = {};
|